platform平台总线工作原理详解

一、platform平台总线的简介
(1)相对于USB、PCI、I2C、SPI等物理总线来说,platform总线是一种虚拟、抽象出来的总线,实际中并不存在这样的总线。
(2)cpu与外部通信的两种方式,地址总线式链接(32的cpu就有0-4G直接集成在cpu内部,以地址指针方式直接访问,没有具体的总线链接就用虚拟的platform平台总线来控制内部的外设)和专用接口式(iic,pci,usb等这些外部总线链接的)链接平台总线对应地址总线式链接设备,也就是soc内部集成的各种内部外设

(3)思考:为什么要有平台总线?进一步思考:为什么要有总线的概念?
因为大多数设备都是集成在soc内部,和cpu直接连接,将其直接扩展到内部地址空间,因此他们本身就不该就有总线的概念,本身就不属于总线的链接方式,但是如果一部分设备设计得有总线,一部分没总线就太乱了,所以除了iic,pci,spi等的设备就归类到平台总线来便于管理

二、platform平台总线下管理的2员大将
(1)platform工作体系都定义在drivers/base/platform.c中
(2)两个结构体:platform_device和platform_driver
(3)两个接口函数:platform_device_register和platform_driver_register

1、platform_device

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 resource resource
struct resource { // 资源结构体
resource_size_t start; // 资源的起始值,如果是地址,那么是物理地址,不是虚拟地址
resource_size_t end; // 资源的结束值,如果是地址,那么是物理地址,不是虚拟地址
const char *name; // 资源名
unsigned long flags; // 资源的标示,用来识别不同的资源
struct resource *parent, *sibling, *child; // 资源指针,可以构成链表
};

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;  // 设备ID表
};

三、平台总线本身的初始化函数platform_bus_init

int __init platform_bus_init(void)
{
    int error;
    early_platform_cleanup();   //  进行一些早期的平台清理  
    error = device_register(&platform_bus); //  注册设备 (在/sys/devices/目录下建立 platform目录对应的设备对象  /sys/devices/platform/) 
    if (error)
        return error;
    error =  bus_register(&platform_bus_type);  //  总线注册
    if (error)
        device_unregister(&platform_bus);
    return error;
}

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

2、代码分析: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,如果匹配上就匹配上了,如果还没匹配上那就匹配失败

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

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

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值