一个驱动支持多个设备再usb子系统、input子系统、platform、iic子系统 中的实现
来源:互联网 发布:日语教材 知乎 编辑:程序博客网 时间:2024/05/02 01:45
platform
你写的驱动你应该知道它适用与哪些设备吧,如果你想支持一个设备,那么你就构造一个
usb_device_id (USB)、i2c_device_id (IIC)、platform_device_id(Platform)放到对应驱动的id_table中
/** 先看平台总线。*/struct bus_type platform_bus_type = { .name = "platform", .dev_attrs = platform_dev_attrs, /** 匹配驱动与设备 */ .match = platform_match, .uevent = platform_uevent, .pm = &platform_dev_pm_ops,}; /** 匹配的方法有两种 : 1 : 是利用了platform_driver中定义的id_table,(一个驱动可能支持多个设备) 如果定义了id_table,那么,就会逐一遍历id_table表中的每一项 否则,使用name来匹配 2 : 使用name来匹配 (一个驱动只能支持一个设备) */ static int platform_match(struct device * dev,struct device_driver * drv) { /** 底层调用container_of宏来获取平台设备、平台设备驱动 */ struct platform_device = to_platform_device(dev); struct platform_driver = to_platform_driver(drv); /** 这个函数,如果drv->of_match_table不存在,或者dev->of_node不存在 就会返回NULL,实际中用的不多 最终还是比较 drv->of_match_table 和 dev->of_node的name、type等是不是一样 if ((!matches) || (!dev->of_node)) return NULL; return of_match_node(matches, dev->of_node); */ if(of_driver_match_device(dev,drv)) { return 1; } /** 如果平台驱动提供了id_table,那么就会platform_match_id函数 id_table的出现,让一个驱动支持多个设备成为可能。 platform_match_id()这个函数会在下面说 */ if(pdrv->id_table) { return platform_match_id(pdrv->id_table,pdev) != NULL; } /** 如果平台驱动没有提供id_table,那么就会利用名字来比较了 如果是这样,一个驱动只能支持一个设备了 */ return (strcmp(pdev->name,drv->name) == 0); } /** 这个函数 会在驱动的id_table表里面 查找和platform_device的name字段相同的一项 如果相同,那么就返回true,否则返回false, 所以 : 这样就可以一个驱动支持多个设备, 如果只是简单的比较name的话,那么一个驱动只能支持一个设备 */ static const struct platform_device_id *platform_match_id( const struct platform_device_id *id, struct platform_device *pdev) { while (id->name[0]) { /** 还是比较每一项的名字 */ if (strcmp(pdev->name, id->name) == 0) { pdev->id_entry = id; return id; } id++; } return NULL; }
iic子系统
在前面的博文中已经详细的分析过,这里简单的说一下,方便对比
struct bus_type i2c_bus_type = { .name = "i2c", /** 匹配函数,下面看这个函数。 */ .match = i2c_device_match, /** iic总线提供了probe,匹配成功后会调用这个probe, 然后再这个probe中调用驱动的probe */ .probe = i2c_device_probe, .....};static int i2c_device_match(struct device *dev, struct device_driver *drv){ /** 根据type类型来检查是不是iic_client类型, */ struct i2c_client *client = i2c_verify_client(dev); struct i2c_driver *driver; /** 不是iic_client类型,就直接返回,因为这里要匹配是iic_client和对应的驱动 */ if (!client) { return 0; } /** 获取iic_driver,是为了在下面取出来它的id_table */ driver = to_i2c_driver(drv); /** 如果提供了id_table就调用i2c_match_id()来比较 */ if (driver->id_table) { /** 这个函数就是遍历id_table,取出每一个表项来与iic_client的name比较 其实还是利用了name比较, */ return i2c_match_id(driver->id_table, client) != NULL; } return 0;}/** 看最终还是和上面的platform调用的是同一个函数。*/static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, const struct i2c_client *client){ while (id->name[0]) { if (strcmp(client->name, id->name) == 0) return id; id++; } return NULL;}
usb子系统
struct bus_type usb_bus_type = { .name = "usb", /** 当调用usb_register()注册一个usb_driver的时候 __driver_attach() .... driver_match_device() 调用总线提供的match函数 如果这个match函数匹配不成功的话,那么就不会调用驱动提供的probe函数(这里总线没有提供probe) 具体match函数怎么做的,下面有分析 */ .match = usb_device_match, .uevent = usb_uevent,};static struct usb_driver usb_mouse_driver = { .name = "usbmouse", .probe = usb_mouse_probe, /** usb设备拔出后调用的函数 主要做一些销毁、释放、杀死urb的工作 */ .disconnect = usb_mouse_disconnect, /** 前面说过,要想你写的驱动支持某一个设备的话, 可以构造一个usb_device_id放到usb_mouse_id_table这个数组中 怎么构造,以前的博文已经说过,可以使用内核提供了一些宏来构造。 */ .id_table = usb_mouse_id_table,};
0 0
- 一个驱动支持多个设备再usb子系统、input子系统、platform、iic子系统 中的实现
- Linux设备驱动 --- input子系统
- linux ------ input 子系统设备驱动
- 输入设备驱动(input子系统)
- Linux设备驱动子系统 - USB
- linux设备驱动(三)--应用input子系统实现按键驱动
- Linux设备驱动子系统第三弹 - Input
- Linux设备驱动子系统第三弹 - Input
- Linux设备驱动子系统第三弹 - Input
- Linux设备驱动之input子系统
- Linux设备驱动子系统第三弹 - Input
- Linux设备驱动子系统终极弹 - USB
- Linux设备驱动子系统终极弹 - USB
- Linux设备驱动子系统终极弹 - USB
- Linux设备驱动子系统 - USB Gadget
- Linux设备驱动子系统终极弹 - USB
- Linux设备驱动子系统终极弹 - USB
- iic子系统
- 【BZOJ 3997】: [TJOI2015]组合数学
- JAVA之NIO按行读写大文件,完美解决中文乱码问题
- Linux、GUN/Linux、GUN、GPL以及各个发行版本详细介绍
- 二维码的生成
- MySQL存储过程
- 一个驱动支持多个设备再usb子系统、input子系统、platform、iic子系统 中的实现
- Unity问答第1期
- usleep和sleep的区别
- POJ 1003 Hangover
- Redis工作系列之一 与 Memcached对比理解
- HDU4632 Palindrome subsequence(区间DP)
- 《JavaScript DOM编程艺术》学习
- python 递归和装饰器
- Android属性动画(一)之基本用法