2. 硬件平台基础:SoC架构、总线拓扑、外设地址空间、中断控制器、DMA引擎
在驱动架构设计中,硬件平台是软件运行的物理基础。理解SoC(片上系统)的内部结构、总线拓扑、外设地址映射、中断分发机制以及DMA传输引擎,是进行设备树描述和内存映射分层重构的前提。本章将系统梳理这些核心硬件要素,为后续的驱动框架设计奠定坚实的硬件抽象基础。
2.1 SoC架构概览
现代嵌入式SoC通常集成了处理器核心、内存控制器、总线矩阵、以及各类外设控制器。一个典型的SoC内部结构可以抽象为以下层次:
- 处理器核心(Core):执行指令,通常包含L1/L2 Cache和MMU(内存管理单元)。
- 内部总线/互联(Interconnect):连接Core、内存和外设,决定数据通路带宽和延迟。
- 内存控制器(Memory Controller):管理DDR/SRAM等主存,提供物理地址访问接口。
- 外设总线桥(Peripheral Bridge):将高速系统总线转换为低速外设总线(如APB)。
- 外设控制器(Peripheral IP):UART、I2C、SPI、GPIO、Timer等具体功能模块。
架构要点: SoC内部并非所有模块都直接挂在同一条总线上。处理器通过多层总线矩阵实现并行访问,避免单总线瓶颈。驱动开发者需要关注外设挂在哪一级总线下,这直接影响寄存器访问延迟和时钟域。
2.2 总线拓扑与地址空间
总线拓扑决定了外设的访问路径和地址映射方式。在ARM架构的SoC中,常见的总线层次包括:
| 总线类型 | 典型协议 | 位宽 | 用途 | 地址空间示例 |
|---|---|---|---|---|
| 系统总线 | AXI4 / ACE | 64/128 bit | Core ↔ 内存、Core ↔ 高速外设 | 0x8000_0000 – 0xFFFF_FFFF |
| 外设总线 | AHB5 / AHB-Lite | 32 bit | 高速外设(DMA、USB、Ethernet) | 0x5000_0000 – 0x5FFF_FFFF |
| 低速外设总线 | APB4 / APB3 | 32 bit | 低速控制外设(UART、I2C、GPIO) | 0x4000_0000 – 0x4FFF_FFFF |
驱动开发提示: 在设备树中,
reg 属性描述的就是外设的物理地址基址和地址范围。例如:reg = <0x40011000 0x1000>; 表示该外设寄存器位于物理地址 0x40011000,占用 4KB 空间。驱动通过 ioremap() 将其映射到内核虚拟地址空间。
2.3 外设地址空间与内存映射
每个外设控制器在SoC的物理地址空间中占据一段连续的地址区域,这段区域通常称为寄存器组或MMIO(Memory-Mapped I/O)区域。驱动通过读写这些物理地址来控制外设行为。
一个典型的外设寄存器映射结构如下:
/* 示例:UART外设寄存器布局 (物理基址 0x40011000) */
#define UART_BASE 0x40011000
#define UART_DR (UART_BASE + 0x000) /* 数据寄存器 (R/W) */
#define UART_RSR (UART_BASE + 0x004) /* 接收状态寄存器 (R) */
#define UART_CR (UART_BASE + 0x008) /* 控制寄存器 (R/W) */
#define UART_FR (UART_BASE + 0x00C) /* 标志寄存器 (R) */
#define UART_IBRD (UART_BASE + 0x010) /* 整数波特率除数 (R/W) */
#define UART_FBRD (UART_BASE + 0x014) /* 小数波特率除数 (R/W) */
地址对齐与访问宽度: 外设寄存器通常要求自然对齐访问(32位寄存器必须4字节对齐)。使用
readl() / writel() 等内核API可以保证正确的访问宽度和内存屏障。切勿直接使用指针解引用访问MMIO区域,否则可能导致总线错误或数据不一致。
2.4 中断控制器(GIC/INTC)
中断控制器是SoC中管理外设中断请求的核心模块。在ARM Cortex-A系列处理器中,通用中断控制器(GIC)是标准配置。GIC负责:
- 中断分发:将外设产生的中断信号路由到指定的CPU核心。
- 中断优先级管理:支持多级优先级,高优先级中断可抢占低优先级中断。
- 中断屏蔽与使能:允许软件动态开启或关闭特定中断源。
- 中断类型配置:支持电平触发(Level-sensitive)和边沿触发(Edge-triggered)。
在设备树中,中断控制器的描述通常如下:
/* GIC 设备树节点示例 */
gic: interrupt-controller@1c000000 {
compatible = "arm,cortex-a7-gic";
reg = <0x1c000000 0x1000>, /* GIC 分发器 (GICD) */
<0x1c001000 0x2000>; /* GIC CPU 接口 (GICC) */
interrupt-controller;
#interrupt-cells = <3>; /* 中断类型、中断号、触发方式 */
};
2.5 DMA引擎
DMA(直接内存访问)引擎允许外设与内存之间直接传输数据,无需CPU逐字节搬运,大幅提升系统吞吐量。DMA引擎通常包含以下核心组件:
- DMA控制器:管理多个DMA通道,每个通道可独立配置源地址、目的地址、传输宽度和传输计数。
- 通道描述符:描述一次DMA传输的完整参数,支持链表模式实现连续传输。
- 流控制:支持外设流控制(外设请求DMA传输)和内存流控制(软件触发)。
- 中断输出:传输完成或出错时向中断控制器发送中断信号。
在设备树中,DMA控制器的描述通常如下:
/* DMA控制器设备树节点示例 */
dma: dma-controller@1c020000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x1c020000 0x1000>;
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
#dma-cells = <2>; /* 通道号、请求类型 */
dma-channels = <8>; /* 支持8个DMA通道 */
dma-requests = <16>; /* 支持16个外设DMA请求 */
};
DMA与Cache一致性: 当DMA直接访问内存时,如果CPU Cache中缓存了同一块内存区域,就会产生Cache一致性问题。驱动开发中必须使用
dma_alloc_coherent() 分配一致性内存,或使用 dma_map_single() 配合适当的同步操作(如 dma_sync_single_for_cpu() / dma_sync_single_for_device())来保证数据一致性。
2.6 硬件平台知识在驱动架构中的映射
理解上述硬件基础后,驱动开发者需要将其映射到软件架构中:
| 硬件要素 | 设备树描述 | 驱动层对应 | 关键API/机制 |
|---|---|---|---|
| SoC总线拓扑 | compatible + reg |
平台驱动 (platform driver) | of_match_table, platform_get_resource |
| 外设地址空间 | reg = <base size> |
MMIO映射层 | ioremap(), devm_ioremap_resource() |
| 中断控制器 | interrupt-controller + interrupts |
中断处理层 | request_irq(), devm_request_irq() |
| DMA引擎 | dma-controller + dmas |
DMA引擎层 | dma_request_chan(), dmaengine_prep_slave_sg() |