AUTOSAR标准对于操作系统的基本任务(Basic Task)定义了运行、挂起和就绪三种状态。任务从挂起状态被激活后,首先进入就绪状态,然后才会转入运行状态,如下图所示。
这意味着任务的激活时刻并不一定是任务实际开始运行的时刻。下图以1ms任务和10ms任务为例进行讲解。假设这两个任务的实际执行时间(如图中黑色粗实线所示)各需100us和2ms,当这两个任务同时被激活时,如图中A点,此时优先级较高的1ms任务首先进入运行状态,执行完毕后,如图中B点,操作系统再进行调度,将10ms任务设为运行状态,10ms任务此时才获得执行。
更进一步,如果在A点和B点之间,有比10ms任务更高优先级的X任务被激活,则10ms任务的实际执行时刻将进一步延后。如下入所示。
若X任务的实际执行时间为1.9ms,而上一次10ms任务在激活后立即得到执行,没有被耽搁,则这两次10ms任务之间的实际执行间隔时间约为10+1.9+0.1x3ms, 即约12.2ms。若下一次10ms任务也能够在激活后立即得到执行,则本次10ms任务和下一次10ms任务之间的实际执行间隔时间约为7.8ms。这就是所谓的周期性任务实际执行周期的“抖动”现象。
其实,AUTOSAR标准及其前身OSEK标准中,对操作系统中指定任务的激活频率(Activation Rate)和执行频率(Execuation rate)有明确的定义,如下图所示。一定不能将二者混淆,否则可能在开发中遇到“解释不了”的诡异问题。
下图给出了一个因为没有充分考虑周期性任务的执行“抖动”而导致状态机异常的案例。其中红色曲线表示某状态机的状态,黄色曲线表示100ms任务的计数器,橙色表示10ms任务的计数器。状态机的核心操作S1-S4在10ms任务中依次完成,同时100ms任务中将对状态机进行强制重置。
由图中可以看出,多数情况下相邻两次100ms任务执行时间间隔在100ms左右,少数情况下会出现间隔偏长和偏短的情况。图中右上方M-N处显示最短的间隔仅为47.2ms。
当相邻两次100ms任务执行时间间隔较长时,状态机中的四个操作步骤可以全部获得执行,如图中A点处所示,S1~S4分别代表状态机的四个操作步骤。反之,如果相邻两次100ms任务执行时间隔时间较短,如图中B点处,100ms任务在S4尚未执行时便得到运行,导致状态机的状态被强制重置而未能正常结束,进而造成功能表现异常。
总结一下:操作系统中任务的激活不等于执行,周期性任务相邻两次实际执行间隔也并不等于所配置的周期,实际软件功能逻辑设计过程中,务必要注意任务执行周期的“抖动”可能带来的影响。