瑞芯微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主板
当我们在命令行使用rmdir命令删除item时,会执行驱动中的release函数,本章节来学习一个新函数——drop函数。一起开始本章的学习吧。
release和 .drop_item是两个不同的成员字段,用于不同的目的:
.release成员字段是在 struct config_item_type结构体中定义的一个回调函数指针。它指向一个函数,当 configfs 中的配置项被释放或删除时,内核会调用该函数来执行相应的资源释放操作。它通常用于释放与配置项相关的资源,比如释放动态分配的内存、关闭打开的文件描述符等。
.drop_item 是在 struct configfs_group_operations结构体中定义的一个回调函数指针。它指向一个函数,当 configfs 中的配置组(group)被删除时,内核会调用该函数来处理与配置组相关的操作。这个函数通常用于清理配置组的状态、释放相关的资源以及执行其他必要的清理操作。.drop_item函数在删除配置组时被调用,而不是在删除单个配置项时被调用。
.release成员字段用于配置项的释放操作,而 .drop_item成员字段用于配置组的删除操作。它们分别在不同的上下文中执行不同的任务,但都与资源释放和清理有关。
本实验对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\62_drop\module。
本章编写的驱动文件在上个章节驱动文件的基础上进行编写。在驱动程序中实现了删除配置项的函数,它会释放配置项相关的资源。编写完成的drop.c代码如下所示:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/configfs.h>
// 定义一个名为"mygroup"的config_group结构体
static struct config_group mygroup;
// 自定义的配置项结构体
struct myitem
{
struct config_item item;
};
// 配置项释放函数
void myitem_release(struct config_item *item)
{
struct myitem *myitem = container_of(item, struct myitem, item);
kfree(myitem);
printk("%s\n", __func__);
}
// 配置项操作结构体
struct configfs_item_operations myitem_ops = {
.release = myitem_release,
};
// 配置项类型结构体
static struct config_item_type mygroup_item_type = {
.ct_owner = THIS_MODULE,
.ct_item_ops = &myitem_ops,
};
// 创建配置项函数
struct config_item *mygroup_make_item(struct config_group *group, const char *name)
{
struct myitem *myconfig_item;
printk("%s\n", __func__);
myconfig_item = kzalloc(sizeof(*myconfig_item), GFP_KERNEL);
config_item_init_type_name(&myconfig_item->item, name, &mygroup_item_type);
return &myconfig_item->item;
}
// 删除配置项函数
void mygroup_delete_item(struct config_group *group, struct config_item *item)
{
struct myitem *myitem = container_of(item, struct myitem, item);
config_item_put(&myitem->item);
printk("%s\n", __func__);
}
// 配置组操作结构体
struct configfs_group_operations mygroup_ops = {
.make_item = mygroup_make_item,
.drop_item = mygroup_delete_item,
};
// 定义名为"mygroup_config_item_type"的config_item_type结构体,用于描述配置项类型。
static const struct config_item_type mygroup_config_item_type = {
.ct_owner = THIS_MODULE,
.ct_group_ops = &mygroup_ops,
};
// 定义名为"myconfig_item_type"的配置项类型结构体
static const struct config_item_type myconfig_item_type = {
.ct_owner = THIS_MODULE,
.ct_group_ops = NULL,
};
// 定义一个configfs_subsystem结构体实例"myconfigfs_subsystem"
static struct configfs_subsystem myconfigfs_subsystem = {
.su_group = {
.cg_item = {
.ci_namebuf = "myconfigfs",
.ci_type = &myconfig_item_type,
},
},
};
// 模块的初始化函数
static int myconfig_group_init(void)
{
// 初始化配置组
config_group_init(&myconfigfs_subsystem.su_group);
// 注册子系统
configfs_register_subsystem(&myconfigfs_subsystem);
// 初始化配置组"mygroup"
config_group_init_type_name(&mygroup, "mygroup", &mygroup_config_item_type);
// 在子系统中注册配置组"mygroup"
configfs_register_group(&myconfigfs_subsystem.su_group, &mygroup);
return 0;
}
// 模块退出函数
static void myconfig_group_exit(void)
{
// 注销子系统
configfs_unregister_subsystem(&myconfigfs_subsystem);
}
module_init(myconfig_group_init); // 指定模块的初始化函数
module_exit(myconfig_group_exit); // 指定模块的退出函数
MODULE_LICENSE("GPL"); // 模块使用的许可证
MODULE_AUTHOR("topeet"); // 模块的作者
在上一小节中的drop.c代码同一目录下创建 Makefile 文件,Makefile 文件内容如下所示:
export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m += drop.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的内容注释已在上图添加,保存退出之后,来到存放drop.c和Makefile文件目录下,如下图(图79-1)所示:
图 79-1
然后使用命令“make”进行驱动的编译,编译完成如下图(图79-2)所示:
图 79-2
编译完生成drop.ko目标文件,如下图(图79-3)所示:
图 79-3
至此驱动模块就编译成功了,接下来进行测试。
开发板启动之后,使用以下命令进行驱动模块的加载,如下图(图79-4)所示:、
insmod drop.ko
图79-4
驱动加载之后,我们进入/sys/kernel/config目录下,可以看到注册生成的myconfigfs子系统,如下图(图79-5)所示:
图79-5
然后我们进入注册生成的myconfigfs子系统,如下图(图 79-6)所示,可以看到注册生成的mygroup容器。
图 79-6
然后输入“mkdir test”命令创建config_item,如下图(图 79-7)所示,创建成功之后,打印“mygroup_make_item”。
图 79-7
输入“rmdir test”命令删除item,如下图所示,执行rmdir命令之后,依次执行了mygroup_delete_item函数和myitem_release函数。
图 79-8
最后可以使用以下命令进行驱动的卸载,如下图(图79-9)所示:
rmmod mkdir_item
图 79-9
至此,完善drop和release函数实验就完成了。
?