设备初始化时同样要执行一个device_register函数,该函数传入一个struct device *类型的指针,因此要定义一个struct device类型的变量作为我们的设备。
struct device结构体中init_name表示的是设备名,bus表示设备所处的总线,我们将这两项初始化。但问题是bus是总线类型,这个值从哪来,这个值就从我们之前写的总线中来,在自己写的总线驱动文件中定义了struct bus_type my_bus,因此在设备文件中声明extern struct bus_type my_bus;同时在总线文件中要用EXPORT_SYMBOL(my_bus);将my_bus变量导出。
设备文件为:
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/device.h> 4 5 extern struct bus_type my_bus; 6 struct device my_dev = { 7 .init_name = "my_bus_device", 8 .bus = &my_bus, 9 }; 10 11 static int __init my_dev_init (void) 12 { 13 int ret; 14 15 ret = device_register(&my_dev); 16 17 return 0; 18 } 19 20 static void __exit my_dev_exit (void) 21 { 22 device_unregister(&my_dev); 23 } 24 25 module_init (my_dev_init); 26 module_exit (my_dev_exit); 27 28 MODULE_LICENSE("GPL");
注意Makefile中要把bus也加上去。
编译完之后先用insmod加载总线,这时/sys/bus目录下会出现一个my_bus目录,my_bus目录下的device目录下是空的,因为该总线上没有挂载任何设备。
接下来用insmod加载设备,这时在my_bus/device目录下会出现一个my_bus_device的文件,而且这是一个链接,如下图:
说明bus总线上有一个叫做my_bus_device的设备了,其实这也是一个目录。进入该目录可以看到目录下的文件:
同样也可以给设备增加属性,调用函数device_create_file。将代码修改如下:
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/device.h> 4 #include <linux/string.h> 5 6 extern struct bus_type my_bus; 7 struct device my_dev = { 8 .init_name = "my_bus_device", 9 .bus = &my_bus, 10 }; 11 12 ssize_t my_device_show (struct device *dev, struct device_attribute *attr, char *buf) 13 { 14 return snprintf(buf, PAGE_SIZE, "%s\n", "data:2019.01.01"); 15 } 16 17 DEVICE_ATTR(data, S_IRUGO, my_device_show, NULL); 18 19 static int __init my_dev_init (void) 20 { 21 int ret; 22 23 ret = device_register(&my_dev); 24 25 device_create_file(&my_dev, &dev_attr_data); 26 27 return 0; 28 } 29 30 static void __exit my_dev_exit (void) 31 { 32 device_unregister(&my_dev); 33 } 34 35 module_init (my_dev_init); 36 module_exit (my_dev_exit); 37 38 MODULE_LICENSE("GPL");
用insmod加载总线和驱动之后可以在my_bus_device目录中看到data文件,打印data文件中便可以看到 "data:2019.01.01",如下图:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?