中断与NVIC问答合集

📖 精选 📅 2026-09-04
#来源/立芯星球 #类型/问答合集 #技术/中断 #技术/NVIC #技术/实时性 #技术/RTOS

中断与NVIC问答合集

由本目录 15 篇中断主题问答的答案精华按知识点重组而成,原帖全部保留,每节末尾标注出处。

1. 什么是中断延时:上半部与下半部

中断延时的定义:中断请求发生到进入 ISR 之前的那段时间。处理中断时的经典分法:

  • 上半部:ISR 内必须立刻做的部分,最重要的是清除对应的中断标志位;
  • 下半部:标志位改变后与中断相关的事务处理,这些事务合理安排在 ISR 之外执行,可以有效减少中断服务时间,从而降低系统的中断延时。

中断延时是中断请求到进入ISR之前的时间,上半部是ISR内必须要做的部分(Jack)

注:什么是中断延时: 中断延时是 与上篇为同文异发(正文逐字相同,仅多一个 #知识总结 标签),2025-03-13 与 03-19 先后发布,属于近似重复,保留待人工合并。

2. 如何减少中断延迟处理时间

四条实操路径:

  1. 提高中断优先级;
  2. 减少更高优先级服务函数的执行时间——例如通过全局标志位实现中断服务函数"快进快出";
  3. 减少临界区;
  4. 把中断服务函数分散加载到 RAM 区域执行,减少流水线取指令时间。

(中断资源与实时性上限的系统级讨论见 关于中断优化: 中断在系统是一

老师,中断的延迟处理时间要怎么(Jack)

3. 系统级视角:单个中断快慢不重要,中断偏移才重要

单一中断耗时久不久不重要,重要的是所有中断延时加起来是否构成整个系统的中断偏移。如果产生了偏移,说明系统的中断资源已经溢出,在中断任务上已经不具备实时性。

单一中断久不久不重要,重要的是所有中断延时加起来是不是构成了整个系统的中断偏移(Jack)

4. NVIC 仲裁规则:同优先级同时触发怎么办

两个定时器中断优先级设置相同时同时触发:IRQ 号小的先执行。NVIC 手册原文:If multiple interrupts are pending for the same priority level, the interrupt with the lowest IRQ number is processed first.

老师,如果这两个定时器的中断优先级设置的一样,如果同时触发是定时器6会先执行(Jack)

5. 如何实验观察中断嵌套

在两个中断函数中分别设断点做对照实验:

void EXTI0_IRQHandler(void)
{
    EXTI->PR = EXTI_PR_PR0;
    NVIC_SetPendingIRQ(USART1_IRQn);  // 人为触发 USART1
    while (1);  // 看是否会被 USART1 抢占
}
void USART1_IRQHandler(void)
{
    // 设置断点在这里
}

若能执行到 USART1_IRQHandler,说明嵌套发生了(优先级更高);若卡死在 EXTI0 的 while(1),说明没有嵌套(优先级不够或被屏蔽)。

怎么看中断有没有嵌套? 观察(Jack)

6. 中断屏蔽的语义:悬起但不响应

使用中断屏蔽寄存器组屏蔽掉的中断:可以悬起,但不能响应——屏蔽解除后仍会补上处理,事件不会丢。

使用中断屏蔽寄存器组屏蔽的中断是可以悬起不能响应,还是连悬起都没有(Jack)

7. 中断与 RTOS:高优先级任务被唤醒后怎么办

  • 在 ISR 中调用队列发送等 OS API 时,若有高优先级任务因此被唤醒,并不会立即切换:只置位 PendSV 悬起,等退出所有中断后再响应 PendSV 完成任务切换。这类似于"中断下半部"的优化思路,因此不会如直觉般破坏实时性。
  • 若不主动让出 CPU,ISR 结束后会继续执行被打断的低优先级任务,直到其用完时间片或主动阻塞,高优先级任务的实时性就没了保障;标准做法正是依赖上述 PendSV 机制,让 ISR 结束后立刻切换到被唤醒的高优先级任务。

在0-4的中断里面调用os的api函数,也算是执行了这个中断的ISR(Jack)
在中断服务程序中向队列中发送数据时,可能会有更高优先级的任务会因此被唤醒,这里的更高(Jack)

软件中断在业务开发中用得不多,但线程间通信(IPC)内部到处在用:FreeRTOS 消息队列发送完成后,若发现有更高优先级任务因该消息被唤醒,就会触发 PendSV 软件中断执行上下文切换,保证及时响应。

老师,请问在开发中,软件中断是(Jack)

8. ISR 编写守则:不改共享全局变量

中断里面不建议修改被(中断与线程)共享的全局变量;中断内只置位一个标志位,或发信号量,让外面的线程有秩序地去修改。

中断里面不建议修改被共享的全局变量,中断里面可以置位一个标志位,或者发信号量(Jack)

9. HardFault 定位:LR = 0xFFFFFFF1 的含义

在 HardFault 中看到 LR 为 0xFFFFFFF1,说明进入 HardFault 之前已经处于中断之中——即产生错误时的调用路径是:线程 → 中断 → HardFault。这为栈回溯定位提供了关键线索。

当你在错误中断(Hardfault)中看到LR是0xFFFFFFF1时(Jack)

10. 重定位与中断向量表

重定位的两个用处中与中断直接相关的一条:进入用户空间前把中断向量表搬到 RAM,可减少中断延时,在 ADC 这类高速应用中能提升整体性能(另一条是进入用户程序前做前置校验与配置,例如跳过部分区域初始化加快启动)。

重定位的用处: 1.进入用户空(Jack)

11. 更多相关问答(答案在原帖截图中)

来源笔记