Linux设备模型(四) - uevent应用:内核发送uevent,用户空间接收uevent

1,内核发送uevent

内核发送uevent的API由lib/kobject_event.c文件实现,include/linux/kobject.h是头文件。

enum kobject_action {KOBJ_ADD,KOBJ_REMOVE,KOBJ_CHANGE,KOBJ_MOVE,KOBJ_ONLINE,KOBJ_OFFLINE,KOBJ_MAX
};/* kobject_uevent不能用在中断上下文 */
int kobject_uevent(struct kobject *kobj, enum kobject_action action);
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char *envp[]);

在driver中可以调用kobject_uevent或者kobject_uevent_env来向用户空间发送uevent

kobject_uevent默认会发送”ACTION=xxx”,”DEVPATH=xxx”,”SUBSYSTEM=xxx”这三个uevent环境变量。

kobject_uevent_env可以发送一些如”xxx=xxx”的自定义的uevent环境变量。

static ssize_t esd_info_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{if (!buf || count <= 0)return -EINVAL;kobject_uevent(&core_data->pdev->dev.kobj, KOBJ_CHANGE);return count;
}static int test_uevent(struct device *dev,struct kobj_uevent_env *env)
{int ret = 0;ret = add_uevent_var(env,"COMMENT=%s", "test uevent message");if(ret)return ret;return 0;
}const struct device_type my_dev_type ={.name ="william_ts",.uevent= test_uevent,
};static int xxx_probe(struct platform_device *pdev)
{pdev->dev.type = &my_dev_type;
}

2,用户空间解析uevent

#define UEVENT_MSG_LEN 2048static void uevent_event(uint32_t /*epevents*/, int event_fd)
{char msg[UEVENT_MSG_LEN + 2];int n;char *cp;n = uevent_kernel_multicast_recv(event_fd, msg, UEVENT_MSG_LEN);if (n <= 0)return;if (n >= UEVENT_MSG_LEN) /* overflow -- discard */return;msg[n] = '\0';msg[n + 1] = '\0';cp = msg;ALOGE("william get the uevent size n = %d, msg = %s", n, msg);while(*cp) {ALOGE("william receive the msg = %s", cp);/* advance to after the next \0 */while(*cp++);}ALOGE("william uevent received %s", msg);
}void *MotTouch::uevent_thread_loop(void)
{int epoll_fd, uevent_fd;struct epoll_event ev;int nevents = 0;ALOGE("creating uevent thread");uevent_fd = uevent_open_socket(64 * 1024, true);if (uevent_fd < 0) {ALOGE("uevent_init: uevent_open_socket failed\n");return NULL;}fcntl(uevent_fd, F_SETFL, O_NONBLOCK);ev.events = EPOLLIN;ev.data.ptr = (void *)uevent_event;epoll_fd = epoll_create(64);if (epoll_fd == -1) {ALOGE("epoll_create failed; errno=%d", errno);goto error;}if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, uevent_fd, &ev) == -1) {ALOGE("epoll_ctl failed; errno=%d", errno);goto error;}while (!destroyThread) {struct epoll_event events[64];nevents = epoll_wait(epoll_fd, events, 64, -1);if (nevents == -1) {if (errno == EINTR) continue;ALOGE("usb epoll_wait failed; errno=%d", errno);break;}for (int n = 0; n < nevents; ++n) {if (events[n].data.ptr)(*(void (*)(uint32_t, int event_fd))events[n].data.ptr)(events[n].events, uevent_fd);}}ALOGI("exiting worker thread");
error:close(uevent_fd);if (epoll_fd >= 0)close(epoll_fd);return NULL;
}void sighandler(int sig) {if (sig == SIGUSR1) {destroyThread = true;ALOGI("destroy set");return;}signal(SIGUSR1, sighandler);
}

3,测试结果

上报的event会通知到所有的用户进程,这里能够收到系统中所有的uevent消息,这里只打印了我们自己添加测试的event

william get the uevent size n = 234, msg = change@/devices/platform/william_ts.0

william receive the msg = change@/devices/platform/william_ts.0

william receive the msg = ACTION=change

william receive the msg = DEVPATH=/devices/platform/william_ts.0

william receive the msg = SUBSYSTEM=platform

william receive the msg = DEVTYPE=william_ts

william receive the msg = DRIVER=william_ts

william receive the msg = MODALIAS=platform:william_ts

william receive the msg = MAC=05:04:03:02:01:00

william receive the msg = COMMENT=test uevent message

william receive the msg = SEQNUM=13492

william uevent received change@/devices/platform/william_ts.0

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

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

相关文章

2024年2月19日-2月25日(全面进行+收集免费虚幻商城资源,20小时,合计2561小时,剩余7439小时)

试试周一到周五重点进行&#xff0c;周末抄写源码&#xff0c;周一晚上看书很快就在22&#xff1a;00睡着&#xff0c;早上可以看看视频教程&#xff0c;出租车上补觉。 执行如下&#xff1a; 周一&#xff1a; 8&#xff1a;01-9&#xff1a;20ue4 rpg&#xff08;184&#xf…

Unity零基础到进阶 | Unity中的 RectTransformUtility 方法整理汇总

Unity零基础到进阶 ☀️| RectTransformUtility 方法整理汇总一、RectTransformUtility 官方文档1.1 RectTransformUtility.CalculateRelativeRectTransformBounds&#xff08;重&#xff09;1.2 RectTransformUtility.FlipLayoutAxes1.3 RectTransformUtility.FlipLayoutOnAxi…

观察者模式与发布订阅模式

观察者模式 定义&#xff1a; 观察者模式是一种行为型设计模式&#xff0c;定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。 结构图&#xff1a; ES6简易代码实现&#xff1a; //ts环境下…

Nginx——安装和反向代理

Nginx安装与应用 1.1 Nginx介绍 Nginx 是一个高性能的HTTP和反向代理服务器,特点是占有内存少&#xff0c;并发能力强 Nginx可以作为静态页面的web服务器&#xff0c;同时还支持CGI协议的动态语言&#xff0c;比如perl、php等。但是不支持java。Java程序只能通过与tomcat配合…

谷歌AI发展史:从阿尔法围棋到Gemini与Gemma的开源创新

谷歌一直是人工智能领域的重要推动者。本文将回顾谷歌AI的发展历程&#xff0c;从阿尔法围棋到现如今的Gemini和Gemma&#xff0c;探讨谷歌在人工智能领域的重大突破和创新。 1. 引言 在计算机科学领域&#xff0c;谷歌一直是人工智能&#xff08;AI&#xff0…

华为OD机试真题-数的分解-2023年OD统一考试(C卷)--Python3-开源

参考链接&#xff1a; 华为OD机试真题-用连续自然数之和来表达整数-2023年OD统一考试&#xff08;C卷&#xff09;—python代码免费

MasterAlign全景视觉点胶应用软件说明书

MasterAlign视觉软件通过高精度的图像处理和机器学习算法&#xff0c;实现了对点胶过程的全面控制和管理。以下是关于MasterAlign在全景视觉点胶应用场景中如何使用的详细说明。看完全文相信一定能让您快速上手使用。

刷题第1天:leetcode704--数组元素查找--二分法查找算法

第一部分---数组的基础知识介绍&#xff1a; 1.数组的定义&#xff1a;数组是存放在连续内存空间上的相同数据类型的数据的集合&#xff1b; 2.数组可以通过下标索引的方式获取到下标对应的数据&#xff1b; 3.数组下标是从0开始的&#xff0c;数组的内存空间地址是连续的&a…

多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型

多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型 目录 多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基本介绍…

基于R语言的Meta分析【全流程、不确定性分析】方法与Meta机器学习技术应用

Meta分析是针对某一科研问题&#xff0c;根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法&#xff0c;对来源不同的研究成果进行收集、合并及定量统计分析的方法&#xff0c;最早出现于“循证医学”&#xff0c;现已广泛应用于农林生态&#xff0c;资源环境等方面。…

适配器模式(Adapter Pattern)

定义 适配器模式是一种结构型设计模式&#xff0c;它允许将一个类的接口转换成客户希望的另一个接口。这种模式通常用于解决接口不兼容的问题。适配器模式包括三个角色&#xff1a;目标接口&#xff08;Target&#xff09;、适配器&#xff08;Adapter&#xff09;和被适配者&…

设计模式(六)代理模式

相关文章设计模式系列 1.代理模式简介 代理模式介绍 代理模式也叫委托模式&#xff0c;是结构型设计模式的一种。在现实生活中我们用到类似代理模式的场景有很多&#xff0c;比如代购、代理上网、打官司等。 定义 为其他对象提供一种代理以控制这个对象的访问。 代理模式…

【Elasticsearch专栏 18】深入探索:Elasticsearch核心配置与性能调优 保姆级教程 企业级实战

文章目录 导言01 内存设置优化1.1 JVM堆内存设置1.2 禁用Swap分区1.3 线程栈内存设置 02 文件描述符限制优化2.1 查看当前的文件描述符限制2.2 临时更改文件描述符限制2.3 永久更改文件描述符限制2.4 Elasticsearch文件描述符配置2.5 验证更改 03 网络和I/O优化3.1 网络优化3.2…

Layer1 明星项目 Partisia Blockchain 何以打造互操作、可创新的数字经济网络

我们的目标是创建一个以用户为中心的全新数字经济网络&#xff1a;在去信任化和公平透明的环境下&#xff0c;所有的隐私数据都能够得到天然保障&#xff0c;企业、用户等各角色的协作与共享将会更顺利地进行。 —— Partisia Blockchain 团队 作为一个以 Web3 安全为技术方向的…

Linux学习之vi/vim详细介绍

目录 ​编辑 1. 什么是 vim&#xff1f; 2. vi/vim 的使用 2.1 命令模式 2.2 输入模式 2.3 底线命令模式 3. vi/vim 使用实例 3.1 使用 vi/vim 进入一般模式 3.2 按下 i 进入输入模式(也称为编辑模式)&#xff0c;开始编辑文字 3.3 按下 ESC 按钮回到一般模式…

jenkins+kubernetes+git+dockerhub构建devops云平台

Devops简介 k8s助力Devops在企业落地实践 传统方式部署项目为什么发布慢&#xff0c;效率低&#xff1f; 上线一个功能&#xff0c;有多少时间被浪费了&#xff1f; 如何解决发布慢&#xff0c;效率低的问题呢&#xff1f; 什么是Devops&#xff1f; 敏捷开发 提高开发效率&…

CKA认证,开启您的云原生之旅!

在当今数字化时代&#xff0c;云计算已经成为企业和个人发展的关键技术。而获得CKA&#xff08;Certified Kubernetes Administrator&#xff09;认证&#xff0c;将是您在云原生领域迈出的重要一步。 CKA认证是由Kubernetes官方推出的权威认证&#xff0c;它旨在验证您在Kuber…

C++函数对象包装器function类详解

函数对象包装器是对函数的封装&#xff0c;为函数对象提供一个容器&#xff0c;一个封装。C中现有的可调用实体的一种类型安全的包装&#xff08;相对来说&#xff0c;函数指针的调用不是类型安全的&#xff09;&#xff0c;换句话说&#xff0c;函数对象包装器就是函数的容器。…

vue:实现顶部消息横向滚动通知

前言 系统顶部展示一个横向滚动的消息通知&#xff0c;就是消息内容从右往左一直滚动。 效果如下&#xff1a; 代码 使用 <template><div class"notic-bar"><img :src"notic" class"notice-img" /><div class"noti…

C++之类和对象(2)

目录 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 2. 赋值运算符只能重载成类的成员函数不能重载成全局函数 3. 用户没有显式实现时&…