• platform平台总线


    一、何为平台总线

    (1)相对于usb、pci、i2c等物理总线来说,platform总线是虚拟的、抽象出来的。
    (2)CPU与外部通信的2种方式:地址总线式连接和专用协议类接口式连接。平台总线,是扩展到CPU的32位地址线的寻址空间的里面的那一类设备,即对应地址总线式连接设备,其实就是SoC内部集成的各种内部外设。
    (3)思考:为什么要有平台总线?进一步思考:为什么要有总线的概念?

    因为CPU和有一些外设是集成在一块的(构成SoC),而且这些内部外设是直接扩展到CPU的地址空间的,可以说在这一类设备里面根本就没有总线的概念(因为总线这个概念天生就是给usb、pci、i2c、spi等这类设备设计的,但是又不能说有的设备有总线,有的设备没总线,若这样设计的话看起来就比较乱了,所以就干脆规定所有的设备都有总线,所以平台总线可以看作为那些不需要总线的设备发明的,所以它是虚拟出来的)。

    总线是为了把总线下的那些设备和驱动连接起来,是为了管理方便。

    二、平台总线下管理的2员大将
    (1)platform工作体系都定义在drivers/base/platform.c中,入口函数为 platform_bus_init。另外需要注意的是drivers/base目录下的文件基本都是内核提供的驱动底层架构相关的文件,基本是不需要动的。
    (2)两个结构体:platform_device和platform_driver(写一个平台驱动其实就是写platform_driver结构内的函数,然后注册就可以了)
    (3)提供两个接口函数:platform_device_register和platform_driver_register

    struct platform_device {
    const char * name; // 平台总线下设备的名字
    int id;                        
    struct device dev; // 所有设备通用的属性部分
    u32 num_resources; // 设备使用到的resource的个数
    struct resource * resource; // 设备使用到的资源数组的首地址

    const struct platform_device_id *id_entry; // 设备ID表

    /* arch specific additions */
    struct pdev_archdata archdata; // 自留地,用来提供扩展性的
    };

    struct platform_driver {
    int (*probe)(struct platform_device *); // 驱动探测(安装,“类似”insmod)函数
    int (*remove)(struct platform_device *); // 去掉一个设备,类似于“rmmod”
    void (*shutdown)(struct platform_device *); // 关闭一个设备
    int (*suspend)(struct platform_device *, pm_message_t state);   //挂起一个设备(电源管理相关的)
    int (*resume)(struct platform_device *);                                       //恢复(唤醒)一个设备,和suspend相对应
    struct device_driver driver; // 所有设备共用的一些属性
    const struct platform_device_id *id_table; // 设备ID表
    };


    三、平台总线体系的工作流程
    (1)第一步:系统启动时在bus系统(内核中用来管理总线的的一套体系)中注册platform( platform_bus_init函数)
    (2)第二步:内核移植的人负责提供设备(数据)platform_device
    (3)第三步:写驱动的人负责提供platform_driver(需要编写相关代码)
    (4)第四步:platform的match函数发现driver和device匹配后,调用driver的probe函数来完成驱动的初始化和安装,然后设备就工作起来了

    四、platform本身注册
    (1)每种总线(不光是platform,usb、i2c那些也是)都会带一个match方法,match方法用来对总线下的device和driver进行匹配。理论上每种总线的匹配算法是不同的,但是实际上一般都是看name的(驱动和设备名字相同)。
    (2)platform_match函数就是平台总线的匹配方法。该函数的工作方法是:如果有id_table就说明驱动可能支持多个设备,所以这时候要去对比id_table中所有的name,只要找到一个相同的就匹配上了不再找了,如果找完id_table都还没找到就说明每匹配上;如果没有id_table或者每匹配上,那就直接对比device和driver的name,如果匹配上就匹配上了,如果还没匹配上那就匹配失败。



    五、以leds-s3c24xx.c为例来分析platform设备和驱动的注册过程
    (1)platform_driver_register
    (2)platform_device_register

    六、platdata怎么玩
    (1)platdata其实就是设备注册时提供的设备有关的一些数据(譬如设备对应的gpio、使用到的中断号、设备名称····)
    (2)这些数据在设备和驱动match之后,会由设备方转给驱动方。驱动拿到这些数据后,通过这些数据得知设备的具体信息,然后来操作设备。
    (3)这样做的好处是:驱动源码中不携带数据,只负责算法(对硬件的操作方法)。现代驱动设计理念就是算法和数据分离,这样最大程度保持驱动的独立性和适应性。

    七、match函数的调用轨迹
    八、probe函数的功能和意义

  • 相关阅读:
    oracle乱码问题
    fopen 參数具体解释
    图像特征提取方法:Bag-of-words
    事务应用-运行多条SQL语句
    八大排序算法总结
    svn经常使用命令具体解释(非常全,非常有用)
    android layout属性介绍
    ubuntu/linux mint 创建proc文件的三种方法(四)
    在归档模式下删除非系统文件的恢复
    解决使用DevExpress开发错误:未将对象引用设置到对象的实例
  • 原文地址:https://www.cnblogs.com/zhangshuaifeng/p/10649815.html
Copyright © 2020-2023  润新知