platform驱动实战:设备树匹配与资源获取全流程 - 第1节
1.1 Platform 驱动概述
在 Linux 内核驱动框架中,Platform 驱动(平台驱动) 是一种虚拟总线驱动模型,用于管理那些不挂载在 PCI、USB、I2C、SPI 等物理总线上的设备。这些设备通常直接集成在 SoC 内部,或者通过内存映射 I/O 与 CPU 连接,例如:GPIO 控制器、时钟控制器、中断控制器、DMA 控制器、以太网 MAC 等。
核心概念:Platform 驱动模型将“设备”与“驱动”分离,通过 platform_driver 和 platform_device 两个核心数据结构,实现驱动与设备的动态匹配与绑定。
1.1.1 Platform 总线模型架构
Platform 驱动模型遵循 Linux 设备模型中的“总线-设备-驱动”三层架构。下图展示了 Platform 总线在系统中的位置与交互关系:
1.1.2 Platform 驱动的典型应用场景
| 场景类别 | 典型设备举例 | 说明 |
|---|---|---|
| SoC 内部外设 | UART、SPI、I2C 控制器、定时器 | 集成在芯片内部,无物理总线枚举 |
| 内存映射设备 | GPIO 控制器、中断控制器、DMA 引擎 | 通过 MMIO 访问寄存器,地址在设备树中描述 |
| 非枚举型总线设备 | 板级 I2C/SPI 从设备(部分) | 无法自动枚举,需设备树或板级代码描述 |
| 虚拟/伪设备 | GPIO 按键、LED、看门狗 | 通常由设备树节点触发 platform_device 创建 |
关键认知:Platform 驱动并非只用于“平台设备”,它已成为 Linux 内核中管理 非可枚举设备 的标准抽象层。设备树(Device Tree)的引入,使得 platform_device 的创建和资源描述完全由设备树节点自动生成,驱动开发者只需关注 probe() 中的资源获取与硬件初始化。
1.2 设备树在驱动中的作用
设备树(Device Tree) 是一种描述硬件拓扑和资源的数据结构,以 .dts 源文件形式存在,编译为 .dtb 二进制后由 bootloader 传递给内核。设备树的核心作用在于:将硬件配置信息从内核代码中解耦,使得同一份内核镜像可以支持不同的硬件平台。
1.2.1 设备树如何影响 Platform 驱动
设备树与 Platform 驱动的交互贯穿整个驱动生命周期,从设备注册到资源获取,再到匹配与 probe:
1.2.2 设备树提供的核心资源类型
| 资源类型 | 设备树属性 | 驱动获取 API | 说明 |
|---|---|---|---|
| 寄存器地址/范围 | reg |
platform_get_resource() / of_iomap() |
描述 MMIO 基地址和大小 |
| 中断 | interrupts |
platform_get_irq() |
支持 SPI、PPI、边沿/电平触发 |
| 时钟 | clocks |
devm_clk_get() |
通过 phandle 引用时钟控制器 |
| DMA | dmas |
dma_request_chan() |
描述 DMA 通道与请求线 |
| GPIO | gpios |
devm_gpiod_get() |
通过 GPIO 描述符访问 |
| 自定义属性 | 任意自定义属性名 | of_property_read_*() |
读取整型、字符串、数组等 |
常见误区:设备树不是驱动配置文件的替代品。它描述的是 硬件拓扑 和 不可变资源,而非运行时参数。驱动运行时的可调参数应通过 sysfs、debugfs 或模块参数传递。
1.3 本课程学习目标与前置知识
1.3.1 学习目标
通过本课程的学习,你将能够:
- 理解 Platform 驱动模型:掌握 platform_driver、platform_device 的核心数据结构与生命周期。
- 掌握设备树语法与编译:能够编写 .dts 文件,使用 dtc 编译为 .dtb,并理解设备树在驱动匹配中的作用。
- 实现设备树匹配:在驱动中正确编写 of_match_table,实现 compatible 属性的精确匹配。
- 获取设备树资源:熟练使用 of_iomap()、platform_get_resource()、of_property_read_*() 等 API 获取寄存器、中断、时钟、GPIO 等资源。
- 编写完整的 Platform 驱动:从零开始实现一个基于设备树的 Platform 驱动,包含 probe()、remove()、PM 操作等完整流程。
- 调试与验证:通过 devicetree、sysfs、debugfs 等接口验证驱动与设备树的匹配状态。
1.3.2 前置知识要求
| 知识领域 | 具体要求 | 推荐掌握程度 |
|---|---|---|
| C 语言编程 | 指针、结构体、回调函数、链表操作 | 熟练 |
| Linux 内核基础 | 内核模块编写、编译、加载/卸载;printk 调试 |
入门 |
| Linux 设备模型 | kobject、sysfs、总线/设备/驱动模型基本概念 | 了解 |
| 嵌入式系统基础 | ARM/ RISC-V 体系结构、MMIO、中断控制器基本概念 | 了解 |
| 设备树基础 | .dts 文件结构、节点、属性、phandle 基本语法 | 了解(本课程会系统讲解) |
学习建议:如果你对设备树语法尚不熟悉,不必担心。本课程第 2 章将系统讲解设备树语法与编译流程,第 3 章开始进入 Platform 驱动实战。建议在学习过程中准备一块支持设备树的开发板(如 QEMU virt 平台或 Raspberry Pi),边学边练效果最佳。
1.3.3 课程路线图
课程承诺:本课程不空谈理论,每一章都围绕“可运行的 Platform 驱动”展开。你将在第 3 章开始编写第一个基于设备树的驱动,并在第 6 章完成一个包含中断、时钟、DMA 资源获取的完整驱动实例。所有代码均在 QEMU virt 平台验证通过。