驱动编写的 3 种方法
1. 传统写法
使用哪个引脚,怎么操作引脚,都写死在了代码中。
最简单,不考虑扩展性,可以快速实现功能。
修改引脚时需要重新编译。
2. 总线设备驱动模型
引入 platfrom_device/platform_driver,将“资源”与“驱动”分离开来。
代码稍微复杂,但是易于扩展。
冗余代码太多,修改引脚时设备端的代码需要重新编译。
3. 设备树
通过配置文件——设备树来定义“资源”。
代码稍微复杂,但是易于扩展。
无冗余代码,修改引脚时只需要修改 dts 文件并编译得到 dtb 文件,把它传给内核。
无需重新编译内核/驱动。
在 Linux 中实现“分离”:Bus/Dev/Drv 模型
Dev 和 Drv 的匹配规则
1. 最先比较
- platform_device. driver_override 和 platform_driver. driver. name
可以设置 platform_device 的 driver_override,强制选择某个 platform_driver。相当于非他不嫁。
2. 然后比较
- platform_device. name 和 platform_driver. id_table[i]. nmae
platform_driver. id_table 是“platform_device_id”指针,表示该 drv 支持若干个 device,它里面列出各个 device 的{ .name, .driver_data },其中“name”表示该 drv 支持的设备的名字,driver_data 是写提供给该 device 的私有数据。
3. 最后比较
- platform_device. name 和 platform_driver. driver. name
platform_driver. id_table 可能为空,这时就比较这俩。
常用函数
这些函数可在内核源码查看:drivers.c/base. c/platform. c,根据函数名即可知道其含义。
注册/反注册
platform_device_register / platform_device_unregister
platform_device_register / platform_device_unregister
platform_add_devices
获取资源
- 返回该 dev 中某类型(type)资源中的第几个(num):
struct resource *platform_get_resource(struct platform_device *dev,unsigned int type,unsigned int num)
- 返回该 dev 所用的第几个(num)中断:
int platform_get_irq(struct platform_device *dev,unsigned int num)
- 通过名字(name)返回该 dev 的某类型(type)资源:
struct resource *platform_get_resource_byname(struct platform_device *dev,unsigned int type,const char *name)
- 通过名字(name)返回该 dev 的中断号:
int platform_get_irq_byname(struct platform_device *dev,const char *name)