中断、余量与那点“不体面”:嵌入式系统设计的现场边界
会议室里有人问,样机在实验室跑了一周没事,装到现场隔三差五复位。我没急着答。先问:看门狗喂狗放在哪个上下文?——嵌入式系统设计里,很多故障不是功能没写,是时序没交代清楚。代码能跑,和系统可预测,两码事。
嵌入式系统中断响应时序与优先级抢占调度示意图
优先级反转更隐蔽。低优先级任务拿着互斥量,高优先级任务等锁,中优先级任务在旁边跑得欢。表面看高优先级被“卡住”,其实是资源协议没设计好。优先级继承、优先级天花板能缓解,但有代价:上下文切换变多,系统复杂度上升。临界区里关中断也一样,关中断时间必须有上限,否则实时性是被自己人关掉的。
嵌入式系统BSP板级支持包与HAL硬件抽象层分层架构图
寄存器访问要 volatile,编译器优化可不管你的外设时序。可 volatile 也不是万能盾牌,内存屏障、读写顺序、缓存一致性,该写清楚还得写清楚。有人复制粘贴驱动,改个宏就上线。实验室里外设碰巧响应慢,现场换批次器件,时序余量不够,故障就来了。说实话,这类问题最不体面——不是算法错,是时序账没算。
实时不是“快”,是可预测的迟到上限
有人把主频高当成实时性强。这个误会很常见。实时系统的核心不是平均响应快,而是最坏情况下仍然满足截止时间。中断延迟、调度延迟、临界区长度、缓存命中不确定性,都会把“平均很快”撕开口子。硬实时和软实时得分开看:电机换相错过窗口可能烧管,界面刷新晚几十毫秒用户未必察觉。条件不同,设计约束就不同。 RTOS 不是魔法。优先级抢占调度建立在可估算的最坏执行时间上。WCET 估不出来,优先级表排得再漂亮,也只是纸面秩序。我见过把浮点运算塞进中断里的设计——能跑,但每次进中断都像把大门关上扫一遍地。外面排队的中断只能等。对吧?
嵌入式系统中断响应时序与优先级抢占调度示意图
优先级反转更隐蔽。低优先级任务拿着互斥量,高优先级任务等锁,中优先级任务在旁边跑得欢。表面看高优先级被“卡住”,其实是资源协议没设计好。优先级继承、优先级天花板能缓解,但有代价:上下文切换变多,系统复杂度上升。临界区里关中断也一样,关中断时间必须有上限,否则实时性是被自己人关掉的。
BSP、HAL 和“板子一换就翻车”
换一块板子,驱动全重写,这种项目不罕见。硬件抽象层不是把寄存器读写包一层函数就完事。时钟树、引脚复用、DMA 通道、中断控制器映射,任何一处和板级支持包耦合,移植性就是口号。BSP 该干的活是把硬件差异关在边界内,不是把差异藏起来假装没有。
嵌入式系统BSP板级支持包与HAL硬件抽象层分层架构图
寄存器访问要 volatile,编译器优化可不管你的外设时序。可 volatile 也不是万能盾牌,内存屏障、读写顺序、缓存一致性,该写清楚还得写清楚。有人复制粘贴驱动,改个宏就上线。实验室里外设碰巧响应慢,现场换批次器件,时序余量不够,故障就来了。说实话,这类问题最不体面——不是算法错,是时序账没算。