1. Platform总线驱动开发概述
在嵌入式Linux系统开发中,Platform总线是最基础也是最常用的虚拟总线机制。作为一名长期从事RK3588平台开发的工程师,我经常需要为各种外设编写Platform驱动。与传统的PCI、USB等物理总线不同,Platform总线是Linux内核专门为片上系统(SoC)外设设计的虚拟总线架构。
为什么我们需要Platform总线?想象一下,当你在开发板上连接一个I2C设备时,内核可以通过扫描物理I2C总线来发现设备。但对于集成在SoC内部的外设(比如GPIO控制器、SPI控制器等),它们没有物理连接线,内核无法通过常规方式发现这些设备。Platform总线就是为解决这个问题而生的虚拟通道。
Platform驱动开发的核心在于理解"设备-总线-驱动"模型。在这个模型中:
- 设备信息通过设备树(DTS)描述
- 总线负责匹配设备和驱动
- 驱动实现具体的设备操作
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Platform总线工作原理深度解析
2.1 设备与驱动的匹配机制
Platform总线的匹配过程就像一场精心安排的相亲会。设备树中的每个设备都带着自己的"相亲简历"(compatible属性),而驱动则声明自己能够匹配的设备类型。内核的媒人(总线核心)负责将合适的设备与驱动配对。
匹配过程的具体流程如下:
- 内核启动时解析设备树,为每个设备创建platform_device结构体
- 驱动注册时提供platform_driver结构体
- 总线核心比较device和driver的compatible字符串
- 匹配成功后调用驱动的probe函数
关键数据结构关系:
c复制struct platform_device {
const char *name;
int id;
struct device dev;
// ...
};
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
struct device_driver driver;
// ...
};
2.2 设备树的关键作用
设备树是现代Linux驱动开发的基石。在RK3588 Android12平台上,所有Platform设备都必须通过设备树声明。一个典型的设备节点配置如下:
dts复制/ {
my_device: my-device@ff000000 {
compatible = "vendor,my-device";
reg = <0xff000000 0x1000>;
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru CLK_MYDEVICE>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&mydev_default>;
pinctrl-1 = <&mydev_sleep>;
vendor,param = <0x1234>;
};
};
每个属性的含义:
compatible: 驱动匹配的关键标识reg: 设备寄存器地址范围interrupts: 中断号配置clocks: 时钟资源pinctrl-*: 引脚复用配置
3. Platform驱动开发实战
3.1 最小驱动框架实现
让我们从最简单的Platform驱动框架开始。以下代码展示了一个完整的驱动
