linux平台总线模型

打印 上一主题 下一主题

主题 999|帖子 999|积分 2997

什么是平台总线模型: 是linux系统假造出来的总线, 没有对应的硬件接口
平台总线模型将一个驱动分成了两个部分
device.c: 描述硬件资源代码, 描述寄存器的地点, 中断号
driver.c: 控制硬件的驱动代码, 操作寄存器, 处理中断
这两个部分通过相同的name进行匹配
为什么要使用平台总线, 平台总线的优点
差异的处理器的相同功能的寄存器不在一个位置, 但是使用驱动可以是同一套

  • 减少编写的重复代码, 提高服从
  • 提高代码的使用率
注册平台设备

device.c描述的硬件资源是
硬件的寄存器的地点, 中断号, 和其他硬件资源
使用下面的结构体描述
  1. struct platform_device {
  2.     // 名字, 和driver匹配, 可以在sys目录下看到
  3.         const char        *name;
  4.         // 区分不同的设备, sys目录下的设备文件的后缀(-1无后缀)
  5.         int                id;
  6.         bool                id_auto; // 自动设置id, 一般不用
  7.     // 设备的通用属性部分, 必须实现里面的release函数
  8.         struct device        dev;
  9.         u64                platform_dma_mask;
  10.         struct device_dma_parameters dma_parms;
  11.     // 存储资源的个数
  12.         u32                num_resources;
  13.         // 存放硬件资源的结构体
  14.         struct resource        *resource;
  15.         const struct platform_device_id        *id_entry;
  16.         const char *driver_override;
  17.         /* MFD cell pointer */
  18.         struct mfd_cell *mfd_cell;
  19.         /* arch specific additions */
  20.         struct pdev_archdata        archdata;
  21. };
复制代码
描述硬件资源的结构体
  1. // linux-master/include/linux/ioport.h
  2. struct resource {
  3.         resource_size_t start;
  4.         resource_size_t end;
  5.         const char *name;
  6.         unsigned long flags;
  7.         unsigned long desc;
  8.         struct resource *parent, *sibling, *child;
  9. };
复制代码

  • start/end: 资源的起始信息和终止信息, 比如寄存器的起始地点和终止地点
  • flags: 硬件资源信息的范例, 在include/linux/ioport.h路径下列举
硬件资源举例
  1. static struct resource my_device_resources[] = {
  2.     [0] = {
  3.         .start = 0xFDD60000,
  4.         .end = 0xFDD60004,
  5.         .flags = IORESOURCE_MEM, // 内存类型或寄存器
  6.     },
  7.     [1] = {
  8.         .start = 13,
  9.         .end = 13,
  10.         .flags= IORESOURCE_IRQ, // 中断类型
  11.     },
  12. };
复制代码
platform设备加卸载函数: 把设备加载到总线上
  1. int platform_device_register(struct platform_device *pdev)
  2. void platform_device_unregister(struct platform_device *pdev)
复制代码
注册平台驱动
  1. struct platform_driver {
  2.         int (*probe)(struct platform_device *);
  3.         int (*remove)(struct platform_device *);
  4.         void (*shutdown)(struct platform_device *);
  5.         int (*suspend)(struct platform_device *, pm_message_t state);
  6.         int (*resume)(struct platform_device *);
  7.         struct device_driver driver;
  8.         const struct platform_device_id *id_table;
  9.         bool prevent_deferred_probe;
  10.         bool driver_managed_dma;
  11. };
复制代码

  • probe: 必须实现, 当设备和驱动匹配乐成之后, 自动执行
  • remove: 移出一个设备的时候执行
  • shutdown: 电源管理, 关掉设备时执行
  • suspend: 电源管理, 挂起时执行
  • resume: 电源管理, 恢复时执行
  • driver: 设备共用的一些属性
  • id_table: 设备的ID表
platform驱动加卸载函数
  1. const struct platform_device_id mydriver_id_table = {
  2.     .name = "mydevice",
  3. };
  4. struct platform driver platform driver test ={
  5.     .probe = mydriver_probe,
  6.     .remove =mydriver_remove,
  7.     .driver = {
  8.         .name ="mydevice",
  9.         .owner = THIS_MODULE,
  10.     }
  11.     // id_table的优先级大于drive中的name
  12.     .id_table = &mydriver_id_table,
  13. }
  14. int platform_driver_register(struct platform_driver *drv, struct module *owner)
  15. void platform_driver_unregister(struct platform_driver *drv);
复制代码
设备和驱动的匹配方法

平台设备和驱动的匹配方法

  • 先通过platform_driver中的id_table
  • 假如id_table不存在,则只是简单的比较设备中的name字段和驱动中的name字段是否相同
  1. static int platform_match(struct device *dev, struct device_driver *drv)
  2. {
  3.     ...
  4.         /* Then try to match against the id table */
  5.         if (pdrv->id_table)
  6.                 return platform_match_id(pdrv->id_table, pdev) != NULL;
  7.         /* fall-back to driver name match */
  8.         return (strcmp(pdev->name, drv->name) == 0);
  9. }
复制代码
获取设备资源

获取设备资源的函数
platform_get_resource: 返回设备指定范例的第num个资源
  1. struct resource *platform_get_resource(struct platform_device *dev,
  2.                                        unsigned int type, unsigned int num)
  3. {
  4.         u32 i;
  5.         for (i = 0; i < dev->num_resources; i++) {
  6.                 struct resource *r = &dev->resource[i];
  7.                 if (type == resource_type(r) && num-- == 0)
  8.                         return r;
  9.         }
  10.         return NULL;
  11. }
复制代码
用户程序通过平台总线访问设备寄存器的例子



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

三尺非寒

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表