嵌入式系统中有很多的物理总线:I2c、SPI、USB、uart、PCIE、APB、AHB
linux从2.6起就加入了一套新的驱动管理和注册的机制platform平台总线,是一条虚拟的总线,并不是一个物理的总线。
相比 PCI、USB,它主要用于描述SOC上的片上资源。platform 所描述的资源有一个共同点:在CPU 的总线上直接取址。
平台设备会分到一个名称(用在驱动绑定中)以及一系列诸如地址和中断请求号(IRQ)之类的资源。
设备用platform_device表示,驱动用platform_driver进行注册。
与传统的bus/device/driver机制相比,platform由内核进行统一管理,在驱动中使用资源,提高了代码的安全性和可移植性。
二、platform
1. platform总线两个最重要的结构体
platform维护的所有的驱动都必须要用该结构体定义:
platform_driver
- 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;
- bool prevent_deferred_probe;
- };
该结构体,用于注册驱动到platform总线,
成员 | 含义 |
---|---|
probe | 当驱动和硬件信息匹配成功之后,就会调用probe函数,驱动所有的资源的注册和初始化全部放在probe函数中 |
remove | 硬件信息被移除了,或者驱动被卸载了,全部要释放,释放资源的操作就放在该函数中 |
struct device_driver driver | 内核维护的所有的驱动必须包含该成员,通常driver->name用于和设备进行匹配 |
const struct platform_device_id *id_table | 往往一个驱动可能能同时支持多个硬件,这些硬件的名字都放在该结构体数组中 |
我们编写驱动的时候往往需要填充以上几个成员
platform_device
platform总线用于描述设备硬件信息的结构体,包括该硬件的所有资源(io,memory、中断、DMA等等)。
- struct platform_device {
- const char *name;
- int id;
- bool id_auto;
- struct device dev;
- u32 num_resources;
- struct resource *resource;
- const struct platform_device_id *id_entry;
- /* MFD cell pointer */
- struct mfd_cell *mfd_cell;
- /* arch specific additions */
- struct pdev_archdata archdata;
- };
成员 | 含义 |
---|---|
const char*name | 设备的名字,用于和驱动进行匹配的 |
struct devicedev | 内核中维护的所有的设备必须包含该成员, |
u32num_resources | 资源个数 |
struct resource*resource | 描述资源 |
struct devicedev->release()必须实现,