中断使处理器能够在外设事件发生时转去处理相应工作,例如按键触发、接收数据或定时器到期。外设发出请求、中断控制器选择请求、处理器进入异常以及软件执行处理程序,是几个相关但不同的步骤。
一次外部中断的基本过程
跳转到“一次外部中断的基本过程”flowchart TD A[外设产生事件并记录状态] --> B[向中断控制器提出请求] B --> C{使能、屏蔽与优先级允许响应?} C -->|暂不允许| D[保持或记录待处理状态] D --> C C -->|允许| E[处理器按架构规则保存必要现场并进入异常] E --> F[根据向量或入口机制执行处理程序] F --> G[处理事件并按外设规则确认或清除请求] G --> H[异常返回并恢复执行上下文]这是概念流程,具体的边沿、电平、挂起与确认规则由设备和中断控制器决定。并非所有控制器都以完全相同的方式保留被屏蔽的请求。
| 步骤 | 硬件或软件的职责 | 容易混淆的地方 |
|---|---|---|
| IRQ 请求 | 外设或其他中断源报告事件 | 状态位已经置位,不代表处理器已经进入处理程序 |
| 请求选择 | 中断控制器考虑使能、挂起、屏蔽和优先级等条件 | 控制器的选择不是执行一条普通 C 函数调用 |
| 异常入口 | 处理器按架构保存所需状态并转移执行 | 自动保存哪些寄存器、是否切栈,各架构不同 |
| 中断服务例程 ISR | 读取状态、搬运必要数据、确认事件或安排后续工作 | 只清控制器挂起位可能无法消除仍有效的外设请求 |
| 异常返回 | 恢复状态并继续合适的执行上下文 | 返回对象可能是线程或被抢占的中断;有调度器时也可能切换任务 |
向量表不等于处理器内部的一张函数表
跳转到“向量表不等于处理器内部的一张函数表”“中断向量表”通常是内存中的架构数据结构,处理器通过约定的位置或基址寄存器访问它。它的内容和入口形式也不统一。
例如 Cortex-M 的向量表包含处理程序入口地址,首项还保存初始主栈指针;x86 使用中断描述符表等机制。不能统一描述成“控制器在 CPU 内部查到一个函数地址,然后调用它”。具体实现要结合处理器架构、启动代码和操作系统。
外设 IRQ 通常与正在执行的指令异步发生;由指令引起的故障、陷阱和系统调用等异常又有不同的触发与返回语义。资料中的“中断”有时是广义称呼,阅读时应先确认其范围。
写处理程序时先回答四件事
跳转到“写处理程序时先回答四件事”- 谁产生请求,怎样确认? 查外设状态位、清除顺序和中断控制器规则;有的状态需要写 1 清除,有的需要特定读写序列。
- 哪些操作允许在此上下文执行? 保持必要工作有界,避免等待只能由被抢占代码完成的事件;操作系统通常提供专门的中断接口。
- 怎样与主循环或任务交换数据? 选择队列、环形缓冲区、原子操作或受保护的共享状态。
volatile本身不提供互斥或完整同步。 - 处理期间还会发生什么? 考虑更高优先级抢占、事件再次到来、缓冲区溢出和响应时间;不要只测试单次触发。
以 Cortex-M 为例,屏蔽某中断与清除其挂起状态是不同操作,CMSIS 核心寄存器说明明确指出:禁止响应时,请求仍可能进入挂起状态。
相关专题
跳转到“相关专题”- 处理器核心寄存器:区分通用寄存器、状态寄存器与屏蔽寄存器。
- STM32H743 中断预算与测量:在具体设备上分析频率、执行时间和负载。
- Linux 中断驱动:操作系统中的中断处理接口。