第1章:中断管理——实时性的第一道防线
做麻醉机嵌入式开发这些年,我最大的体会就是:中断管理做不好,实时性就是一句空话。你想想看,病人正在手术中,呼吸参数突然报警,CPU却还在处理一个无关紧要的任务——这种场景光是想想就后背发凉。
今天咱们就聊聊中断管理的三个核心问题:中断延迟的组成、中断嵌套与可重入性、以及ISR的设计原则。这些都是我踩过坑之后才真正理解的东西。
1.1 中断延迟的组成
什么叫中断延迟?说白了就是从硬件发出中断请求,到CPU开始执行你的ISR第一行代码,这中间到底花了多少时间。
我习惯把中断延迟拆成三部分来看:
| 延迟阶段 | 时间来源 | 典型时长(ARM Cortex-M3 @72MHz) |
|---|---|---|
| 硬件延迟 | 中断信号传递、CPU当前指令完成 | 3~12个时钟周期 |
| 中断响应 | 压栈、取向量、跳转 | 12~16个时钟周期 |
| 软件延迟 | 关中断时间、高优先级ISR执行 | 不确定,看你怎么写代码 |
前两部分基本是硬件决定的,你改不了。但软件延迟这部分,完全取决于你的代码质量。我在项目中遇到过最夸张的情况:一个同事在ISR里调用了printf,结果中断延迟直接飙到毫秒级。麻醉机的压力采样周期才1ms,这还得了?
1.2 中断嵌套与可重入性
中断嵌套,就是高优先级中断可以打断低优先级中断。听起来很美好对吧?但这里有个大坑——可重入性。
什么叫可重入?就是一个函数在被调用执行的过程中,又被再次调用了。如果这个函数使用了全局变量或者静态变量,那第二次调用就可能把第一次的数据给覆盖掉。
我举个例子:
// 不可重入的例子
static uint32_t counter = 0;
void increment_counter(void) {
counter++; // 如果被中断打断,再次调用,counter就乱了
}
// 可重入的例子
void increment_counter_safe(uint32_t *p_counter) {
(*p_counter)++; // 只操作传入的指针,不碰全局变量
}
在麻醉机里,这个问题特别要命。我记得有一次,压力传感器中断和流量传感器中断共享了一个全局缓冲区。结果两个中断嵌套了,缓冲区里的数据全乱了套。那台机器在测试时出现了压力波形抖动,排查了两天才找到原因。
我的建议:ISR里尽量别用全局变量。实在要用,就用volatile关键字声明,并且考虑用关中断或者原子操作来保护。但说实话,最好的办法就是——ISR里只做最必要的事。
1.3 ISR设计原则
这部分是我最想跟你分享的。做了十年嵌入式,我总结了几条ISR设计原则,每一条都是用教训换来的。
原则一:ISR要短小精悍
ISR不是让你写业务逻辑的地方。它的任务只有一个:快速接收事件,然后通知后台任务去处理。
怎么做?我习惯用这两种方式:
- 设置标志位:ISR里只置一个全局标志,主循环里轮询处理
- 使用消息队列:ISR把数据塞进队列,任务线程从队列里取
你想想看,如果ISR里做了一堆浮点运算,那其他中断得等到什么时候?
原则二:避免在ISR中调用不可重入函数
这个前面已经说过了。再强调一遍:printf、malloc、甚至是某些库函数,在ISR里调用都可能出问题。
我个人的习惯是:ISR里只用两种函数——要么是硬件寄存器操作,要么是自己写的、明确标注了可重入的函数。
原则三:合理设置中断优先级
麻醉机里,中断优先级不是随便设的。我一般这样排:
- 最高优先级:系统心跳定时器(1ms中断)——这是整个系统的节拍
- 次高优先级:压力/流量传感器中断——实时性要求极高
- 中等优先级:通信中断(SPI、I2C)——数据不能丢,但可以等一等
- 最低优先级:按键、显示刷新——慢一点没关系
💡 小技巧:我习惯在项目初期就画一张中断优先级表格,贴在工位上。每次新增中断,先看看这张表,避免优先级冲突。这个习惯帮我避免了好几次潜在的bug。
原则四:注意中断延迟的累积效应
单个中断延迟可能只有几微秒,但多个中断嵌套起来,延迟就可能累积到几十甚至上百微秒。在麻醉机这种生命支持设备里,最坏情况下的中断延迟才是你真正需要关心的。
怎么算?我一般这样估算:
最坏中断延迟 = 硬件延迟 + 最长关中断时间 + 所有高优先级ISR执行时间之和
如果这个值超过了你的实时性要求,那就得优化了。要么缩短关中断时间,要么降低某些ISR的执行时间。
小结
中断管理这件事,说难不难,说简单也不简单。关键是要有系统思维——别只盯着一个中断看,要看到整个中断系统的相互作用。
最后分享一个我自己的习惯:每次写完ISR,我都会问自己三个问题:
- 这个ISR能在10微秒内执行完吗?
- 如果被更高优先级中断打断,会出问题吗?
- 这个ISR里有没有调用不可重入函数?
三个问题都回答「是」,才算合格。嗯,这标准可能有点严,但做医疗设备嘛,严一点总没错。