中断与DMA使用要点与常见坑

📅 2026-09-04
#来源/立芯星球 #类型/专题提炼 #技术/中断 #技术/DMA #技术/实时性

中断与DMA使用要点与常见坑

本专题合并整理自「立芯嵌入式」星球中关于 NVIC 中断机制、中断优化与 DMA 使用的 20 余篇问答,提炼出可直接落地的原则与典型坑。

一、中断延时与上半部/下半部模型

中断延时指从中断请求产生到进入 ISR 之前的时间。ISR 内部又分两半:上半部是必须立刻做的事,核心是清除对应标志位;下半部是与中断相关但耗时的处理,应安排在 ISR 之外执行,以缩短中断服务时间、降低系统中断延时(什么是中断延时: 中断延时是,Jack;更早的同主题总结见 中断延时是中断请求到进入ISR之前的时间,上半部是ISR内必须要做的部分,Jack)。

中断在系统里是紧俏资源:ISR 处理时间过长会影响实时性,甚至丢中断。优化思路分两层(关于中断优化: 中断在系统是一,Jack):

  • 上半部:精简逻辑、减少不必要的局部变量(避免压栈出栈开销);数据通知优先用全局变量而非 IPC,中断线程化以降低消耗。
  • 下半部:把耗时处理剥离到线程中;配合显式/隐式双 buffer、原地/异地解包等手段(详见 数据缓冲与解包: 以串口为例)。

同时要认识到系统实时性有上限:负载超过芯片能力时丢中断是必然的,此时用看门狗、GPIO+示波器测量定位瓶颈,软件优化到极限后只剩升级硬件一条路(同上,Jack)。判断"中断资源是否溢出"不是看单一中断长不长,而是看所有中断延时叠加构成的系统中断偏移——产生偏移即说明中断任务已不具实时性(单一中断久不久不重要,重要的是所有中断延时加起来是不是构成了整个系统的中断偏移,Jack)。

二、NVIC 行为的关键细节

三、RTOS 环境下中断与任务的衔接

ISR 中向队列发送数据可能唤醒更高优先级任务:若不主动处理,中断退出后会继续执行被打断的低优先级任务,直到其时间片用尽或阻塞,高优先级任务的实时性就没了;正确做法是让调度器在中断退出后立刻切换到高优先级任务(在中断服务程序中向队列中发送数据时,可能会有更高优先级的任务会因此被唤醒,这里的更高,Jack)。

底层机制是:中断中调用 FreeRTOS 队列 API 时,即使唤醒了高优先级任务,也只置位 PendSV 悬起,等退出所有中断后才响应 PendSV 完成切换——这本身就是一种中断下半部优化(在0-4的中断里面调用os的api函数,也算是执行了这个中断的ISR,Jack)。而消息队列发送后检查并触发 PendSV 做上下文切换,正是软件中断在产品代码中最典型的应用(老师,请问在开发中,软件中断是,Jack)。

四、DMA 使用要点

五、真实复盘:UART + DMA 接收错位(RH850)

一个典型案例:DMA 启动接收后数据整体后移,表面像 DMA 搬错,根因却是只发送不接收阶段 Rx 引脚仍处于 UART 复用输入,总线波形被误解析成数据残留在接收寄存器里,下一次 enable DMA 时先把脏数据搬进 buffer。解法是按接收状态动态切换 Rx 引脚模式:不接收时配成普通 DIO 输入断开外设输入链路,接收时再切回复用输入(最近在 RH850 平台调试 时,遇到一个比较典型的问题,zzz)。

核心经验:DMA 只是被动搬运工具,不判断数据有效性。排查"外设+DMA"问题不能只盯 DMA 配置,还要检查外设输入源是否干净、request 是否挂起、enable 前有无残留数据。

六、不定长接收的两条路线

  1. 空闲中断 + 指针偏移:不要靠 DMA 定长中断,每次空闲中断产生就解析数据,且不要去干预 DMA 本身,否则容易挂(这里不能靠dma中断去定长度进,Jack)。
  2. 无空闲中断的芯片:查询 DMA 剩余传输长度并结合时间来断帧,很多没有串口空闲中断的单片机都这么做,顺带节省中断资源(串口dma接收,不用idle的话,可以自己查询dma剩余传输长度结合时间来断帧,Jack;图解见 单片机的串口本身没有空闲中断怎,Jack)。

来源笔记