Lazy loaded image
Words 0Read Time 1 min
Invalid Date
📡
案例定位
这页用两类很典型、但经常被低估的场景来补齐 DMA 专题的第三个角:
  • ADC 周期采样:强调采样时刻、触发源、周期窗口与模拟前端延迟
  • UART + circular DMA + IDLE:强调持续输入流、环形缓存、事件驱动回收与消费速度失衡

一、为什么这一类案例很重要

如果:
  • 音频 DMA 案例最适合讲 周期流节拍
  • 网卡 DMA 案例最适合讲 高吞吐 ring 并发推进
 
那 ADC / UART 这类案例最适合讲的是:
  • 持续采集不是只会“收数据”,而是要精确控制“何时采、采到哪、来不来得及处理”
  • DMA 不只是搬运通道,还是系统实时性边界的一部分

二、这类驱动最该抓的,不是带宽,而是时机

ADC 场景:采对时刻,比采得快更重要

以电流采样这类 ADC 驱动为例,真正关键的问题不是“ADC 开没开”,而是:
  • 触发源是谁
  • 采样窗口在哪里
  • PWM、死区、预驱、放大器、ADC 本身的延迟怎么算
  • 采样时刻是否已经滑到噪声区或尖峰区
 
也就是说,ADC + DMA 场景最值钱的洞察是:
DMA 负责把样本搬回来,但“什么时候采”才是决定数据质量的第一变量。

UART 场景:收得回来,不代表处理得过来

UART + circular DMA + IDLE 这类场景又是另一种问题:
  • 数据并不总是按固定 period 到达
  • 用户态 / 任务层处理速度可能跟不上
  • 缓冲区可能线性推进,也可能发生回卷
  • 半传输、全传输、IDLE 事件可能交错到来
 
所以 UART 这类持续输入流最该思考的是:
DMA 只是把数据送进环形缓冲区,系统真正的成败在于消费侧是否能及时、正确、低抖动地把它接走。

三、ADC DMA 驱动怎么看

1. 先看触发链,而不是先看 buffer

一个成熟 ADC 采样链路通常要先回答:
  • 定时器哪个事件触发 ADC
  • ADC 是规则通道还是注入通道
  • 是否双 ADC 同步采样
  • DMA 在转换完成后如何搬结果
 
如果你一开始只盯 DMA buffer,那通常会错过真正决定质量的 trigger path。

2. 采样窗口才是 ADC DMA 的灵魂

像相电流检测这类场景,采样窗口通常受这些东西共同限制:
  • PWM 占空比
  • 死区时间
  • MOS 开关延迟
  • 放大器与滤波器延迟
  • ADC 本身转换时间
 
所以这类驱动的本质不是“配个 DMA 通道”,而是:
在真实硬件延迟预算下,给采样动作找到一块还算干净的时间窗口。

3. 规则组 / 注入组 / 双 ADC 模式,不是配置项堆砌

它们背后对应的是不同的系统目标:
  • 规则组:更像常规连续采样数据面
  • 注入组:更像在关键时刻插队,优先拿到高价值样本
  • 双 ADC 同步:更像为了保证多路信号在同一时刻被看到
 
也就是说,别把这些选项当菜单。它们是在回答:
  • 你要的到底是吞吐、确定性,还是同步性?

四、UART circular DMA 驱动怎么看

1. 它本质上是“持续输入流 + 环形消费”问题

UART DMA 接收不是“来一帧处理一帧”那么简单。
 
在 circular DMA 模式下,真正要治理的是:
  • DMA 写指针持续往前推
  • CPU / 线程从旧位置开始消费
  • 如果消费慢,缓冲区会回卷并覆盖旧数据

2. IDLE / HT / TC 不是三种零散中断,而是三种观察点

  • HT:说明前半段可处理
  • TC:说明整块写满了一轮
  • IDLE:说明这一波输入暂时停了,适合把尾巴收掉
 
这三者一起用时,本质是在回答:
我现在从哪儿到哪儿这段数据,已经足够稳定,可以交给 CPU 处理?

3. old_pos -> pos 模型为什么重要

持续输入流里一个非常值钱的处理框架就是:
  • 记录上一次消费位置 old_pos
  • 当前 DMA 到达位置记为 pos
  • 如果 pos > old_pos,处理线性区间
  • 如果 pos < old_pos,说明发生回卷,要拆成两段处理
 
这其实就是 ring buffer 消费协议在 MCU 外设接收场景下的缩微版。

五、把这两个案例放在一起看,会看见什么

共同点

ADC 和 UART 这类持续采集 DMA 驱动,都有三个共性:
  1. 数据是持续到来的,不是一次性事务
  1. 软件消费速度不一定和硬件生产速度一致
  1. 真正难点不在“开 DMA”,而在“定义稳定的交接窗口”

差异点

维度
ADC 周期采样
UART circular DMA
核心矛盾
采样时刻是否准确
消费是否跟得上生产
关键边界
trigger / window / latency
write pos / old pos / overflow
主要风险
采到尖峰、相位错位、样本失真
缓冲区覆盖、帧边界错判、处理抖动
更像什么
时序精度问题
持续流消费问题

六、在主线里,这个案例对应哪些章节

这页最适合和这些章节一起看:
 
如果你把三类案例连起来看:
  • 这页的 ADC / UART 持续采集
 
你会更容易真正建立对 DMA 世界的立体感。

七、读这类源码时该追的问题

ADC 类

  • 触发源是谁?Timer 哪个事件?
  • 规则组还是注入组?为什么?
  • 采样窗口是否考虑了死区与模拟前端延迟?
  • DMA 搬回来后,结果由谁消费、何时消费?

UART 类

  • DMA 是 normal 还是 circular?为什么?
  • IDLE / HT / TC 各自承担什么观察职责?
  • 消费位置怎么维护?回卷怎么处理?
  • 若处理跟不上,系统是丢数据、阻塞还是扩大缓冲?

八、真正要带走的判断

🧠
持续采集类 DMA 驱动的核心,不是“把数据搬进内存”,而是 找到稳定的采样 / 交接窗口,并保证消费速度不会把系统拖进覆盖与抖动地狱。
这句话一旦立住,你再看 ADC、UART、采集卡,思路就不会散。
上一篇
Data Structure and Algorithm
下一篇
用面试拷问嵌入式技术栈

Comments
Loading...