当前位置: 首页 > news >正文

充电学习—3、Uevent机制和其在android层的实现

在这里插入图片描述

  • sysfs 是 Linux userspace 和 kernel 进行交互的一个媒介。通过 sysfs,userspace 可以主动去读写 kernel 的一些数据,同样的, kernel 也可以主动将一些“变化”告知给 userspace。也就是说,通过sysfs,userspace 和 kernel 的交互,本质上是双向的
    userspace 通过 sysfs 访问 kernel 数据的方法,便是大名鼎鼎的 show() / store() 方法

  • uevent是通过netlink实现的,首先在内核中调用netlink_kernel_create函数创建一个socket套接字,当有事件发生时,通过kobject_uevent函数最终调用netlink_broadcast_fillted函数向用户发送数据;同时在用户空间有监听事件,则kernel的变化,用户空间即刻知晓

  • uevent初始化:
    uevent_net_init()创建类型为NETLINK_KOBJECT_UEVENT的socket,并将其放入uevent_sock_list链表上。uevent_net_exit()则将其从uevent_socket_list中摘除,并且释放socket相关资源

  • 对uevent_helper设置:
    Linux下热插拔通知用户空间
    对uevent_helper设置,可以对/proc/sys/kernel/hotplug写可执行文件路径即可。然后在内核触发uevent事件的之后调用相关可执行文件进行处理
    或者还可以对/proc/kernel/uevent_helper写入可执行文件路径
    usermode helper用于帮助在内核空间启动一个用户空间程序

1、kernel中uevent主要调用函数:

  • 通过内核发送uevent很简单,将数据代表环境变量的字符串组装好后,选择合适的action,指定对应的kobject设备即可
    kobject_uevent(&drv->p->kobj, KOBJ_ADD);
    kobject_uevent_env(kobj, action, NULL);
    retval = netlink_broadcast_filtered(uevent_sock, skb,0, 1, GFP_KERNEL,kobj_bcast_filter,kobj);
    uevent发送可以通过kobject_uevent(),或者通过kobject_uevent_env()附加更多uevent信息。

  • kobject_uevent_env()主要分为两部分,一是通过netlink_broadcast_filtered()将socket信息发出去;另一个是通过uevent helper将uevent调用指定的uevent_helper进行处理,通常是热插拔程序mdev、udevd等

  • 其中kobject_uevent函数中的action对应:
    KOBJ_ADD,
    KOBJ_REMOVE,
    KOBJ_CHANGE,
    KOBJ_MOVE,
    KOBJ_ONLINE,
    KOBJ_OFFLINE,

  • 而 kobject_uevent() 其实就是直接调用了 kobject_uevent_env() 函数。一切的操作,将在该函数中完成,比如 kset uevent ops (struct kset_uevent_ops)的获取、字符串的填充组合、netlink message 的发送等,这些 uevent ops 在 start_kernel() 就会被注册

  • 发送格式一般为:action@devpatch
    change@/devices/virtual/thermal/cooling_device0
    ACTION=change
    DEVPATH=/devices/virtual/thermal/cooling_device0
    SUBSYSTEM=thermal
    NAME=user_cooling
    STATE=1
    TEMP=90
    SEQNUM=747

2、userspace用户空间的实现使用:

用户空间会首先创建一个socket,并绑定到AF_NETLINK地址族上,然后recv接收消息,处理内核传递上来的message
创建socket——》recv接收uevent信息——》解析接收到的uevent信息——》地址族是AF_NETLINK类型的socket,协议类型是NETLINK_KOBJECT_UEVENT——》将当前socket绑定到AFNETLINK上,并设置本进程为处理消息的进程

3、mdev: kmod

busybox下的mdev;

  • mdev是一种附加“-s”主动遍历/sys/dev下设备,另一种是作为hotplug处理程序,被内核uevent helper调用到;
  • mdev作为hotplug程序处理时,从环境变量中获取参数,创建或删除设备
    /etc/mdev.con文件配置:

4、mdev和udev区别:

  • udev和mdev都是通过uevent机制处理热插拔的用户程序
  • udev在用户空间监听内核uevent消息,然后解析uevent消息进行相应的热插拔事件处理
  • mdev是基于uevent-helper机制,内核在发送uevent的时,同时调用uevent-helper指向的用户空间程序进行热插拔处理,
  • udev是作为一个demo常驻内存的,mdev是在需要时被调用

5、总结:

  • uevent是内核发送消息到用户空间的一种途径,通过netlink实现, 内核中通过kobject_uevent、kobject_uevent_env发送uevent消息
  • 用户空间使用标准的socket接口来监听接收uevent消息,;或者通过uevent-helper调用用户空间进程mdev来进行热插拔动作,处理方式遵循mdev.conf规则
  • 而 uevent 把事件上报给用户空间有两种途径:
    通过 kmod 模块,直接调用用户空间的可执行程序或脚本;
    通过 netlink 通信机制,将事件从内核空间传递到用户空间;

6、通过 uevent 上报电池电量:

内核:

drivers/power/supply/power_supply_core.c
drivers/power/supply/power_supply_sysfs.c
power_supply_init
power_supply_class->dev_uevent = power-suply_uevent

  • 初始化workqueue,后续用于调度;
    INIT_WORK(&psy->changed_work, power_supply_changed-work);

  • 驱动中检测到硬件发生变化时,调用power_supply_changed函数,进而调用changed_work
    schedule_work(&psy->changed_work);

  • 添加环境变量,回调kset中注册的power-supply-uevent,将msg以socketbuffer的格式打包
    power_supply_changed-work
    kobject-uevent(&psy->dev.kobj, KOBJ_CHANGE);
    kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char *envp_ext[])
    if(envp_ext != NULL)
    add_uevent_var(env, “%s”, envp_ext[i]);
    if(uevent_ops && uevent_ops->uevent) // uevent_ops = kset->uevent_ops; uevent_ops->uevent = dev_uevent
    uevent_ops->uevent(kset, kobj, env); // power_supply_class->dev_uevent = power_supply_uevent; class类kset
    power_supply_uevent;
    add_uevent-var(env, “ACTION=%s”, action_string);
    add_uevent_var(env, “DEVPATH=%s”, devpath);
    add_uevent_var(env, “SUBSYSTEM=%s”, subsystem);

    kobject_uevent_net_boardcast(kobj, env, action_string, devpath);
    alloc_uevent_skb // sockect buffer的放置有关 header: action@devpath + socket_buffer
    scratch = skb_put(skb, len); /add header/
    sprintf(scratch, “%s@%s”, action_string, devpath);
    skb_put_data(skb, env->buf, env_buflen);

用户:

hardware/interfaces/health/utils/libhealthloop/HealthLoop.cpp

  • power_supply通过调用kobject_uevent, envp_ext为NULL, 会回调class的dev_uevent并且使用的是默认的add_uevent_var
  • ACTION=action_string DEVPATH=devpath SUBSYSTEM=subsystem,电池上层接受的时候会通过SUBSYSTEM进行过滤
    StartLoop
    epollfd.reset(epoll_create1(EPOLL_CLOEXEC)); // 进程被替换时会关闭文件描述符
    uevent_fd.reset(uevent_open_socket(64 * 1024, true)); // uevent_fd
    ev.events = EPOLLIN; // 1 新的请求, 2 接收到普通数据(缓冲未满) 3 正常关闭连接
    ev.events |= EPOLLWAKEUP; // 1 唤醒源, 系统会保持唤醒
    epoll_ctl(epollfd_, EPOLL_CTRL_ADD, uevent_fd_, &ev); // ADD表示绑定事件
    MainLoop -> while(1)
    epoll_wait(wpollfd_, events, eventctl, timeout); // epoll等待uevent事件
    uevent_kernel_multicast_recv // 接收uevent事件
    strcmp(cp, “SUBSYSTEM=” POWER_SUPPLY_SUBSYSTEM); // 判断subsystem,battery = power_supply
    ScheduleBatteryUpdate(); // 更新上报电池细节,

相关文章:

充电学习—3、Uevent机制和其在android层的实现

sysfs 是 Linux userspace 和 kernel 进行交互的一个媒介。通过 sysfs,userspace 可以主动去读写 kernel 的一些数据,同样的, kernel 也可以主动将一些“变化”告知给 userspace。也就是说,通过sysfs,userspace 和 ker…...

“河南省勘察设计资质整合趋势与企业应对“

"河南省勘察设计资质整合趋势与企业应对" 河南省勘察设计资质的整合趋势与企业应对策略可以从以下几个方面来分析: 整合趋势: 资质标准简化与合并:随着国家和地方政府深化“放管服”改革,勘察设计资质的管理趋向简化&…...

简单了解雪花算法

雪花算法是什么 不多解释。看一看 具体是怎么 生产 唯一ID 的。 ID 由多个数据组合拼接成64位,分别是 时间戳 服务器节点ID 序列号,每个数据项占的位数不固定,可以根据实际需求设置。首位 1 个二进制位 是 符号位。 public long allocate(l…...

决策树算法详细介绍原理和实现

决策树是一种常用的分类算法,它通过一系列的问题将数据分割成不同的分支,最终确定数据属于哪个类别。下面是决策树的原理、实现方式以及一个案例实现的详细介绍。 决策树原理 特征选择:决策树的构建过程首先需要选择一个特征作为节点&#…...

vue:vue2与vue3如何全局注册公共组件(包括涉及到的相关方法函数的讲解)

目录 第一章 vue2全局注册公共组件 1.1 方法一:逐个注册 1.2 方法二:批量注册 1.2.1 require.context()方法解释 第二章 vue3全局注册公共组件 1.1 方法一:逐个注册 1.2 方法二:批量注册 第一章 vue2全局注册公共组件 Vue…...

LoRa126X系列LoRa模块:专为物联网设计而生

LoRa126X是思为无线研发的一款应用于物联网应用的LoRa 前端模块系列,采用 Semtech 公司的 SX1262和SX1268 芯片。该系列模块具有小体积、低功耗,高灵敏度等特点,并且严格遵循无铅工艺生产和测试流程,符合 RoHS 和 Reach 环保标准。…...

个人职业规划(含前端职业线路、前端技术线路、前端核心竞争力、大龄程序员的出路)

1. 了解自己的兴趣与长处 喜欢擅长的事 职业方向 2. 设定长期目标(5年) 目标内容 建立自己的品牌建立自己的社交网络 适量参加社交活动,认识更多志同道合的小伙伴寻求导师指导 建立自己的作品集 注意事项 每年元旦进行审视和调整永葆积极…...

【设计模式深度剖析】【10】【行为型】【状态模式】

👈️上一篇:访问者模式 | 下一篇:解释器模式👉️ 设计模式-专栏👈️ 文章目录 状态模式定义英文定义直译如何理解呢? 状态模式的角色Context(环境类)State(抽象状态类)Concret…...

API低代码平台介绍5-数据库记录修改功能

数据库记录修改功能 在上篇文章中我们介绍了如何插入数据库记录,本篇文章会沿用上篇文章的测试数据,介绍如何使用ADI平台定义一个修改目标数据库记录的接口,包括 单主键单表修改、复合主键单表修改、多表修改(整合前两者&#xff…...

git commit撤销修改

背景 如果提交了代码,却发现有不需要提交的文件。这时候如何修改呢?可以用git reset指令。 git reset用法解释 git reset 命令用于回退版本,可以指定退回某一次提交的版本。 git reset 命令语法格式如下: git reset [--soft …...

深入理解RunLoop

RunLoop 是 iOS 和 OSX 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理。之后会介绍一下在 iOS 中,苹果是如何利用 RunLoop 实现自动释放池、延迟回调、触摸事件、屏幕刷新等功能的。 一…...

Elasticsearch term 查询:精确值搜索

一、引言 Elasticsearch 是一个功能强大的搜索引擎,它支持全文搜索、结构化搜索等多种搜索方式。在结构化搜索中,term 查询是一种常用的查询方式,用于在索引中查找与指定值完全匹配的文档。本文将详细介绍 term 查询的工作原理、使用场景以及…...

IntelliJ IDEA调试技巧

IntelliJ IDEA高级调试技巧 假设我们在UserService类的getUserAndCheckStatus方法中遇到了难以追踪的问题。以下是在IntelliJ IDEA中进行高效调试的一些进阶技巧: 1. 条件断点(Conditional Breakpoint) 如果你知道问题只在特定条件下出现&…...

NGINX_六 nginx 日志文件详解

六 nginx 日志文件详解 nginx 日志文件分为 **log_format** 和 **access_log** 两部分log_format 定义记录的格式,其语法格式为log_format 样式名称 样式详情配置文件中默认有log_format main $remote_addr - $remote_user [time_local] "req…...

第6章 工程项目融资 作业

第6章 工程项目融资 作业 一单选题(共2题,40分) (单选题) 项目资金结构不包括( )。 A.项目债务资金结构比例 B. 项目建设投资与工程项目总成本费用的比例 C. 项目资本金内部结构比例 D. 项目资本金与债务资金的比例 正…...

网站安全防护怎么做?

引言:在当今数字化的时代,网络安全已经成为个人、企业乃至整个社会的一项关键挑战。随着互联网的普及和信息技术的迅猛发展,我们的生活和工作方式日益依赖于各种互联网服务和数据交换。然而,这种依赖也带来了越来越多的安全威胁和…...

泵设备的监测控制和智慧运维

泵是一种输送流体或使流体增压的机械。它通过各种工作原理(如离心、柱塞等)将机械能转换为流体的动能或压力能,从而实现液体的输送、提升、循环等操作。 泵的一些具体应用场景: 1.智能水务:在城市供水管网中&#xff…...

【智能算法应用】基于混合粒子群-蚁群算法的多机器人多点送餐路径规划问题

目录 1.算法原理2.数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】粒子群算法(PSO)原理及实现 配餐顺序: 采用混合粒子群算法 || 路径规划: 采用蚁群算法 2.数学模型 餐厅送餐多机器人多点配送路径规划&…...

Java中的JVM调优技巧

Java中的JVM调优技巧 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! Java虚拟机(JVM)是Java应用程序的核心组件,负责将Jav…...

软件工程-第4章结构化编码和测试

软件的实现阶段:软件编码,单元测试和综合测试。 软件编码是对软件设计的进一步具体化,其任务是将设计表示变换成用程序设计语言编写的程序。 软件测试是软件质量保证的重要手段,要成功开发出高质量的软件产品,必须认…...

XML Group端口详解

在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...