在 Linux 内核设备驱动模型中,platform_device
是一个核心结构体,用于描述 平台总线(Platform Bus) 上的硬件设备。以下是其核心概述:
1. 核心作用
- 硬件抽象:将硬件设备(如 SoC 内置外设)的信息(如寄存器地址、中断号、时钟等)抽象为软件可操作的结构。
- 驱动匹配:通过
name
字段与对应的platform_driver
匹配,实现驱动与设备的自动绑定。 - 资源管理:集中管理设备所需的物理资源(如内存、中断、DMA 等)。
2. 结构体定义(简化版)
struct platform_device {
const char *name; // 设备名称(与 driver 的 name 匹配)
int id; // 设备实例编号(如多个同类设备)
struct device dev; // 通用设备模型(继承自 struct device)
u32 num_resources; // 资源数量
struct resource *resource; // 资源数组(内存、中断等)
const struct platform_device_id *id_entry; // 用于驱动匹配的 ID 表
// ... 其他字段(如电源管理、热插拔等)
};
3. 关键字段解析
-
name
设备名称(如"my-device"
),必须与对应的platform_driver
的driver.name
完全一致,否则无法匹配。 -
id
设备实例编号。若系统中有多个同名设备(如多个 UART 控制器),通过id
区分(如0
,1
)。 -
resource
指向struct resource
数组的指针,描述设备的物理资源:struct resource { resource_size_t start; // 资源起始地址(如寄存器基地址) resource_size_t end; // 资源结束地址 const char *name; // 资源名称 unsigned long flags; // 资源类型(IORESOURCE_MEM, IORESOURCE_IRQ 等) };
-
dev
继承自内核通用设备模型,提供统一的设备操作接口(如dev->of_node
用于设备树节点)。
4. 使用场景
- 静态注册:在内核初始化时通过
platform_device_register()
注册设备(如 SoC 内置设备)。 - 动态注册:通过设备树(Device Tree)或 ACPI 动态描述设备,内核自动生成
platform_device
。 - 驱动开发:驱动通过
platform_get_resource()
等 API 获取设备资源。
5. 注册流程示例
// 1. 定义资源(如内存和中断)
static struct resource my_resources[] = {
[0] = {
.start = 0x10000000,
.end = 0x10000FFF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 42,
.end = 42,
.flags = IORESOURCE_IRQ,
},
};
// 2. 定义 platform_device
static struct platform_device my_device = {
.name = "my-device",
.id = 0,
.num_resources = ARRAY_SIZE(my_resources),
.resource = my_resources,
};
// 3. 注册设备
int __init my_init(void) {
return platform_device_register(&my_device);
}
6. 注意事项
- 资源管理:需确保资源(如内存地址)未被其他设备占用。
- 驱动匹配:设备名称必须与驱动名称严格一致。
- 生命周期:设备注册后需在模块卸载时调用
platform_device_unregister()
释放资源。
通过 platform_device
,Linux 内核实现了硬件设备的统一抽象,简化了驱动开发流程。