RK3568驱动指南|第十篇 热插拔-第117章uevent_helper实验

瑞芯微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主板


第117章uevent_helper实验

在前面的章节中已经讲解了广播这一内核发送事件到用户空间的方法,而在本章节中将会讲解内核发送事件到用户空间的第二种方法-调用可执行程序。

117.1 设置uevent_helper

在114.2小节的第十部分中进行了定义,具体内容如下所示:

#ifdef CONFIG_UEVENT_HELPER
	/* call uevent_helper, usually only enabled during early boot */
	if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {
		struct subprocess_info *info;

		retval = add_uevent_var(env, "HOME=/");
		if (retval)
			goto exit;
		retval = add_uevent_var(env,
					"PATH=/sbin:/bin:/usr/sbin:/usr/bin");
		if (retval)
			goto exit;
		retval = init_uevent_argv(env, subsystem);
		if (retval)
			goto exit;

		retval = -ENOMEM;
		info = call_usermodehelper_setup(env->argv[0], env->argv,
						 env->envp, GFP_KERNEL,
						 NULL, cleanup_uevent_env, env);
		if (info) {
			retval = call_usermodehelper_exec(info, UMH_NO_WAIT);
			env = NULL;	/* freed by cleanup_uevent_env */
		}
	}
#endif

第3行为一个if表达式,它检查 uevent_helper 数组的第一个元素是否为真。并调用 kobj_usermode_filter 函数进行用户模式过滤, uevent_helper定义如下所示:

char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;

其中CONFIG_UEVENT_HELPER_PATH 是一个宏定义在内核源码的“include/generated/autoconf.h”文件中,如下所示:

1 

#define CONFIG_UEVENT_HELPER_PATH ""

该宏为空,所以为了使能uevent_helper功能需要在图形配置界面使能CONFIG_UEVENT_HELPER和CONFIG_UEVENT_HELPER_PATH两个宏。首先来到内核源码目录下,如下图(图 117-1)所示:

 

图 117-1

然后输入以下命令将平台切换为arm64、加载rk3568的默认配置文件和进入图像配置界面,如下图(图117- 2)所示:

图117- 2

然后需要在menuconfig的图形配置界面进行以下配置:

配置1:

Device Drivers
	Generic Driver Options
		[*] Support for uevent helper//选中
		(/sbin/mdev) path to uevent helper//设置mdev路径

图117- 3

配置2:

File systems
	Pseudo filesystems.
		[*]/proc file system support//选中

图117- 4

配置3:

File systems
	Pseudo filesystems.
		[*] Sysctl support(/proc/sys)//选中

图117- 5

配置4:

1

[*]Networking support//选中

图117- 6

在上面的配置1中设置了uevent helper和相对应的路径,这就是配置方法1,但是这种方式需要重新编译内核,使用起来较为麻烦,除了方法一之外还有更快捷的方法2和方法3,具体内容如下所示:

配置方法2:

无论是否配置了CONFIG_UEVENT_HELPER_PATH,在系统启动后,可以使用以下命令来设置uevent_helper:

echo /sbin/mdev > /sys/kernel/uevent_helper

这将把uevent_helper设置为/sbin/mdex。

配置方法3:

无论是否配置了CONFIG_UEVENT_HELPER_PATH,在系统启动后,可以使用以下命令来设置uevent_helper:

echo /sbin/mdev > /proc/sys/kernel/hotplug

这将把uevent_helper设置为/sbin/mdexw.。

需要注意的是配置方法2和配置方法3依赖于上面的配置2、3、4选项,并且可以通过配置方法2和配置方法3修改配置方法1中已经写好的值。

对/proc/sys/kernel/hotplug和/sys/kernel/uevent_helper进行读写都是为了对uevent_helper属性进行读写操作。

/sys/kernel/uevent_helper是sysfs文件系统中的一个文件,它是uevent_helper属性的接口。通过对该文件进行读写操作,可以读取或修改uevent_helper属性的值。在内核源码的kernel/ksysfs.c目录下可以找到对uevent_helper属性的定义和相关操作的实现,具体内容如下所示:  

#ifdef CONFIG_UEVENT_HELPER
/* uevent helper program, used during early boot */
static ssize_t uevent_helper_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", uevent_helper);
}

static ssize_t uevent_helper_store(struct kobject *kobj, struct kobj_attribute *attr,
                                   const char *buf, size_t count)
{
    if (count + 1 > UEVENT_HELPER_PATH_LEN)
        return -ENOENT;

    memcpy(uevent_helper, buf, count);
    uevent_helper[count] = '\0';

    if (count && uevent_helper[count - 1] == '\n')
        uevent_helper[count - 1] = '\0';

    return count;
}

KERNEL_ATTR_RW(uevent_helper);
#endif

uevent_helper_show函数用于将uevent_helper的值写入buf中,并返回写入的字符数。

uevent_helper_store函数用于将buf中的值复制到uevent_helper中,并根据需要进行处理,然后返回写入的字符数。

而/proc/sys/kernel/hotplug是一个虚拟文件,用于配置内核中的热插拔事件处理程序。通过对该文件进行写操作,可以设置uevent_helper属性的值。在内核源码的kernel/sysctl.c文件中,可以看到对hotplug操作其实是对uevent_helper进行操作。具体内容如下所示:

#ifdef CONFIG_UEVENT_HELPER
{
	.procname = "hotplug",
	.data = &uevent_helper,
	.maxlen = UEVENT_HELPER_PATH_LEN,
	.mode = 0644,
	.proc_handler = proc_dostring,
}

这段代码定义了一个名为hotplug的文件,用于处理uevent事件。它与uevent_helper属性相关联。

.procname表示文件名,即/proc/hotplug。

.data是一个指向uevent_helper结构体的指针,用于保存与该文件相关的数据。该指针指向uevent_helper结构体,用于处理uevent事件。

.maxlen表示文件的最大长度,即文件内容的最大长度。该值为UEVENT_HELPER_PATH_LEN,表示文件内容的最大长度为UEVENT_HELPER_PATH_LEN。

.mode表示文件的访问权限。该值为0644,表示该文件的权限为 -rw-r--r--,即所有用户都可以读取该文件,但只有root用户可以写入该文件。

117.2 处理uevent事件

在上一章节中我们使用了netlink机制来监听内核向用户空间发送的uevent事件,而在上一小节中我们设置了uevent_helper,所以本小节将会学习调用用户空间程序来处理内核发送的uevent事件。

117.2.1 编写应用程序

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

本小节编写的是应用程序,所要实现的效果极其简单,只是获取SUBSYSTEM环境变量并打印即可,编写完成的应用程序内容如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int fd = open("/dev/ttyFIQ0", O_WRONLY);
    dup2(fd, STDOUT_FILENO);
    printf("SUBSYSTEM is %s\n", getenv("SUBSYSTEM"));
    return 0;
}

117.2.2 编译应用程序

下面进行应用程序编译,因为测试APP是要在开发板上运行的,所以需要aarch64-linux-gnu-gcc来编译,输入以下命令,编译完成以后会生成一个mdev的可执行程序,如下图(图 117-7)所示:

aarch64-linux-gnu-gcc -o mdev mdev.c

图 117-7

下面进行程序的测试。

117.2.3 运行测试

本小节测试所使用的驱动文件为115章编译生成的uevent_ops.ko,应用程序为上一小节编译出来的mdev。

mdev可执行文件和uevent_ops.ko驱动存放在开发板的/mnt目录下,如下图(图 117-8)所示:

图 117-8

在第一小节中讲解了三种配置方法,配置方法1是在内核中直接指定的,使用起来较为麻烦,这里直接使用配置方法2 和配置方法3这两种方式进行演示。

配置方法2:

echo /mnt/mdev > /sys/kernel/uevent_helper

然后使用以下命令加载uevent_ops.ko驱动,如下图(图 117-9)所示:

 

图 117-9

配置方法3:

echo /mnt/mdev > /proc/sys/kernel/hotplug

然后使用以下命令加载uevent_ops.ko驱动,如下图(图 117-10)所示:

图 117-10

上面两种配置都可以打印出内核加载时传递的SUBSYSTEM环境变量,最后可以使用以下命令进行驱动的卸载,如下图(图54-12)所示:

rmmod uevent_ops.ko

图 117-11

至此,uevent_helper实验就完成了。


 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python json模块

json是JavaScript对象表示法的缩写&#xff0c;是一种轻量级的数据交换格式&#xff0c;经常被用于Web应用程序中。python中的json库是用于解析和生成json数据格式的库。 import jsondata {"name": "张三","age": 18,"hobbies": [&q…

Unity报错:[SteamVR] Not Initialized (109)的解决方法

问题描述 使用HTC vive 头像进行SteamVR插件的示例场景进行测试&#xff0c;发现头显场景无法跳转到运行场景&#xff08;Unity 项目可以运行&#xff0c;仅出现警告&#xff09;。 具体如下&#xff1a; [SteamVR] Not Initialized (109) [SteamVR] Initialization failed…

python 基础知识点(蓝桥杯python科目个人复习计划20)

今日复习内容&#xff1a;基础算法中的选择排序/插入排序/快速排序/归并排序/桶排序 一.选择排序 1.算法步骤 从左往右找到最小的元素&#xff0c;放在起始位置重复上述步骤&#xff0c;依次找到第二&#xff0c;第三小的元素 2.具体描述 给定一个长度为n的列表&#xff0…

[VisualStudioCode]_[VSCODE]_[C/C++开发环境配置-问题解决和补充]

场景 在使用VSCode配置C的开发环境时《VisualStudioCode_C/C开发环境配置[1]》&#xff0c;编译时会发现找不到标准库的std::mutex和std::thread的声明&#xff0c;而这两个的头文件已经引入&#xff0c;什么情况&#xff1f; 无论如何MinGW都是Windows上验证开发C特性比较新的…

Python从入门到网络爬虫(控制语句详解)

前言 做任何事情都要遵循一定的原则。例如&#xff0c;到图书馆去借书&#xff0c;就需要有借书证&#xff0c;并且借书证不能过期&#xff0c;这两个条件缺一不可。程序设计亦是如此&#xff0c;需要使用流程控制实现与用户的交流&#xff0c;并根据用户需求决定程序“做什么…

运用AI搭建中间服务层(一)

知识点 适用于 AI 的 Visual Studio 工具 微软认知服务&#xff08;影像服务/实体搜索服务&#xff09;的使用 商业应用软件的架构设计 ASP.NET 核心 Web 应用程序 休息 应用程序接口 服务端的测试技术 软件工程中的需求演进处理 不断演进的应用场景 下面我们会用讲故…

PR-视频去水印

文章目录 前言PR-视频去水印实现示例 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&#xff0c;那欢迎常来啊!!! PR-视频…

Unity组件开发--短连接HTTP

1.网络请求管理器 using LitJson; using Cysharp.Threading.Tasks; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Events;using System.Web; using System.Text; using Sy…

企业的 Android 移动设备管理 (MDM) 解决方案

移动设备管理可帮助您在不影响最终用户体验的情况下&#xff0c;通过无线方式管理和保护组织的移动设备群&#xff0c;现代 MDM 解决方案还可以控制 App、内容和安全性&#xff0c;因此员工可以毫无顾虑地在托管设备上工作。移动设备管理软件可有效管理个人设备上的公司空间。M…

刷题第十五天-存在重复元素Ⅲ

存在重复元素Ⅲ 题目要求 解题思路 主要使用滑动窗口方法&#xff0c;让滑动窗口代销固定为t。 本题最大的难点在于快速地找到滑动窗口内的最大值和最小值&#xff0c;以及删除指定元素。 如果遍历求滑动窗口内的最大值和最小值&#xff0c;时间复杂度是O&#xff08;K&#…

自动化测试框架搭建全过程

前段时间写了一系列自动化测试相关的文章&#xff0c;当然更多的是方法和解决问题的思路角度去阐述我的一些观点。这篇文章来聊聊新手如何从零到一落地实践接口自动化测试。 为什么要做接口测试 测试理念的演变 早些时候&#xff0c;软件研发交付流程大多遵循V型或W型的瀑布模…

vue 公众号开发,调用jssdk封装

vue 公众号开发&#xff0c;经常会使用到 转发朋友&#xff0c;朋友圈&#xff0c;调用扫一扫等功能&#xff0c;这时就要使用微信的 jssdk 微信jssdk传送门 1. 安装jssdk 插件 (jweixin-module) npm install jweixin-module --save 2. 封装方法 utils/jwx.js let jweixin…

Hello,World!

“Hello, world”的由来可以追溯到 The C Programming Language 。在这门编程语言中&#xff0c;它被用作第一个演示程序&#xff0c;向人们展示了在计算机屏幕上输出“Hello world”这行字符串的计算机程序。由于这个演示程序的简洁性和直观性&#xff0c;它成为了许多初学者学…

qt图形化界面开发DAY3

作业&#xff1a; 1> 思维导图 2> 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转…

Android 输入系统介绍

文章目录 一、目的二、环境三、相关概念3.1 输入设备3.2 UEVENT机制3.3 JNI3.4 EPOLL机制3.5 INotify 四、详细设计4.1 结构图4.2 代码结构4.3 InputManagerService模块4.3.1 IMS服务入口4.3.2 IMS初始化4.3.3 IMS启动4.3.4 IMS消息监听 4.4 NativeInputManager模块4.4.1 nativ…

解决Windows 11/10共享打印机无法连接问题0x00000709错误

在解决共享打印机连接问题之前&#xff0c;请确保满足以下几个条件&#xff1a; 确保Windows 11设备和共享打印机的电脑连接到同一个网络。检查网络连接是否稳定。确保共享打印机所连接的计算机处于开机状态。检查共享设置&#xff0c;确保共享打印机在Windows 7计算机上正确设…

Docker安装Nacos2.2.3并鉴权、Prometheus监听Nacos、Grafana监控Nacos【亲测可用】

1、Docker 拉取镜像&#xff1a;docker pull nacos/nacos-server:v2.2.3 2、docker run --env MODEstandalone --name nacos -d -p 8848:8848 -p 9848:9848 -p 9849:9849 nacos/nacos-server:v2.2.3 3、复制镜像中的配置文件 mkdir -vp /home/nacos/logs mkdir -vp /home/n…

Transformer详解【学习笔记】

文章目录 1、Transformer绪论2、Encoders和Decoder2.1 Encoders2.1.1 输入部分2.1.2 多头注意力机制2.1.3 残差2.1.4 LayNorm&#xff08;Layer Normalization&#xff09;2.1.5 前馈神经网路 2.2 Decoder2.2.1 多头注意力机制2.2.2 交互层 1、Transformer绪论 Transformer在做…

使用PyTorch实现去噪扩散模型

在深入研究去噪扩散概率模型(DDPM)如何工作的细节之前&#xff0c;让我们先看看生成式人工智能的一些发展&#xff0c;也就是DDPM的一些基础研究。 VAE VAE 采用了编码器、概率潜在空间和解码器。在训练过程中&#xff0c;编码器预测每个图像的均值和方差。然后从高斯分布中对…

【Spring Boot】项目端口号冲突解决方法,一步到位

启动项目遇到以下问题&#xff1a; Description: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port. Process finished with …