【linux】驱动-7-平台设备驱动

时间:2021-04-01 14:10:41   收藏:0   阅读:30


前言

区分设备驱动模型平台设备驱动模型
设备驱动模型 可以理解为 总线、设备、驱动
平台设备驱动模型 就是那些 Linux 内核管理没有物理总线(即是不需要特殊时序控制的设备)(也是Linux内核没有自动创建相应驱动总线的设备类型)的设备的一套 Linux 平台总线、平台模型、平台驱动的模型。

7. 平台设备驱动

为解决驱动代码和设备信息耦合问题,linux提出了设备驱动模型。

注意,前面的总线、设备、驱动是一个软件层面的抽象,与 SOC 中物理总线概念不一样。

物理总线:芯片与各个功能外设之间传送信息的公共通信干线,包括数据总线、地址总线和控制总线,以此来传输各种通信时序
驱动总线:负责管理驱动和设备。制定设备和驱动的匹配规则。一旦总线上注册了新设备/驱动,总线便执行匹配程序。

对于常见的 I2C、SPI、USB物理总线Linux 内核都会自动创建与之对应的 驱动总线。所以 I2C设备、SPI设备、USB设备都会挂在在相应的总线上。

相对的,实际项目开发中还有很多结构简单的设备是不需要特殊的时序控制的。也就没有相应的物理总线,Linux 也不会为它们创建相应的驱动总线。如 LED、RTC时钟、按键等等。

但是为了这些简单的设备也能遵循设备驱动模型,Linux 内核引入了一种虚拟总线--平台总线
平台总线 用于管理、挂在那些没有物理总线的设备,且,这些设备被称为平台设备,对应的设备驱动被称为平台驱动

平台设备使用 platform_device 结构体进行表示,继承了设备驱动模型中的 device 结构体。
平台驱动使用 platform_driver 结构体进行表示,继承了设备驱动模型中的 device_driver 结构体。

7.1 平台总线

Linux内核只有一条平台总线,用于图一管理简单设备--platform_bus_type

7.1.1 平台总线注册和匹配方式

最先比较

其次比较

最后比较

7.1.2 源码分析

平台总线

struct bus_type platform_bus_type = {

    .name           = "platform",
    .dev_groups     = platform_dev_groups,
    .match          = platform_match,
    .uevent         = platform_uevent,
    .pm             = &platform_dev_pm_ops,

};

EXPORT_SYMBOL_GPL(platform_bus_type);
int __init platform_bus_init(void){
    int error;
    ...
    error =  bus_register(&platform_bus_type);
    ...
    return error;}

建议:以上匹配规则及源码,可以追踪函数 platform_match 源码来分析。

7.2 平台设备

7.2.1 platform_device

平台设备

struct platform_device {
     const char *name;
     int id;
     struct device dev;
     u32 num_resources;
     struct resource *resource;
     const struct platform_device_id *id_entry;
     /* 省略部分成员 */
 };

7.2.2 设备信息

平台设备的工作是为 驱动程序 提供 设备信息。包括 硬件信息 和 软件信息。

硬件信息

/** 
  * Resources are tree-like, allowing nesting etc..
  */
struct resource {
    resource_size_t start;
    resource_size_t end;
    const char *name;
    unsigned long flags;
    /* 省略部分成员 */
};

设备驱动程序主要目的还是操作设备的寄存器。
不同架构的计算机提供不同的操作接口,主要有IO端口映射IO内存映射两种方式。

IO端口映射方式:

IO内存映射方式:

软件信息

7.2.3 注册/注销平台设备

注册:platform_device_register

注销:platform_device_unregister

7.3 平台驱动

7.3.1 platform_driver

平台驱动

struct platform_driver {

    int (*probe)(struct platform_device *);
    int (*remove)(struct platform_device *);
    struct device_driver driver;
    const struct platform_device_id *id_table;
};
struct platform_device_id 
{
    char name[PLATFORM_NAME_SIZE];
    kernel_ulong_t driver_data;
};

7.3.2 注册/注销平台驱动

注册:platform_driver_register

注销:platform_driver_unregister

7.3.3 平台驱动获取设备信息

首先要知道的是,平台设备的硬件信息保存在 resource 结构体中。而软件信息则保存在 platform_data 中。

获取硬件信息:platform_get_resource

获取软件信息:dev_get_platdata
* dev:struct device 结构体类型指针。

static inline void *dev_get_platdata(const struct device *dev)
{
    return dev->platform_data;
}

参考

原文:https://www.cnblogs.com/lizhuming/p/14605803.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!