直接回答:DMA 让外设绕过 CPU 直接读写内存,编译器与 CPU 视角的借用规则全被架空:缓冲区被 DMA 写时 CPU 读它(撕裂数据)、DMA 传输中缓冲区被释放或移动(悬垂)、cache 与内存不一致(写了但没回写,DMA 拿到旧数据;或 DMA 写了但 CPU 读到 cache 旧值)。三类问题分别对应生命周期、移动与 cache 一致性。

展开解析:类型系统解法分三层。所有权转移:启动 DMA 时把缓冲区的所有权(或 &'static mut)交给传输对象,传输完成前编译器禁止访问——embassy 与多数 HAL 的 Transfer 类型持有 buffer,await/complete 后归还;这同时解决了“传输中修改”与“提前释放”。禁止移动的保证:要么要求 'static 缓冲区(编译期钉死地址),要么用 Pin 包装——栈上数组传给 DMA 然后函数返回是经典事故。cache 一致性:带 D-cache 的 MCU(如 Cortex-M7)必须在 DMA 读前 clean cache(回写)、DMA 写后 invalidate;部分 HAL 用类型区分 DMA 区段(链接脚本划到 non-cacheable SRAM),从根上免维护。对齐与长度也要静态约束:很多 DMA 要求 4/8 字节对齐与特定长度倍数,新类型包装(如 AlignedBuffer)把校验放构造期。遗留风险:中断里偷看 DMA 缓冲(HAL 管不到手写 unsafe)、多核 MCU 的另一核访问——要靠文档约定加评审。总原则:让“传输中不可访问”成为类型错误而非纪律要求。

追问方向:scatter-gather DMA 如何用类型建模?双缓冲(ping-pong)模式的借用怎么设计?

(约 490 字)