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内部并非所有模块都直接挂在同一条总线上。处理器通过多层总线矩阵实现并行访问,避免单总线瓶颈。驱动开发者需要关注外设挂在哪一级总线下,这直接影响寄存器访问延迟和时钟域。
SoC内部架构分层示意图 SoC 内部架构分层示意图 处理器核心 (CPU Core) — Cortex-A/M/R 系统总线/互联 (AXI/AHB/NoC) 内存控制器 (DDR/SRAM) 外设总线桥 (AHB-APB Bridge) 内存地址空间 (0x8000_0000 ...) 外设寄存器空间 (0x4000_0000 ...) 说明:不同SoC的层次划分可能略有差异,但核心逻辑均为“Core → 总线 → 内存/外设桥 → 外设”

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>;      /* 中断类型、中断号、触发方式 */
};
GIC中断分发流程 GIC 中断分发流程 外设中断源 外设中断源 外设中断源 GIC 分发器 中断使能/屏蔽 优先级路由 类型配置 中断号映射 GIC CPU 接口 IRQ/FIQ 信号 优先级掩码 应答与结束 CPU 说明:GIC分发器收集所有外设中断,根据优先级和路由配置,将中断请求发送到指定CPU核心的GIC CPU接口

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())来保证数据一致性。
DMA传输流程 DMA 传输流程 外设 (UART/SPI) DMA请求 DMA 控制器 通道配置 / 描述符 源地址 → 目的地址 读数据 内存 (DDR) 写数据 外设 FIFO 传输完成中断 说明:DMA控制器在外设请求下,直接从内存读取数据写入外设FIFO,或从外设FIFO读取数据写入内存,传输完成后触发中断通知CPU

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()