图5 交换ServerTask与ControlTask优先级结果
使用互斥信号量
当多个任务访问同一资源时,例如网络驱动或图形显示,可能会发生优先级反转。这种情况下,可以使用互斥信号量降低优先级反转的影响。
互斥信号量是包含优先级继承机制的二值信号量,二值信号量更适合实现任务间或任务与中断服务之间的同步操作,互斥信号量更适用于互斥实现。
用作互斥机制时,互斥信号量相当于一个令牌,保护共享资源。当任务希望访问该共享资源时,需要首先获得(“take”)令牌。资源使用完后,任务必须释放令牌,让其它任务可以访问相同的资源。
互斥信号量允许指定阻塞时间,阻塞时间指示一个任务在尝试获取令牌时,如果令牌不可用,任务可以阻塞的最大节拍数。然而,与二值信号量的区别在于,互斥量支持优先级继承机制。这意味着,如果有一个高优先级的任务在试图获取当前持有令牌的低优先级任务占用的资源时,系统会临时提升占有资源的任务优先级别为被阻塞任务的优先级。该机制确保高优先级的阻塞时间尽量短,从而尽量减少优先级反转的时间。
优先级继承并不能解决优先级反转问题,它只是最小化了反转在某些情况下产生的影响。硬实时应用设计时,需保证优先级反转不会发生。
使用Gatekeeper任务
在访问系统资源时,为了避免优先级反转问题,我们推荐使用“Gatekeeper”任务。Gatekeeper任务结构如图6所示,包含一个控制资源的任务,接收数据/命令的队列和一个回调函数。
应用任务不直接访问资源,而是将数据/命令写入队列。Gatekeeper任务处理接收到的数据/命令,并相应地更新资源。资源状态发生改变时,将触发ISR (例如接收到一个新的网络消息),将信息放置在队列中,然后,Gatekeeper任务将执行回调函数,将新的数据传给应用任务。
此方法防止了系统资源访问时优先级反转的出现,是我们推荐的解决办法。
图6 Gatekeeper任务
结论
使用实时内核,优先级反转问题是实时系统中出现得非常多的问题。在嵌入式系统系统设计时,应尽量避免优先级反转发生,或者可以通过可视化分析工具捕获该问题,通过相应的RTOS方法降低其风险。