RK3568驱动指南|第九篇 设备模型-第103章 在总线下注册设备实验

发布时间:2024年01月04日

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


第103章?在总线下注册设备实验

在99章节中,我们成功地注册了自定义的总线,并确保该总线已被系统识别和管理。现在,在本章节中,将继续构建在该总线上注册设备的流程。让我们继续构建在自定义总线上注册设备的过程,并为我们的设备模型增添更多的功能和扩展性。让我们开始吧!

103.1实验程序的编写

103.1.1 驱动程序编写

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

我们编写驱动代码,定义了一个名为 "mybus" 的总线,并实现了总线的匹配回调函数 mybus_match 和设备探测回调函数 mybus_probe。同时,还定义了一个名为 "value" 的属性文件,并实现了属性的显示回调函数 mybus_show。编写完成的bus.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>
#include <linux/device.h>
#include <linux/sysfs.h>

int mybus_match(struct device *dev, struct device_driver *drv)
{
    // 检查设备名称和驱动程序名称是否匹配
    return (strcmp(dev_name(dev), drv->name) == 0);
};

int mybus_probe(struct device *dev)
{
    struct device_driver *drv = dev->driver;
    if (drv->probe)
        drv->probe(dev);
    return 0;
};

struct bus_type mybus = {
    .name = "mybus",                 // 总线的名称
    .match = mybus_match,            // 设备和驱动程序匹配的回调函数
    .probe = mybus_probe,            // 设备探测的回调函数
};
EXPORT_SYMBOL_GPL(mybus);             // 新加导出总线符号

ssize_t mybus_show(struct bus_type *bus, char *buf)
{
    // 在 sysfs 中显示总线的值
    return sprintf(buf, "%s\n", "mybus_show");
};

struct bus_attribute mybus_attr = {
    .attr = {
        .name = "value",             // 属性的名称
        .mode = 0664,                // 属性的访问权限
    },
    .show = mybus_show,               // 属性的 show 回调函数
};

// 模块的初始化函数
static int bus_init(void)
{
    int ret;
    ret = bus_register(&mybus);       // 注册总线
    ret = bus_create_file(&mybus, &mybus_attr);  // 在 sysfs 中创建属性文件

    return 0;
}

// 模块退出函数
static void bus_exit(void)
{
    bus_remove_file(&mybus, &mybus_attr);  // 从 sysfs 中移除属性文件
    bus_unregister(&mybus);                // 取消注册总线
}

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

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

我们编写驱动文件device.c,在驱动中,Linux内核中创建一个自定义设备并将其注册到自定义总线上。

编写好的驱动如下所示:

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

extern struct bus_type mybus;

void myrelease(struct device *dev)
{
    printk("This is myrelease\n");
};

struct device mydevice = {
    .init_name = "mydevice",      // 设备的初始化名称
    .bus = &mybus,                // 所属总线
    .release = myrelease,         // 设备的释放回调函数
    .devt = ((255 << 20 | 0)),    // 设备号
};

// 模块的初始化函数
static int device_init(void)
{
    int ret;
    ret = device_register(&mydevice);  // 注册设备

    return 0;
}

// 模块退出函数
static void device_exit(void)
{
    device_unregister(&mydevice);      // 取消注册设备
}

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

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

103.3 运行测试

103.3.1 编译驱动程序

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

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m += device.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的内容注释已在上图添加,保存退出之后,来到存放device.c和Makefile文件目录下,如下图(图103-1)所示:

图 103-1

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

图 103-2

编译完生成bus.ko目标文件,如下图(图103-3)所示:

图 103-3

至此device.ko驱动模块就编译成功了,bus.ko也需要重新编译,接下来进行测试。

103.3.2 运行测试

开发板启动之后,使用以下命令进行bus.ko驱动模块的加载,如下图(图103-4)所示:

insmod bus.ko

图103-5

驱动加载之后,我们进入/sys/devices目录下,如下图所示,有注册生成的设备。

图103-6

我们进入到/sys/bus/mybus/devices目录下,如下图所示,在总线下注册的设备为mydevice。

?

图103-7

最后可以使用以下命令进行驱动的卸载,如下所示:

rmmod device

rmmod bus

至此,在总线下注册设备实验就完成了。


?

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