什么是平台总线模型: 是linux系统假造出来的总线, 没有对应的硬件接口
平台总线模型将一个驱动分成了两个部分
device.c: 描述硬件资源代码, 描述寄存器的地点, 中断号
driver.c: 控制硬件的驱动代码, 操作寄存器, 处理中断
这两个部分通过相同的name进行匹配
为什么要使用平台总线, 平台总线的优点
差异的处理器的相同功能的寄存器不在一个位置, 但是使用驱动可以是同一套
注册平台设备
device.c描述的硬件资源是
硬件的寄存器的地点, 中断号, 和其他硬件资源
使用下面的结构体描述- struct platform_device {
- // 名字, 和driver匹配, 可以在sys目录下看到
- const char *name;
- // 区分不同的设备, sys目录下的设备文件的后缀(-1无后缀)
- int id;
- bool id_auto; // 自动设置id, 一般不用
- // 设备的通用属性部分, 必须实现里面的release函数
- struct device dev;
- u64 platform_dma_mask;
- struct device_dma_parameters dma_parms;
- // 存储资源的个数
- u32 num_resources;
- // 存放硬件资源的结构体
- struct resource *resource;
- const struct platform_device_id *id_entry;
- const char *driver_override;
- /* MFD cell pointer */
- struct mfd_cell *mfd_cell;
- /* arch specific additions */
- struct pdev_archdata archdata;
- };
复制代码 描述硬件资源的结构体- // linux-master/include/linux/ioport.h
- struct resource {
- resource_size_t start;
- resource_size_t end;
- const char *name;
- unsigned long flags;
- unsigned long desc;
- struct resource *parent, *sibling, *child;
- };
复制代码
- start/end: 资源的起始信息和终止信息, 比如寄存器的起始地点和终止地点
- flags: 硬件资源信息的范例, 在include/linux/ioport.h路径下列举
硬件资源举例- static struct resource my_device_resources[] = {
- [0] = {
- .start = 0xFDD60000,
- .end = 0xFDD60004,
- .flags = IORESOURCE_MEM, // 内存类型或寄存器
- },
- [1] = {
- .start = 13,
- .end = 13,
- .flags= IORESOURCE_IRQ, // 中断类型
- },
- };
复制代码 platform设备加卸载函数: 把设备加载到总线上- int platform_device_register(struct platform_device *pdev)
- void platform_device_unregister(struct platform_device *pdev)
复制代码 注册平台驱动
- 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;
- bool prevent_deferred_probe;
- bool driver_managed_dma;
- };
复制代码
- probe: 必须实现, 当设备和驱动匹配乐成之后, 自动执行
- remove: 移出一个设备的时候执行
- shutdown: 电源管理, 关掉设备时执行
- suspend: 电源管理, 挂起时执行
- resume: 电源管理, 恢复时执行
- driver: 设备共用的一些属性
- id_table: 设备的ID表
platform驱动加卸载函数- const struct platform_device_id mydriver_id_table = {
- .name = "mydevice",
- };
- struct platform driver platform driver test ={
- .probe = mydriver_probe,
- .remove =mydriver_remove,
- .driver = {
- .name ="mydevice",
- .owner = THIS_MODULE,
- }
- // id_table的优先级大于drive中的name
- .id_table = &mydriver_id_table,
- }
- int platform_driver_register(struct platform_driver *drv, struct module *owner)
- void platform_driver_unregister(struct platform_driver *drv);
复制代码 设备和驱动的匹配方法
平台设备和驱动的匹配方法
- 先通过platform_driver中的id_table
- 假如id_table不存在,则只是简单的比较设备中的name字段和驱动中的name字段是否相同
- static int platform_match(struct device *dev, struct device_driver *drv)
- {
- ...
- /* Then try to match against the id table */
- if (pdrv->id_table)
- return platform_match_id(pdrv->id_table, pdev) != NULL;
- /* fall-back to driver name match */
- return (strcmp(pdev->name, drv->name) == 0);
- }
复制代码 获取设备资源
获取设备资源的函数
platform_get_resource: 返回设备指定范例的第num个资源- struct resource *platform_get_resource(struct platform_device *dev,
- unsigned int type, unsigned int num)
- {
- u32 i;
- for (i = 0; i < dev->num_resources; i++) {
- struct resource *r = &dev->resource[i];
- if (type == resource_type(r) && num-- == 0)
- return r;
- }
- return NULL;
- }
复制代码 用户程序通过平台总线访问设备寄存器的例子
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |