Linux Kernel 学习笔记16:总线设备驱动模型
来源:互联网 发布:2017年淘宝测黑号 编辑:程序博客网 时间:2024/05/22 01:29
(本章基于:Linux-3.13.0-32)
Linux总线设备驱动模型结构如下图:
设备(device)和驱动(driver)分别挂载在总线(bus)上,总线再通过自身的匹配函数(match)帮助device找到对应driver或者帮助driver找到对应的device;
数据结构
总线(bus)结构
struct bus_type { //总线名const char*name; //匹配函数int (*match)(struct device *dev, struct device_driver *drv); ......}
驱动(driver)结构
struct device_driver { //驱动名const char*name; //需挂载的总线struct bus_type*bus; //驱动处理函数int (*probe) (struct device *dev); ........}设备(device)结构
struct device { //设备名const char*init_name; //需挂载的总线struct bus_type*bus; ......}
相关操作函数
bus注册注销
int bus_register(struct bus_type *bus);
int bus_unregister(struct bus_type *bus);
成功注册bus后可在/sys/bus下看到对应的目录;
driver注册注销
int driver_register(struct device_driver *drv);
int driver_unregister(struct device_driver *drv);
成功注册driver后可在/sys/bus下对应的总线目录下的drivers中看到此驱动;
device注册注销
int device_register(struct device *dev);
int device_unregister(struct device *dev);
成功注册device后可在/sys/bus/下对应的总线目录下的devices中看到此设备;
例:
本例分三个小模块bus、driver、device,bus使用名称匹配driver与device。依次挂载模块bus、driver、device,bus匹配device到对应的驱动driver并执行其中的驱动处理函数probe()。反之依次挂载bus、device、driver可以得到同样的效果;
注意:
1、注册device时我们将名称参数保存在成员init_name中,但在注册过程中会将init_name中的名称拷贝到kobj.name中,并将init_name置空。这点在匹配函数的编写中非常重要;
2、driver、device中均需要使用bus中使用EXPORT_SYMBOL导出的bus变量名,但事实上driver、device无法获取到这一变量,这是由于2.6.26之后产生的一个内核BUG,解决办法见:http://blog.csdn.net/stone8761/article/details/74744550
my_bus.c
#include <linux/init.h>#include <linux/module.h>#include <linux/device.h>int my_match(struct device *dev, struct device_driver *drv){ if(dev->kobj.name && drv->name) { return !strncmp(dev->kobj.name, drv->name, strlen(drv->name)); } else { return 0; }}struct bus_type my_bus_type = { .name = "my_bus", .match = my_match,};EXPORT_SYMBOL_GPL(my_bus_type);static __init int hello_init(void){ bus_register(&my_bus_type); return 0;}static __exit void hello_exit(void){ bus_unregister(&my_bus_type);}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Stone");my_driver.c
#include <linux/init.h>#include <linux/module.h>#include <linux/device.h>int my_probe(struct device *dev){ printk(KERN_INFO "found the driver!!!!!\n"); return 0;}extern struct bus_type my_bus_type;struct device_driver my_driver = { .name = "my_driver_device", .bus = &my_bus_type, .probe = my_probe,};static __init int hello_init(void){ if(driver_register(&my_driver)) { printk(KERN_WARNING "driver_register error!\n"); return 1; } return 0;}static __exit void hello_exit(void){ driver_unregister(&my_driver);}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Stone");my_device.c
#include <linux/init.h>#include <linux/module.h>#include <linux/device.h>extern struct bus_type my_bus_type;void my_release(struct device *dev){ return;}struct device my_device = { .init_name = "my_driver_device", .bus = &my_bus_type, .release = my_release,};static __init int hello_init(void){ if(device_register(&my_device)) { printk(KERN_WARNING "device_register error!\n"); return 1; } printk(KERN_INFO "device init!\n"); return 0;}static __exit void hello_exit(void){ device_unregister(&my_device); printk(KERN_INFO "device exit!\n");}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Stone");
- Linux Kernel 学习笔记16:总线设备驱动模型
- Linux Kernel设备驱动模型之总线添加设备
- Linux Kernel设备驱动模型之总线查找设备
- Linux Kernel设备驱动模型之总线添加驱动
- Linux Kernel设备驱动模型之 总线查找驱动
- Linux Kernel设备驱动模型之 总线注册
- Linux Kernel设备驱动模型之总线初始化
- Linux总线设备驱动模型学习
- Linux 设备总线驱动模型
- Linux总线设备驱动模型
- Linux总线、设备、驱动模型
- Linux总线设备驱动模型
- Linux 设备总线驱动模型
- Linux总线设备驱动模型
- Linux总线、设备、驱动模型
- Linux kernel -- 设备驱动模型
- Linux 设备模型 --- 总线设备驱动模型 --- 总线
- linux嵌入式驱动-总线设备驱动模型
- Codevs 1031 质数环
- 大数相乘
- 程序员两方面相论
- Robomongo bug:执行aggregate最多只返回50个文档
- JavaWeb: Tomcat优化
- Linux Kernel 学习笔记16:总线设备驱动模型
- python2爬虫的入门知识
- java生成简单图片验证码
- POJ2376 Cleaning Shifts(贪心)
- Linux中的系统调用
- makefile 问题备忘
- 大数相减
- [LeetCode] 19. Remove Nth Node From End of List
- OC 宏入门