探路者号 Mars PathFinder 是宇航历史上的一个重要里程碑,发回了很多火星上的图片,让地球人终于可以一睹火星地表的情况。开始的运行过程还比较顺利,有一天探路者号忽然不动了,一直在反复重启。从事后的一些分析文章,我们可以有幸知道一些情况,原来探路者运行的是经典的 RTOS VxWorks,这个时候发生了优先级反转这个嵌入式系统中的典型事件。
系统中运行了3个线程:
T1: Information bus thread,系统通信总线集中处理线程,优先级高T2:Communiction thread,远程通信线程,优先级中等,运行时间可能会比较长T3:Weather thread,气象传感数据处理,优先级低
T3 和 T1 之间共享了一个数据区,作为系统通信数据交互区域,T3 收集到数据后要把数据发给总线,于是向系统申请一个互斥量 mutex,这时候 T2 要求开始运行,由于 T2 的优先级高于 T3,于是开始 T2 的运行。而这个时候 T1 作为高优先级的线程,在等待 T3释放互斥量,长时间得不到调度,时间一长看门狗就复位了。
当时的解决方式是优先级继承,T3 由于是申请了一个 T1 同时共享的互斥量,于是申请的时候临时把优先级提升到 T1,于是 T2 就没有机会打断运行,就不会发生优先级反转。
事后诸葛虽然看起来简单,但实际运行的系统在几万公里之外,工程师是如何发现和解决这个问题的呢?实际运行的系统也带了完整的 trace,于是他们在本地模拟了流程,经过十几个小时,完全复现了该现象,于是可以进行有效的问题定位。而且系统带上了远程补丁系统,通过远程的差分补丁,实现了系统修复。
为什么事前没有发现呢?首先,这确实是工程师的失误,因为地面模拟的时候偶尔也出现过异常复位,但了解系统运行的人一般会觉得只是硬件故障,或者低概率事件。其次,实验场景没有完全模拟出来,实际运行的天线比预想的效果好很多,气象传感数据远高于模拟的状态,得到数据后就申请互斥量,于是导致概率上升很多。
几个认知:* Test-what-you-fly-and-fly-what-you-test* Debug and trace system* Patching system