1. Linux 平台设备驱动框架概述
在嵌入式系统开发中,我们经常需要与各种片上外设打交道,比如GPIO控制器、UART串口、I2C总线等。这些设备与PCI、USB等标准总线设备不同,它们无法通过硬件机制自动被发现和识别。这就是Linux平台设备驱动框架要解决的问题。
想象一下,你正在开发一块基于ARM的嵌入式板卡。板子上集成了多个UART接口、GPIO引脚和PWM控制器,这些设备在硬件上都是固定存在的,但操作系统并不知道它们的存在。平台设备框架就像一位尽职的管家,它维护着一份设备清单,告诉内核:"嘿,这块板子上有这些设备,它们位于这些地址,使用这些中断号..."
这个框架的核心思想是创建一个虚拟的"平台总线"(platform bus),所有静态设备都挂载在这条总线上。它主要包含两个关键部分:
- 平台设备(platform_device):描述硬件设备本身,包括设备名称、资源(内存区域、中断号等)
- 平台驱动(platform_driver):包含操作这些设备的代码,通过probe/remove等回调函数管理设备生命周期
现代Linux内核中,设备树(Device Tree)已成为描述平台设备的主流方式。设备树是一种描述硬件配置的数据结构,它替代了传统的板级文件(board file),使得同一内核镜像可以支持不同的硬件平台。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 关键数据结构解析
2.1 platform_device结构体
这个结构体是平台设备框架的核心之一,它描述了一个具体的硬件设备:
c复制struct platform_device {
const char *name; // 设备名称,用于匹配驱动
int id; // 设备实例ID,-1表示自动分配
struct device dev; // 内嵌的标准设备结构体
u32 num_resources; // 资源数量
struct resource *resource; // 资源数组
// ...其他字段
};
其中,struct resource描述了设备的硬件资源:
c复制struct resource {
resource_size_t start; // 资源起始地址
resource_size_t end; // 资源结束地址
const char *name; // 资源名称
unsigned long flags; // 资源类型标志
// ...其他字段
};
资源类型标志常用的有:
- IORESOURCE_MEM:内存区域资源
- IORESOURCE_IO:I/O端口资源
- IORESOURCE_IRQ:中断资源
2.2 platform_driver结构体
这个结构体描述了如何操作平台设备:
c复制struct platform_driver {
int (*probe)(struct platform_device *); // 设备探测回调
int (*remove)(struct platform_device *); // 设备移除回调
struct device_driver driver; // 内嵌的标准驱动结构体
const struct platform_device_id *id_table; // ID匹配表
const struct of_device_id *of_match_table; // 设备树匹配表
// ...其他回调函数
};
probe函数是驱动的核心,它在设备与驱动匹配成功后调用,负责初始化硬件、分配资源等操作。remove函数则是在设备卸载或驱动移除时调用,用于释放资源。
3. 设备与驱动的匹配机制
平台设备与驱动的匹配主要通过以下几种方式:
- 名称匹配:比较platform_device的name字段和platform_driver的driver.name字段
- **I
