上层监听Kernel上报的UEvent事件Demo

本文介绍了一种在自定义NeoManagerService服务中通过监听内核UEVENT来监测lgy节点连接状态的方法。该方法利用Java中的UEventObserver类实现,并详细展示了如何注册观察者并处理UEVENT消息。

最近的项目需要上层判断新外挂的mcu的连接状态 , 其节点自定义为  /sys/class/lgy_class/lgy/lgy。

在kernel中创建节好点的时候,其实已经有了uevent事件了。

上层需要监听的是这个节点虚拟出来的

 

1,在自定义的NeoManagerService.java 服务中添加监听动作;

private static final String LGY_STATE_MATCH ="DEVPATH=/devices/virtual/lgy_class/lgy";

    

/*
 * Listens for uevent messages from the kernel to monitor the lgy state
 */ 
private final class LgyUEventObserver extends UEventObserver {
     @Override
     public void onUEvent(UEventObserver.UEvent event) {
          
 			Log.d("lgy_debug","onUEvent 1111111111111");
 			Log.d("lgy_debug","onUEvent 2222222222222");
            String state = event.get("LGY_STATE");
			Log.d("lgy_debug","onUEvent 2222222222222 state ="+state);
            doSomeThing();
    }
}

 

private static final String LGY_STATE_MATCH ="DEVPATH=/devices/virtual/lgy_class/lgy";

private static UEventObserver mUEventObserver;

    public NeoManagerService(Context context) {
        //super(context);
        mContext = context;	
		try {
		myService = ILgytestDevice.getService(); 
		mLgytestCallback = new LgytestCallback();
		myService.registerCallback(mLgytestCallback);
	    mUEventObserver = new LgyUEventObserver();
        mUEventObserver.startObserving(LGY_STATE_MATCH);
		} catch (Exception e) {
			Log.e ("lgy_debug","ILgytestDevice getService error!");
					e.printStackTrace();
				}			

    }

 

kernel层使用kobject_uevent_env函数上报uevent事件

char *disconnected[2] = { "LGY_STATE=DISCONNECTED", NULL };
char *connected[2] = { "LGY_STATE=CONNECTED", NULL };
char **uevent_envp = NULL;


uevent_envp = dev->connected ? connected : disconnected;//设备连接状态

kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, uevent_envp);//开始上报事件
//kobject_uevent(&dev->kobj, KOBJ_CHANGE);//这种方式上层得不到LGY_STATE的值

 

<think>好的,用户的问题是关于在用户空间使用uevent_init函数来监听内核的uevent事件。首先,我需要确认uevent_init是否真的存在,以及它在用户空间中的作用。根据提供的引用内容,引用[1]提到mdev通过修改uevent_helper来处理热插拔事件,而引用[2]则详细说明了内核发送uevent的API,比如kobject_uevent。但用户空间接收uevent通常有不同的方法,比如使用netlink套接字。 接下来,我需要回忆uevent的处理机制。用户空间程序通常通过创建一个netlink套接字(AF_NETLINK,NETLINK_KOBJECT_UEVENT)来监听内核发送的uevent事件。例如,udev和mdev都是这样做的。然而,用户提到的uevent_init函数并不是标准库或常见API的一部分。可能用户误解了某个代码示例中的函数,或者是指某个特定库中的初始化步骤。 然后,我需要检查是否有任何库或框架提供了uevent_init函数。例如,某些嵌入式系统或特定的用户空间工具可能有自定义的函数来初始化uevent监听。但根据常见Linux环境,标准做法是直接使用socket系统调用来建立连接,而不是调用某个init函数。因此,用户可能在文档或示例中看到了uevent_init,但这可能是一个自定义的封装函数,而非标准API。 接下来,需要指导用户如何正确监听uevent事件。步骤应包括创建套接字、绑定到适当的地址、接收和处理事件数据。同时,提醒用户注意权限问题,可能需要root权限或适当的capabilities。此外,解释事件数据的格式,通常是字符串环境变量形式,需要正确解析。 还要考虑用户可能的错误点,比如函数名称拼写错误或混淆用户空间与内核空间的API。例如,kobject_uevent是内核函数,用户空间无法直接调用。必须明确区分内核发送事件的机制和用户空间接收的方法。 最后,确保回答引用了提供的参考文献,特别是引用[1]和[2],以支持解释的正确性。例如,指出mdev使用uevent_helper机制,而内核通过kobject_uevent发送事件,但用户空间监听需要不同的方法。</think>在Linux系统中,用户空间监听内核uevent事件的标准方法是基于NETLINK套接字实现的,而`uevent_init`并不是Linux标准C库或POSIX规范中的函数。根据内核uevent机制的工作方式,以下是完整的实现方法解析: ### 一、uevent监听原理 内核通过`kobject_uevent_env()`函数发送事件时[^2],会向`NETLINK_KOBJECT_UEVENT`类型的netlink套接字广播消息。用户空间需要创建对应协议的socket并监听,这与mdev通过`/proc/sys/kernel/hotplug`注册热插拔处理程序的机制[^1]是两种不同的实现路径。 ### 二、标准实现步骤 ```c #include <sys/socket.h> #include <linux/netlink.h> int main() { // 1. 创建NETLINK套接字 int sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); // 2. 设置地址绑定参数 struct sockaddr_nl addr; memset(&addr, 0, sizeof(addr)); addr.nl_family = AF_NETLINK; addr.nl_pid = getpid(); // 设置进程PID作为标识 addr.nl_groups = 1; // 接收所有广播消息 // 3. 绑定套接字 bind(sock, (struct sockaddr*)&addr, sizeof(addr)); // 4. 消息接收循环 char buf[8192]; while(1) { int len = recv(sock, buf, sizeof(buf), 0); // 解析buf中的uevent消息(格式为key=value的字符串序列) printf("Received uevent: %.*s\n", len, buf); } return 0; } ``` ### 三、关键注意事项 1. **权限要求**:需要`CAP_NET_ADMIN`能力或root权限 2. **消息格式**:数据为多个`KEY=value`形式的字符串,以空字符分隔 3. **多播组选择**:通过`nl_groups`指定关注的事件类型(位掩码) ### 四、关于`uevent_init`的解释 在标准Linux开发环境中不存在名为`uevent_init`的公开API函数。该名称可能出现在以下场景: 1. 特定项目中的封装函数(如某些嵌入式框架) 2. 旧版文档的命名错误(实际应为socket初始化) 3. 对内核API`kobject_uevent()`的混淆(该函数属于内核空间API[^2])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值