Linux设备模型(十一) - platform设备

本文详细介绍了Linux2.6以后的设备驱动模型中platform_device的概念,涉及平台总线、设备注册、driver的probe和register方法,以及如何通过platform_device来隔离BSP和驱动,提高设备驱动的可扩展性和跨平台性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,platform device概述

在Linux2.6以后的设备驱动模型中,需关心总线、设备和驱动这3个实体,总线将设备和驱动绑定。在系统每注册一个设备的时候,

会寻找与之匹配的驱动;相反的,在系统每注册一个设备的时候,会寻找与之匹配的设备,而匹配由总线完成。

一个现实的Linux设备和驱动通常都需要挂接在一种总线上,而对于本身依附于PCI、USB、I2C、SPI等的设备而言,这自然不是问题,

但是在嵌入式系统里面,在SoC系统中集成的独立外设控制器、挂接在SoC内存空间的外设等却不依附于此类总线。基于这一背景,Linux

发明了一种虚拟总线,称为platform总线,相应的设备称为platform_device,而驱动称为platform_driver。

所谓的platform_device并不是与字符设备、块设备和网络设备并存的概念,而是linux系统提供的一种附加手段,例如,我们通常把在

SoC内部集成的I2C、RTC、LCD、看门狗等控制器都归纳为platform_device,而他们本身就是字符设备。这些设备有一个基本的特征:可以通过CPU bus直接寻址(例如在嵌入式系统常见的“寄存器”)。

二,platform模块的软件架构

内核中Platform设备有关的实现位于include/linux/platform_device.h和drivers/base/platform.c两个文件中,它的软件架构如下:

由图片可知,Platform设备在内核中的实现主要包括三个部分:

Platform Bus,基于底层bus模块,抽象出一个虚拟的Platform bus,用于挂载Platform设备;

Platform Device,基于底层device模块,抽象出Platform Device,用于表示Platform设备;

Platform Driver,基于底层device_driver模块,抽象出Platform Driver,用于驱动Platform设备。

其中Platform Device和Platform Driver会给其它Driver提供封装好的API,具体可参考后面的描述。

三,platform bus/platform device/platform driver结构体

1,platform_driver

// msm_kernel\include\linux\platform_device.h
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_table的指针,该指针和of_match_table、acpi_match_table的功能类似:提供其它方式的设备probe */
    bool prevent_deferred_probe;

    ANDROID_KABI_RESERVE(1);
};

2,platform_device

// msm_kernel\include\linux\platform_device.h
struct platform_device {
    const char    *name; /* 设备的名称,和struct device结构中的init_name意义相同。实际上,该名称在设备注册时,会拷贝到dev.init_name中 */
    int        id; /* 用于标识该设备的ID。内核允许存在多个名称相同的设备。而设备驱动的probe,依赖于名称,Linux采取的策略是:在bus的设备链表中查找device,和对应的device_driver比对name,如果相同,则查看该设备是否已经绑定了driver(查看其dev->driver指针是否为空),如果已绑定,则不会执行probe动作,如果没有绑定,则以该device的指针为参数,调用driver的probe接口。
因此,在driver的probe接口中,通过判断设备的ID,可以知道此次驱动的设备是哪个*/
    bool        id_auto; /* 指示在注册设备时,是否自动赋予ID值 */
    struct device    dev; /* 真正的设备(Platform设备只是一个特殊的设备,因此其核心逻辑还是由底层的模块实现) */
    u64        platform_dma_mask;
    struct device_dma_parameters dma_parms;
    u32        num_resources;
    struct resource    *resource; /* 该设备的资源描述,由struct resource(include/linux/ioport.h)结构抽象 */

    const struct platform_device_id    *id_entry;
    char *driver_override; /* Driver name to force a match */

    /* MFD cell pointer */
    struct mfd_cell *mfd_cell;

    /* arch specific additions */
    struct pdev_archdata    archdata;

    ANDROID_KABI_RESERVE(1);
    ANDROID_KABI_RESERVE(2);
};

3,platform bus

// msm_kernel\drivers\base\platform.c
struct bus_type platform_bus_type = {
    .name        = "platform",
    .dev_groups    = platform_dev_groups,
    .match    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值