RK3568驱动指南|第十篇 热插拔-第113章 内核是如何发送事件到用户空间

发布时间:2024年01月10日

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。

?
【公众号】迅为电子

【粉丝群】824412014(加群获取驱动文档+例程)

【视频观看】嵌入式学习之Linux驱动(第十期_热插拔_全新升级)_基于RK3568

【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板


第113章?内核是如何发送事件到用户空间

113.1 相关接口函数

kobject_uevent是Linux内核中的一个函数,用于生成和发送uevent事件。它是udev和其他设备管理工具与内核通信的一种方式。

kobject_uevent函数的原型如下所示:

int?kobject_uevent(struct?kobject *kobj,?enum?kobject_action action);

参数说明:

kobj : 要发送uevent事件的内核对象(kobject)

action: 表示触发uevent的动作,可以是设备的插入,拔出,属性变化等。以下是一些常见的action参数值。这些动作类型用于描述设备发生的不同事件,通过将相应的动作类型作为action参数传递给kobject_uevent函数,可以触发相应的uevent事件,通知用户空间的udev进行相应的操作。

  • KOBJ_ADD:表示设备的添加或插入操作,表示添加一个对象到内核对象系统中。
  • KOBJ_REMOVE:表示设备的移除或拔出操作,表示从内核对象系统中删除一个对象。
  • KOBJ_CHANGE:表示设备属性的修改操作,表示对内核对象进行更改,例如属性修改等。
  • KOBJ_MOVE:表示设备的移动操作,即设备从一个位置移动到另一个位置。
  • KOBJ_ONLINE:表示设备的上线操作,即设备从离线状态变为在线状态,使其可以被访问。
  • KOBJ_OFFLINE:表示设备的离线操作,即设备从在线状态变为离线状态,使其不可以被访问。
  • ?KOBJ_BIND:表示将一个设备连接到内核对象上
  • ?KOBJ_UNBIND: 表示从内核对象上将一个设备解绑
  • ?KOBJ_MAX:表示枚举类型的最大值,通常用于表示没有任何操作行为。

kobject_uevent函数的主要作用是在内核中生成uevent事件,并通过netlink机制将该事件发送给用户空间的udev。在调用该函数时,内核会将相关的设备信息和事件类型封装为uevent消息,并通过netlink套接字将消息发送给用户空间。

用户空间的udev 会接收到这些uevent消息,并根据消息中的设备信息和事件类型来执行相应的操作,例如创建或删除设备节点,加载或卸载驱动程序等。

113.2 udevadm命令

udevadm是一个用于与udev设备管理器进行交互的命令行工具。它提供了一系列的子命令,用于查询和管理设备、触发uevent事件以及执行其他与udev相关的操作。一些常见的udevadm子命令及其功能如下:

1 ?udevadm info:用于获取设备的详细信息,包括设备路径、属性、驱动程序等。

2 ?udevadm monitor:用于监视和显示当前系统中的uevent事件。它会实时显示设备的插入、拔出以及其他相关事件。

3 ?udevadm trigger:用于手动触发设备的uevent事件。可以使用该命令模拟设备的插入、拔出等操作,以便触发相应的事件处理。

4 ?udevadm settle:用于等待udev处理所有已排队的uevent事件。它会阻塞直到udev完成当前所有的设备处理操作。

5 ?udevadm control:用于与udev守护进程进行交互,控制其行为。例如,可以使用该命令重新加载udev规则、设置日志级别等。

6 ?udevadm test:用于测试udev规则的匹配和执行过程。可以通过该命令测试特定设备是否能够正确触发相应的规则。

这些是一些常见的udevadm子命令,它们提供了与udev设备管理器交互的便捷方式,用于设备信息查询、事件监控、事件触发、规则测试等操作。通过使用udevadm工具,用户可以更好地理解和管理Linux系统中的设备和udev机制。

????在iTOP-RK3568开发板上烧写buildroot系统,输入“udevadm monitor &”可以监视和显示当前系统中的uevent事件,在之后的实验中,我们要使用这个方法。如下(图 113-1)所示:

?

113.3实验程序的编写

本实验对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\78_uevent\module

编写完成的uevent.c代码如下所示:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/configfs.h>
#include <linux/kernel.h>
#include <linux/kobject.h>

struct kobject *mykobject01;
struct kset *mykset;
struct kobj_type mytype;

// 模块的初始化函数
static int mykobj_init(void)
{
    int ret;

    // 创建并添加一个kset
    mykset = kset_create_and_add("mykset", NULL, NULL);

    // 分配并初始化一个kobject
    mykobject01 = kzalloc(sizeof(struct kobject), GFP_KERNEL);
    mykobject01->kset = mykset;

    // 初始化并添加kobject到kset
    ret = kobject_init_and_add(mykobject01, &mytype, NULL, "%s", "mykobject01");

    // 触发一个uevent事件,表示kobject的属性发生了变化
    ret = kobject_uevent(mykobject01, KOBJ_CHANGE);

    return 0;
}

// 模块退出函数
static void mykobj_exit(void)
{
    // 释放kobject
    kobject_put(mykobject01);
}

module_init(mykobj_init);  // 指定模块的初始化函数
module_exit(mykobj_exit);  // 指定模块的退出函数

MODULE_LICENSE("GPL");    // 模块使用的许可证
MODULE_AUTHOR("topeet");  // 模块的作者

113.4 运行测试

113.4.1 编译驱动程序

在上一小节中的uevent.c代码同一目录下创建 Makefile 文件,Makefile 文件内容如下所示:

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m += uevent.o    #此处要和你的驱动源文件同名
KDIR :=/home/topeet/Linux/linux_sdk/kernel    #这里是你的内核目录                                                                                                                            
PWD ?= $(shell pwd)
all:
    make -C $(KDIR) M=$(PWD) modules    #make操作
clean:
    make -C $(KDIR) M=$(PWD) clean    #make clean操作

对于Makefile的内容注释已在上图添加,保存退出之后,来到存放uevent.c和Makefile文件目录下,如下图(图113-2)所示:

图 113-2

然后使用命令“make”进行驱动的编译,编译完成如下图(图113--3)所示:

图 113-3

编译完生成uevent.ko目标文件,如下图(图113-4)所示:

图 113-4

至此驱动模块就编译成功了,接下来进行测试。

113.3.2 运行测试

开发板启动之后,使用命令“udevadm monitor &”监视和显示当前系统中的uevent事件。然后使用以下命令进行驱动模块的加载,如下图(图113-5)所示:

insmod uevent.ko

图 113-5?

图 113-6

驱动加载之后,如上图所示udev接收到change动作,说明uevent事件已经发送成功了。

/mykset/mykobject01 是kobject在根目录/sys/下的路径。

最后可以使用以下命令进行驱动的卸载,如下图(图113-7)所示:

rmmod uevent

图 113-7

至此,发送事件到用户空间实验就完成了。


?

文章来源:https://blog.csdn.net/BeiJingXunWei/article/details/135503491
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。