MCU任务交接:互斥等待与通知语义
实时任务偶发超期,未必说明处理器算得不够快。在单核抢占式 MCU 系统中,资源占有可能延长等待,事件通知也可能合并真实发生的次数。任务交接必须同时回答谁在阻塞,以及交付的信息是否完整。
设高优先级控制任务需要访问共享串行设备,低优先级记录任务已经持有设备锁。控制任务只能等待,而一个不使用该设备的中优先级计算任务却可以不断抢占记录任务。结果是高优先级工作间接受制于无关的计算负载,这就是资源占有引出的优先级反转。单纯继续提高控制任务优先级没有用,因为它仍未获得锁;若把保护改为普通二值信号量,也未必获得互斥锁具备的继承行为。
支持优先级继承的互斥锁会在条件满足时临时提升持有者,使其有机会尽快释放资源。不过继承只缓解中优先级干扰,不能把原本很长的设备事务变短。若记录任务持锁后等待一整次慢速外设操作,控制任务仍需要承担该占有时间。工程上应在锁外完成数据准备,将锁内范围压到确实需要独占的硬件访问,并给每项事务设定可验证的最大时长,而不是把整个业务函数都包进锁中。
嵌套锁还会改变等待链。某些实时内核采用简化继承机制,多个互斥对象的释放次序可能影响优先级恢复时机。评估时应按实际内核版本核对,不能假定所有实现都支持完整的链式继承。测试可分别安排低优先级持锁、中优先级满载和高优先级争用,记录持有者运行与解锁时刻。若持锁期间还等待另一把锁,必须把那段依赖也纳入阻塞预算,否则测得的局部时长会过分乐观。继承也不能解决循环等待形成的死锁。
资源交接完成后,事件交付还有另一种损失。任务通知若采用置位语义,同一事件连续发生三次,通知值中仍可能只有一个置位的比特。这很适合表达“状态已经变化,需要重新读取”,却不能自动表达“新增三份必须逐一处理的数据”。在接收任务运行前,后两次事件已经与第一次合并,通知发送成功也不能证明次数得到保存。这里丢失的是事件语义,与任务是否及时被唤醒是两个问题。
如果每次事件都代表一项工作,可以选择计数语义,并明确接收时是一次递减还是整体清零。整体清零后若只处理一项,其余次数便被软件主动丢弃;逐次递减则需要考虑持续积压与计数上限。需要携带样本地址或时间信息时,通知本身也不能替代有容量约束的消息队列。更清晰的实现是用队列保存工作内容,通知只承担唤醒,接收任务被唤醒后持续取出已有条目,直到达到约定的处理边界。
MCU 固件还应区分“允许合并的最新状态”和“不得合并的离散记录”。例如温控目标只需保留最新值,而计量脉冲必须累计次数。两者共用同一个通知通道,往往使覆盖与清零规则变得含糊。验证时可在任务休眠期间注入多个连续事件,并核对处理数量、积压峰值与最终状态。若结果依赖接收任务恰好运行得快,说明接口语义尚未封闭,降低平均调度延迟也只能暂时隐藏错误。
任务交接的可靠性来自明确契约:用受限的资源占有时间约束阻塞,用符合业务含义的通知方式保存事件。前者决定能否按时运行,后者决定运行之后是否处理了正确的工作。





