B站相应的视屏教程:
📌 内核:博文+视频 - 总线驱动模型实战全解析 —— 以 PCA9450 PMIC 为例
敬请关注,记得标为原始粉丝。
在 Linux 内核驱动模型中,设备与驱动的组织方式不是随意堆砌,而是基于清晰的分类逻辑进行架构设计的。最核心的架构基础是“设备模型”(Device Model),而在此模型之上,各类驱动通过“平台驱动模型”与“总线驱动模型”协同运作,实现灵活、高度可扩展的硬件抽象层。
本篇将作为《Day 8》的上篇内容,系统性讲解平台驱动与总线驱动的理论框架、分类方式、匹配机制及其在设备树支持下的应用方法,帮助你全面理解驱动模型的本质与结构基础。
一、Linux 设备模型简介:统一的抽象基础
从 Linux v2.6 内核开始,引入了统一的“设备模型”(Device Model),核心目标是:以统一的方式管理设备与驱动的关系,实现热插拔、自动挂载、sysfs 信息导出、电源管理等功能。
设备模型的三个核心组成:
struct device
:表示一个硬件设备;struct device_driver
:表示该设备的驱动;struct bus_type
:用于连接设备与驱动,形成“设备-驱动总线”。
设备模型本身并不决定设备的分类方式,而是提供统一接口,不同的子系统(如平台设备、I2C、SPI、PCI)根据硬件体系构建在它之上。
二、驱动模型的分类逻辑:平台与总线驱动
1. 平台驱动模型(Platform Driver Model)
平台驱动模型(Platform Driver Model)主要用于描述无法通过标准枚举机制自动发现的设备。如 SoC 内部的控制器、片上外设(LCD 控制器、PWM、I2C 控制器等)。
核心结构:
struct platform_device
struct platform_driver
platform_bus_type
匹配机制:
- 驱动中注册
platform_driver
- DTS 中节点生成
platform_device
- 匹配通过
of_match_table
或driver.name
对比设备节点compatible
或name
属性
适用场景:
- 片上外设(SoC peripherals)
- 固定拓扑结构的设备(不支持热插拔)
2. 总线驱动模型(Bus Driver Model)
总线驱动模型 是针对可被标准总线发现和枚举的设备类型构建的驱动框架,如:
i2c_driver
:用于挂在 I2C 总线上的设备spi_driver
:用于 SPI 总线设备pci_driver
:PCI/PCIe 设备usb_driver
:USB 外设
这些总线本身都是 struct bus_type
的实例。每种总线都维护了一个自己的设备与驱动结构,提供标准化的 probe 入口与资源获取方式。
匹配机制:
- 子设备通过
of_device_id
(或 ACPI)与i2c_driver
中的匹配表比对 - 驱动通过总线核心进行绑定调用
probe
适用场景:
- 支持自动枚举或扫描的外部总线(可热插拔或可动态挂载设备)
- 芯片级外设(如 I2C、SPI 的从设备)
三、平台驱动与总线驱动的结构对比
特性 | 平台驱动(platform_driver) | 总线驱动(i2c_driver 等) |
---|---|---|
设备定义方式 | platform_device | i2c_client 等设备结构 |
注册方式 | platform_driver_register() | i2c_add_driver() |
匹配依据 | compatible / name | compatible + 地址(reg) |
子系统入口 | platform_bus_type | i2c_bus_type 等 |
使用场景 | SoC 内部固定设备 | 可枚举的标准外设 |
资源获取方式 | platform_get_resource() | client->irq 、regmap 等 |
DTS 节点结构 | controller@base + 子节点 | controller + reg-based 子节点 |
四、设备模型下的总线分类汇总
Linux 中存在众多 bus_type 类型,每一种都对应一套设备与驱动注册框架。常见示例如下:
/sys/bus/
├── i2c ← 对应 i2c_driver
├── spi ← 对应 spi_driver
├── platform ← 对应 platform_driver
├── pci ← PCI 总线
├── usb ← USB 设备
├── mdio_bus ← PHY 设备
├── amba ← ARM SoC 特定外设
每个目录底下都包括:
/drivers/
:驱动注册后的信息(.name)/devices/
:设备创建后的路径(device node)
总线是连接设备与驱动的桥梁,它可能是虚拟的(如 platform 总线),也可能是物理的(如 i2c 总线)。平台总线更多是“逻辑建模”的结果,而总线驱动更多依托于硬件结构。
五、匹配机制与设备树支持对比
驱动模型类型 | 匹配字段 | DTS 中体现 | 设备注册方式 |
---|---|---|---|
platform | compatible/name | controller@base(顶层节点) | of_platform_populate() |
i2c/spi/pci | compatible + reg | i2c1 → pmic@25 | i2c_new_device() / 自动扫描 |
usb | USB ID / device | 通过 USB 描述符发现 | 热插拔自动创建 |
特别注意:虽然 platform_driver 是逻辑抽象,但有时它也用于创建“虚拟总线”,如 RPMsg/I2C 桥接场景中,虚拟 I2C 控制器仍通过 platform_driver 注册。
六、总结
我们可以这样更准确地描述 Linux 驱动的分类:
- 平台驱动模型:用于 SoC 中的控制器类设备(controller)
- 总线驱动模型:用于挂载在控制器之上的外设(device)
这不是“平台设备 vs 非平台设备”的二元划分,而是“控制器层 vs 外设层”的驱动模型设计逻辑。
✅ 下一篇预告
在《Day 8:下篇》中,我们将以 NXP i.MX8MP 的 I2C1 接口挂载 PCA9450 PMIC 为实例,系统讲解设备树的结构组织、设备与驱动的匹配机制、资源获取、probe 函数流程,并从驱动源码中深度解析总线驱动模型的实战逻辑。敬请期待!