充电学习—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(); // 更新上报电池细节,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/29071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索序列到序列模型:了解编码器和解码器架构的强大功能

目录 一、说明 二、什么是顺序数据? 三、编码器解码器架构的高级概述: 3.1 编码器和解码器架构的简要概述: 3.2 训练机制:编码器和解码器架构中的前向和后向传播: 四、编码器解码器架构的改进: 4.1.…

一道session文件包含题

目录 环境说明 session文件包含getshell 审计源码 session包含 base64在session中的解码分析 题目: 链接:https://pan.baidu.com/s/1Q0BN08b8gWiVE4tOnirpTA?pwdcate 提取码:cate 环境说明 这里我用的是linux,也可以用p…

【论文阅读】-- DeepVisualInsight: 深度分类训练时空因果关系的时间旅行可视化

中文标题 摘要引言动机举例相关工作时间旅行可视化的属性符号定义邻居保护属性边界距离保持属性逆投影保持属性暂时保存属性 方法 δ \delta δ-边界估计(k)-BAVR综合体建设逆投影保持时间连续性 评估案例分析结论参考文献 摘要 了解深度学习模型的预测在训练过程中是如何形成…

[WTL/Win32]_[中级]_[MVP架构在实际项目中应用的地方]

场景 在开发Windows和macOS的界面软件时,Windows用的是WTL/Win32技术,而macOS用的是Cocoa技术。而两种技术的本地语言一个主打是C,另一个却是Object-c。界面软件的源码随着项目功能增多而增多,这就会给同步Windows和macOS的功能造成很大负担…

Linux-远程访问及控制

一、SSH远程管理 SSH(Secure Shell)是一种安全通道协议,主要用来实现字符界面的远程登录、远程复制等功能。SSH 协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令。与早期的 Telent(远程登录…

【Spine学习11】之 战士攻击动作 思路总结(手动调整贝塞尔曲线实现前快后慢)

拿到一份psd文件先观察检查一下图片顺序有没有问题, 重点看一下人物的腿部分层,(如果是大小腿分开画的就网格可打可不打,如果是连在一起画的,那必须打网格) 拿着剑的时候剑和手的层级有没有错位&#xff0c…

HCS-华为云Stack-容器网络

HCS-华为云Stack-容器网络 容器隧道overlay VPC网络

第〇篇:深入Docker的世界系列博客介绍

深入Docker的世界系列博客介绍 欢迎来到“深入Docker的世界”系列博客,这是一次旨在全面探索Docker容器化技术的冒险之旅。从基础原理到高级应用,再到实践案例分析,我们将深入挖掘Docker的每一个角落,帮助你不仅掌握这项技术的实…

FreeRtos-09事件组的使用

1. 事件组的理论讲解 事件组:就是通过一个整数的bit位来代表一个事件,几个事件的or和and的结果是输出 #define configUSE_16_BIT_TICKS 0 //configUSE_16_BIT_TICKS用1表示16位,用0表示32位 1.1 事件组适用于哪些场景 某个事件若干个事件中的某个事件若干个事件中的所有事…

第10章 文件和异常

第10章 文件和异常 10.1 从文件中读取数据10.1.1 读取整个文件10.1.2 文件路径10.1.3 逐行读取10.1.4 创建一个包含文件各行内容的列表10.1.5 使用文件的内容10.1.6 包含一百万位的大型文件10.1.7 圆周率值中包含你的生日吗 10.2 写入文件10.2.1 写入文件10.2.2 写入多行10.2.3…

MyBatisPlus基础学习

一、简介 二、集成MP 三、入门HelloWorld 四、条件构造器EntityWrapper 五、ActiveRecord(活动记录 ) 六、代码生成器 七、插件扩展 八、自定义全局操作 九、公共字段自动填充 十、Oracle主键Sequence 十一、Idea快速开发插件 十二、mybatis-plus实践及架构原理

C#聊天室客户端完整③

窗体 进入聊天室界面(panel里面,label,textbox,button): 聊天界面(flowLayoutPanel(聊天面板)): 文档大纲(panel设置顶层(登录界面),聊天界面在底层) 步骤:设置进入聊天室→输入聊天→右边自己发送的消息→左边别人发的消息 MyClient.cs(进入聊天室类) …

如何利用TikTok矩阵源码实现自动定时发布和高效多账号管理

在如今社交媒体的盛行下,TikTok已成为全球范围内最受欢迎的短视频平台之一。对于那些希望提高效率的内容创作者而言,手动发布和管理多个TikTok账号可能会是一项繁琐且耗时的任务。幸运的是,通过利用TikTok矩阵源码,我们可以实现自…

Linux C语言:字符串处理函数

一、字符串函数 1、C库中实现了很多字符串处理函数 #include <string.h> ① 求字符串长度的函数strlen② 字符串拷贝函数strcpy③ 字符串连接函数strcat④ 字符串比较函数strcmp 2、字符串长度函数strlen 格式&#xff1a;strlen(字符数组)功能&#xff1a;计算字符串…

【Python】已解决报错:AttributeError: module ‘json‘ has no attribute ‘loads‘解决办法

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主。 &#x1f913; 同时欢迎大家关注其他专栏&#xff0c;我将分享Web前后端开发、人工智能、机器学习、深…

1)Java项目笔记搭建系统梳理相关知识

目录 前言项目结构Java部分Spring整合部分SpringBoot整合部分 模块说明规划 小结javarabbitmqmybatisspring最后推荐几本工具书 前言 工作有年头了&#xff0c;学到了很多技术&#xff0c;收获了很多。但是对与工作相关的专业技能知识的掌握杂而乱&#xff0c;不够全面系统。因…

Web应用安全测试-综合利用(一)

Web应用安全测试-综合利用&#xff08;一&#xff09; 文章目录 Web应用安全测试-综合利用&#xff08;一&#xff09;1.跨站脚本攻击&#xff08;XSS&#xff09;漏洞描述测试方法GET方式跨站脚本Post方式跨站脚本 风险分析风险等级修复方案总体修复方式对于java进行的web业务…

21.FuturePromise

在异步处理时,经常用到两个接口Future 和 Promise。 说明:Netty中的Future与jdk中的Future同名,但是是两个接口,netty的Future继承了jdk的Future,而Promise又对Netty的Future进行了扩展。 JDK的Future只能同步等待任务结束(成功、失败)才能得到结果。FutureTask.get()方…

ROS中使用超声波传感器(附代码)

在ROS中使用超声波传感器通常涉及到订阅或发布sensor_msgs/Range类型的消息。下面是一个简单的示例&#xff0c;展示了如何使用C在ROS中编写一个超声波传感器的驱动程序。这个例子假设你有一个超声波传感器连接到了Arduino或者其他微控制器&#xff0c;并且该微控制器已经通过串…

SpringBoot三层架构

目录 一、传统方式 二、三层架构 三、代码拆分 1、dao层 2、service层 3、control层 四、运行结果 一、传统方式 上述代码存在一定的弊端&#xff0c;在进行软件设计和软件开发中提倡单一责任原则&#xff0c;使代码的可读性更强&#xff0c;复杂性更低&#xff0c;可扩展性…