总线_设备_驱动注册流程详解
注册流程图
• 设备一般都需要先注册,才能注册驱动
– 现在越来越多的热拔插设备,反过来了。先注册驱动,设备来了再注册
设备
• 本节使用的命令
– 查看总线的命令#ls /sys/bus/
– 查看设备号的命令#cat /proc/devices
• 设备都有主设备号和次设备号,否则255个设备号不够用
– 查看杂项设备号的命令#cat /proc/misc
二、总线设备注册
关于注册设备的一点说明
• 早先的Linux会使用单独的文件注册设备,现在大多是使用引入的虚拟平台,使用虚拟平台来注册设备会容易很多
• 如果大家在网上看到大段的注册设备的代码,可简单了解一下,知道有这么个东西就成,不用去深究。不要去学习“屠龙技”,现在基本都是直接在平台文件中注册设备
注册设备
• 注册设备使用结构体platform_device,该结构体在头文件“vim include/linux/platform_device.h”中。头文件中也有注册设备和卸载设备的函数,了解即可
操作过程
– 注册设备。将设备结构体放到平台文件中,会自动注册设备,不用去调用注册设备的函数。
vim arch/arm/mach-exynos/mach-itop4412.c
添加设备注册
#ifdef CONFIG_HELLO_CTL
struct platform_device s3c_device_hello_ctl = {
.name = "hello_ctl",
.id = -1,
};
#endif
#ifdef CONFIG_LEDS_CTL
struct platform_device s3c_device_leds_ctl = {
.name = "leds",
.id = -1,
};
#endif
和这个
#ifdef CONFIG_HELLO_CTL
&s3c_device_hello_ctl,
#endif
#ifdef CONFIG_LEDS_CTL
&s3c_device_leds_ctl,
#endif
– 在Kconfig文件中添加编译HELLO设备的宏定义(前面教程中已经添加)
– 配置menuconfig中的HELLO宏定义,生成新的.config文件
– 生成新的zImage
• 注册完之后在虚拟平台总线下可以查到注册的设备
– ls /sys/devices/platform/
中间遇到的问题:编译make zImage的时候提示
arch/arm/mach-exynos/mach-itop4412.c:2997: error: 's3c_device_hello_ctl' undeclared here (not in a function)
这个的没有写正确
#ifdef CONFIG_HELLO_CTL
struct platform_device s3c_device_hello_ctl = {
三、总线驱动注册
头文件
• 驱动注册使用结构体platform_driver,该结构体在头文件“vim include/linux/platform_device.h”中
• 驱动注册platform_driver_register,驱动卸载函数 platform_driver_unregister也在这个头文件中
– 这两个函数的参数都只有结构体platform_driver
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
};
注册结构体
• 驱动常见的几种状态,初始化,移除,休眠,复位
– 就像PC一样,有的驱动休眠之后无法使用,有的可以使用;有的系统唤醒之后,驱动需要重新启动才能正常工作,也有直接就可以使用等等
• probe函数:platform_match函数匹配之后,驱动调用的初始化函数
• remove函数: 移除驱动函数
• suspend函数: 悬挂(休眠)驱动函数
• resume函数: 休眠后恢复驱动
• device_driver数据结构的两个参数
– name和注册的设备name要一致
– owner一般赋值THIS_MODULE
register driver
#include #include /* device register header file, include device and driver struct * register and remove function */ #include #define DRIVER_NAME "hello_ctl" MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("TOPEET"); static int hello_probe(struct platform_driver *pdv) { printk(KERN_EMERG "tinitializedn"); return 0; } static int hello_remove(struct platform_driver *pdv) { return 0; } static void hello_shutdown(struct platform_driver *pdv) { } static int hello_suspend(struct platform_driver *pdv) { return 0; } static int hello_resume(struct platform_driver *pdv) { return 0; } struct platform_driver hello_driver = { .probe = hello_probe, .remove = hello_remove, .shutdown = hello_shutdown, .suspend = hello_suspend, .resume = hello_resume, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, } }; static int hello_init(void) { int DriverState; printk(KERN_EMERG "Hello world enter!n"); DriverState = platform_driver_register(&hello_driver); printk(KERN_EMERG "tDriverState is %dn", DriverState); return 0; } static void hello_exit(void) { printk(KERN_EMERG "Hello world exit!n"); platform_driver_unregister(&hello_driver); } module_init(hello_init); module_exit(hello_exit); 实验 • 在mini_linux_module的基础上添加驱动注册部分 • 编译,在开发板上加载和卸载驱动 mount -t nfs -o nolock 192.168.2.147:/home/topeet/linux /mnt/nfs 挂载了nfs后,加载内核后 [root@iTOP-4412]# insmod probe_linux_module.ko [ 8454.570719] Hello world enter! [ 8454.572614] initialized [ 8454.582781] DriverState is [root@iTOP-4412]# rmmod probe_linux_module [ 8647.985422] Hello world exit!
上一篇:4412 杂项设备
下一篇:4412 make menuconfig和make
推荐阅读最新更新时间:2024-11-06 08:22
设计资源 培训 开发板 精华推荐
- MPS探索营 “正经玩技术”!创意征集 | 解锁锂电池充电的无限玩法!
- 智能家居当下趋势与挑战 泰科电子助力连接舒适未来
- 下载有礼:数据中心养生秘籍《福禄克数据中心解决方案》等你带回家!
- 答题有礼: 寻觅可靠的触控、手势控制解决方案?快来认识新一代AVR DA单片机
- Microchip有奖直播:为什么选择FPGA,而非MCU?
- 免费下载——Maxim 面向工业应用的参考设计
- 有奖电源小课堂 | PI 1250V高压氮化镓芯片
- 免费申请| Microchip WBZ451 Curiosity
- 【把你我的经验串一串,共享丰收】EEWORLD优秀主题/回复第17期活动开始拉
- 了解泰克新品P7700探头,答题赢好礼!