1. DMA基础概念:DMA工作原理、DMA与CPU数据搬运对比、DMA在显示子系统中的作用
1.1 DMA工作原理
直接存储器访问(Direct Memory Access,DMA)是一种允许硬件子系统直接读写系统内存而无需CPU干预的数据传输技术。在嵌入式显示系统中,DMA是连接帧缓冲(Frame Buffer)与显示控制器(Display Controller)之间的关键数据通道。
核心思想:DMA控制器接管总线控制权,在源地址与目的地址之间建立一条硬件直连的数据通路,通过硬件状态机自动完成数据搬运,仅在传输完成或出错时通知CPU。
DMA传输的基本流程
- CPU配置DMA控制器:设置源地址(如帧缓冲地址)、目的地址(如显示控制器FIFO)、传输长度(字节/字/块数)、触发方式(软件触发或硬件外设请求)。
- DMA请求与仲裁:外设(如LCD控制器)发出DMA请求信号,DMA控制器向总线仲裁器申请总线控制权。
- 总线控制权移交:CPU释放总线,DMA控制器获得总线主控权,开始逐字/逐块搬运数据。
- 数据传输执行:DMA控制器按配置的传输模式(单次/突发/循环)从源读取数据并写入目的地址,地址指针自动递增或递减。
- 传输完成中断:计数寄存器归零后,DMA控制器释放总线,向CPU发送完成中断或触发下一个DMA链。
关键指标:DMA传输延迟 = 配置延迟 + 仲裁延迟 + (数据量 × 总线时钟周期 / 总线位宽) + 中断延迟。在显示场景中,仲裁延迟和总线抢占是影响帧同步的主要因素。
1.2 DMA与CPU数据搬运对比
在显示数据搬运场景中,CPU搬运(PIO模式)与DMA搬运在性能、资源占用和实时性方面存在显著差异。以下从多个维度进行对比:
| 对比维度 | CPU数据搬运(PIO) | DMA数据搬运 |
|---|---|---|
| 数据路径 | 内存 → CPU寄存器 → 外设 | 内存 → DMA控制器 → 外设(直通) |
| CPU占用率 | 100%(搬运期间无法执行其他任务) | 仅配置和中断阶段占用(通常 < 5%) |
| 传输速率 | 受限于CPU指令执行速度(通常 10~50 MB/s) | 接近总线带宽上限(通常 100~800 MB/s) |
| 实时性 | 受中断嵌套和任务调度影响,抖动大 | 硬件状态机执行,延迟确定性强 |
| 功耗 | CPU高频运行,功耗高 | DMA控制器低频率运行,功耗低 |
| 适用场景 | 小数据量(< 64字节)、配置寄存器 | 大数据量(≥ 1 KB)、周期性显示刷新 |
常见误区:并非所有场景都适合DMA。对于小于DMA配置开销的数据量(通常 < 64字节),CPU直接搬运反而更快。在显示驱动中,单像素配置、小尺寸光标更新等场景应使用CPU搬运。
性能对比示例:1080p@60fps 显示刷新
- 数据量:1920 × 1080 × 4字节(RGBA)= 8,294,400 字节/帧
- CPU搬运耗时:8.29 MB / 30 MB/s ≈ 276 ms(远超16.7ms帧周期,不可行)
- DMA搬运耗时:8.29 MB / 400 MB/s ≈ 20.7 ms(接近帧周期,需优化)
- 优化后DMA(双缓冲+突发模式):8.29 MB / 600 MB/s ≈ 13.8 ms(满足60fps要求)
1.3 DMA在显示子系统中的作用
在现代嵌入式显示子系统中,DMA扮演着"数据搬运工"的核心角色。显示控制器需要以固定帧率(如60fps)从帧缓冲中读取像素数据,而DMA正是实现这一连续、高速数据流的关键硬件单元。
显示子系统中的DMA应用场景
| 应用场景 | 数据流向 | DMA模式 | 关键要求 |
|---|---|---|---|
| 主显示层刷新 | 帧缓冲 → 显示控制器 | 循环/自动请求模式 | 低延迟、无撕裂、帧同步 |
| 硬件光标更新 | 光标缓冲 → 显示叠加层 | 单次传输模式 | 小数据量、快速响应 |
| 2D图形加速 | 显存 → 显存(Blit操作) | 内存到内存模式 | 高带宽、地址偏移灵活 |
| 显示旋转/缩放 | 帧缓冲 → 硬件旋转引擎 | 链式描述符模式 | 非连续地址、分块传输 |
| 多图层合成 | 多个图层缓冲 → 合成器 | 多通道DMA | 通道同步、优先级管理 |
显示DMA的关键技术指标
- 带宽要求:分辨率 × 色深 × 帧率。例如 1920×1080×4B×60fps ≈ 498 MB/s。
- 延迟抖动:必须小于一个像素时钟周期(通常 < 10ns),否则导致像素错位。
- 地址连续性:帧缓冲在物理内存中可能不连续,DMA必须支持分散-聚集(Scatter-Gather)或描述符链。
- 帧同步机制:DMA传输必须与垂直消隐(VBlank)信号同步,避免撕裂(Tearing)效应。
工程实践:在Linux DRM/KMS驱动中,DMA传输通常通过dmaengine API或自定义DMA驱动实现。显示控制器通过硬件触发信号(如DMA请求线)启动传输,驱动只需在初始化时配置好描述符链,后续传输完全由硬件自动完成。
显示DMA的缓冲调度策略
为了在有限的带宽和内存资源下实现流畅显示,DMA驱动需要实现高效的缓冲调度:
- 双缓冲(Double Buffering):一个缓冲区用于DMA传输(前台),另一个用于CPU/GPU渲染(后台),通过VBlank信号交换。
- 环形缓冲(Ring Buffer):DMA描述符链形成环形,传输完成后自动跳转到下一个描述符,实现连续帧刷新。
- 优先级调度:光标层DMA通道具有最高优先级,确保鼠标移动无延迟;视频层可适当降级。
- 带宽预算:根据显示分辨率和帧率计算各通道的带宽需求,通过DMA仲裁器分配总线时间片。
总结:DMA是显示子系统的"数据高速公路",它将CPU从繁重的数据搬运任务中解放出来,使CPU能够专注于图形渲染、事件处理和上层应用。理解DMA的工作原理、性能特征和调度策略,是开发高效显示驱动的基石。