Linux 平台设备模型
平台设备模型可以看作是bus device driver的一个实例. 主要构成有
- platform bus
- platform device
- platform driver
platform bus
就是bus_type
, 实现了里面的接口函数, 比如match, probe, remove等.
platform device
数据结构
- dev : device结构体
- name : 设备名, 和device.init_name一样
- id : 设备ID, 设备是可以同名的(一个驱动可以支持多个设备), 通过ID区分
- id_auto : 是否自动分配ID, 这样就不用手动设置ID了
num_resources
,resource
: 设备资源, 用于描述设备的资源, 比如内存地址, 中断号等
resource
用来表示系统的各种资源, 比如内存, IO端口, 中断等.
struct resource {
resource_size_t start; // 资源的起始地址
resource_size_t end; // 资源的结束地址
const char *name; // 资源的名称,用于标识资源
unsigned long flags; // 资源的标志位,用于描述资源的类型和属性. IORESOURCE_IO, IORESOURCE_MEM, IORESOURCE_IRQ, IORESOURCE_DMA. 现在IO通常和MEM是一个地址空间,所以通常我们使用的是IORESOURCE_MEM
struct resource *parent; // 指向父资源的指针
struct resource *sibling; // 指向兄弟资源的指针
struct resource *child; // 指向子资源的指针
};
内核通过 struct resource 构建了一棵资源树,用于管理和组织系统中的各种资源。例如:
iomem_resource
:表示整个内存资源树的根。
ioport_resource
:表示整个 I/O 端口资源树的根。
为什么是树形结构呢?因为资源之间存在父子关系,比如一个设备的内存资源和 I/O 端口资源就是设备资源的子资源。
API
-
platform_device.h
-
注册,注销
- int
platform_device_register
(struct platform_device *); - void
platform_device_unregister
(struct platform_device *); - struct platform_device*
platform_device_register_full
- struct platform_device*
platform_device_register_resndata
- struct platform_device*
platform_device_register_simple
- struct platform_device*
platform_device_register_data
//根据参数创建并注册一个平台设备 - struct platform_device*
platform_device_alloc
//分配一个平台设备结构体 - struct platform_device*
platform_create_bundle
(driver, probe, res, n_res, data, size) // 不仅创建注册平台设备还会主动调用 driver的probe函数(需要第二个参数显示传入).
- int
-
获取资源
- struct resource *
platform_get_resource
(struct platform_device *, unsigned int, unsigned int); - struct resource *
platform_get_resource_byname
(struct platform_device *, unsigned int, const char *); - int
platform_get_irq
(struct platform_device *, unsigned int);
- struct resource *
-
设置资源, 数据
platform_device_add_resources
// 添加resourceplatform_device_add_data
//设置pdev->dev.platform_data, 很奇怪吧,为什么device里会有个platform_data字段, 我也很奇怪.
-
相对底层的操作
platfomr_device_add、platform_device_del、platform_device_put
platform driver
数据结构
主要是driver的probe
,remove
之类的函数指针, 然后多了一个id_table
字段, 用于匹配设备.
API
platform_driver_registe
, platform_driver_unregister
//platform driver的注册、注销接口。
platform_driver_probe
// 主动执行probe动作。
platform_set_drvdata
, platform_get_drvdata
//设置或者获取driver保存在device变量中的私有数据。
early platform device/driver
内核启动时,要完成一定的初始化操作之后,才会处理device和driver的注册及probe,因此在这之前,常规的platform设备是无法使用的。但是在Linux中,有些设备需要尽早使用(如在启动过程中充当console输出的serial设备),所以platform模块提供了一种称作Early platform device/driver的机制,允许驱动开发人员,在开发驱动时,向内核注册可在内核早期启动过程中使用的driver。
TODO