资源预览内容
第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
亲,该文档总共4页全部预览完了,如果喜欢就下载吧!
资源描述
驱动注册的 probe 函数probe 函数在设备驱动注册最后收尾工作,当设备的 device 和其对应的 driver 在总线上完成配对之后,系统就调用 platform 设备的probe 函数完成驱动注册最后工作。资源、中断调用函数以及其他相关工作。下面是 probe 被调用的一些程序流程。从 driver_register 看起:cpp view plaincopy1. int driver_register(struct device_driver * drv) 2. 3. klist_init( 4. init_completion( 5. return bus_add_driver(drv); 6. klist_init 与 init_completion 没去管它,可能是 2.6 的这个设备模型要做的一些工作。直觉告诉我要去 bus_add_driver。bus_add_driver 中:都是些 Kobject 与 klist 、attr 等。还是与设备模型有关的。但是其中有一句:driver_attach(drv);单听名字就很像:cpp view plaincopy1. void driver_attach(struct device_driver * drv) 2. 3. bus_for_each_dev(drv-bus, NULL, drv, _driver_attach); 4. 这个熟悉,遍历总线上的设备并设用_driver_attach。在_driver_attach 中又主要是这样:driver_probe_device(drv, dev);跑到 driver_probe_device 中去看看:有一段很重要:if (drv-bus-match & !drv-bus-match(dev, drv)goto Done;明显,是调用的驱动的总线上的 match 函数。如果返回 1,则可以继续,否则就 Done 了。继承执行的话:cpp view plaincopy1. if (drv-probe) 2. ret = drv-probe(dev); 3. if (ret) 4. dev-driver = NULL; 5. goto ProbeFailed; 6. 只要 probe 存在则调用之。至此就完成了 probe 的调用。这个过程链的关键还是在 drv-bus-match ,因为其余的地方出错的话就是注册失败,而只要注册不失败且 match 返回 1,那么就铁定会调用驱程的 probe 了。你可以注册一个总线类型和总线,并在 match 中总是返回 1, 会发现,只要 struct device_driver 中的 bus 类型正确时,probe 函数总是被调用.有两个重要的链表挂在 bus 上,一个是设备 device 链表,一个是驱动 driver 链表。每当我们向一根 bus 注册一个驱动 driver 时,套路是这样的:driver_register(struct device_driver * drv) - bus_add_driver() - driver_attach() -bus_for_each_dev(drv-bus, NULL, drv, _driver_attach);bus_for_each_dev 遍历该总线上所有的 device,执行一次_driver_attach(),看能不能将驱动关联(attach) 到某个设备上去。_driver_attach()-driver_probe_device()-drv-bus-match(dev, drv), / 调用 bus 的 match 函数,看 device 和 driver 匹不匹配。如果匹配上,继续执行 really_probe()。-really_probe()-driver-probe()。( 如果 bus-probe 非空,则调用 bus-probe)而每当我们向一根 bus 添加一个硬件时时,套路是这样的:device_add() device_add 中有很多操作 kobject,注册 sysfs,形成硬件 hiberarchy 结构的代码。如果您忘记了,先回头去参考参考我是 sysfs-bus_attach_device() - device_attach() -bus_for_each_drv()bus_for_each_drv 与 bus_for_each_dev 类似,遍历该总线上所有的 driver,执行一次_device_attach() ,看能不能将设备关联(attach)到某个已登记的驱动上去。_device_attach()-driver_probe_device() /后面与上面一样总结一些,一句话,注册一个某个 bus 的驱动就是先把驱动自己链入到 bus 驱动链表中去,在从 bus 的设备链表中一一寻找,看有没有自己可以关联上的设备。找到就 probe,再把二者 bind 起来。反之,添加设备道理也是一样的。论坛讨论帖:1. 在看 platform 驱动是,发现一个很低能的问题,static int _devinitdm9000_probe(struct platform_device *pdev) 中的 struct platform_device *pdev 是从那里来的 device,跟踪 platform_driver_register(一直没有发现 platform_device 的出现,但是现在 probe 函数中突然出现了这个变量,那么这个变量是从和而来?2. platform 驱动分为 platform_driver 和 platform_device 两个结构体表示,前者表示平台驱动,后者表示平台设备,这个 struct platform_device *pdev 就是在平台相关文件里注册的。平台下会定义一个 platform_device,然后platform_device_register(&platform_device),所以你注册的平台驱动,当在 platform_bus 上探测到有个设备的时候,这个你之前在平台文件里注册的 platform_device 就会传过来。3. platform_bus 上探测到有个设备的时候此句怎么理解, 是怎么探测到的呢?4. 驱动肯定是自己注册了。至于设备的注册,有些设备所使用的协议有枚举过程,从这处过程中可以得到设备信息,进而生成相应设备结构体,然后注册在相应总线上。在总线上注册设备时,会遍历该总线上已注册的驱动,用总线的 match 方法判断是否有匹配的驱动,如果有,则调用驱动的 probe 函数;在总线上注册驱动时,会遍历该总线上已注册的设备,用总线的 match 方法判断是否有匹配的设备,如果有,则调用驱动的 probe 函数。即,不管是先注册设备还是先注册驱动,总线的 match 方法会作用于所有组合,如果匹配了,则调用驱动的 probe 方法,这样就探测到了。platform_bus 是虚拟的总线,没有具体的协议。上面所讲设备的结构体是在枚举时动态生成的,设备的注册也是在枚举时触发的,而platform_device 的定义与注册是在平台初始化文件里手动做的。后面的情况就是一样的了。其它一些没有类似枚举之类过程的总线,如I2C,也是这种流程。5. 内核启动的时候, platform_device 是优先于 platform_driver 注册的。 比如 platform_device A , 是在 arch/arm/mach-XXXX/mach-XXXX.c 文件里注册的, 而这个文件的代码是 优先于 platform_driver_register 执行的。所以在你 platform_driver_register 执行的时候, platform_device A 已经被挂在 platform_bus 总线上了, 而platform_driver_register()有个功能是到 platform_bus 上去挨个找寻,找寻挂在上面的 platform_bus 上的 platform_device。找到了就执行 probe()。6. 可不可以这样,我没有试过。但是因为驱动中有 开发者实现的 probe 函数。 如果先注册驱动, 驱动就找不到设备, 从而不执行 probe 函数,而驱动中最重要的就是 probe 函数,硬件的初始化,寄存器的配置,时钟的使能都在 probe 函数里完成。从这一点来说,驱动先于设备注册,应该不可行。7. 你好,关于 I2C 驱动,目前有三个问题想请教下: 1,请问用 i2c_add_driver 注册 I2C 的 client 端的驱动的时候,这个 client 是怎么和哪个 adapter attach 的(在此之前,系统中注册了四个 bit-style 的 adapter)?注意,我的 i2c_driver 中,并没有赋值 attach_adapter,但是赋值了 probe2,注册 adapter 是用的 i2c_add_adapter,跟了下这个函数,发现它 call 的是-i2c_register_adapter-adap-dev.bus = adap-dev.type = res = device_register(这里是注册的是一个 device,那么根据 device-driver 的模型,那 adapter 的 driver 是怎么被赋值的呢?3,i2c_add_driver 是向哪跟总线上注册的,是 i2c_bus_type 吗?i2c_register_adapter 又是向哪跟总线注册的呢? 也是i2c_bus_type 吗?谢谢8. i2c_driver 并不是要跟 adapter 绑定,而是要和 i2c_client 绑定 。注册一个 i2c_driver 时并不知道它支持的设备在哪条总线上。例如一个系统有两个 i2c 控制器,每个控制器上有一个相同型号的 EEPROM,它们只需一个 i2c_driver。关键在于如何发现哪条总线上有i2c_driver 所支持设备。老 I2C 框架里,由 i2c_driver 负责发现设备,每注册一个 adapter 遍历已注册 i2c_driver,每注册一个 i2c_driver 遍历已注册的i2c_adapter,不让他们错过任何一次组合,让 i2c_driver 在 adapter 上探测一下是否有它支持的设备,如果有,则生成一个 i2c_client实例。当然由于 i2c 协议很弱,这种探测很不可靠。现在(尤其在 SOC 系统中)倾向于静态定义这些信息:如果我知道哪条总线上有哪个设备,我就犯不着让 i2c_driver 去找它们了。于是在平台初始化函数里注册 i2c_board_info,这个结构体就是一个 i2c_client 模板。i2c_board_info 里有个 bus_num 作为匹配的凭证,如果bus_num 与 i2c_adapter 的 bus_num 相同,那就匹配上了。所有注册的 i2c_board_info 会放在一个链表里,每注册一个 i2c_adapter就去扫描这个链表,如果匹配就生成 i2c_client。在老框架,i2c_client 肯定是在 i2c_driver 时调用 attach_adapter 时出现的;新框架里则可以在没有 i2c_driver 的情况下根据静态信息生成 i2c_client。另外让 i2c_driver 探测设备时,顶多能知道设备地址,而欲查询设备其它属性,i2c 协议里
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号