引 言
VxWorks是美国Wind River(风河)公司的一个实时操作体系,具有杰出的可靠性和实时性。该体系选用根据优先抢占式调度战略,体系为每一个使命分配一个优先级,调度程序确保当时运转的是优先权最高的使命。但在实践开发中,因为使命间资源共享,信号量及中止的引进,往往会呈现高优先级使命被低优先级使命长期堵塞或堵塞一段不确守时刻的现象,即所谓优先级回转(Priority Inversion)。优先级回转会形成使命调度的不确定性,严峻时或许导致体系溃散。本文在参考文献的基础上,结合实践项目开发过程中遇到的优先级回转问题,对形成优先级回转的原因及其处理办法进行了讨论。
优先级回转一般性描绘
优先级回转发生在一个高优先级的使命被逼等候一段不确守时刻,图1中3个使命别离为ta sk1、task2和task3,其优先级由高到低。从图1可知,当task3占有由信号量(semaphore)维护的某种共享资源而进入临界区履行时,task1安排妥当,因为体系的抢占式调度战略,呈现task1抢占task3履行。task1履行一段时刻后也进入临界区,但此刻task3仍占有此临界资源的信号量,task1被堵塞,等候task3开释此信号量。在通过这么一段时刻后,task2已处于安排妥当状况,所以体系调度task2履行。假如task3在task2的履行期间一向没有可以被调度履行的话,那task1和task3将一向比及task2履行完后才干履行,task1更要比及task3开释它所占有的信号量才干履行;假如这段时刻超出task1的最终期限,task1的调度呈现了问题,此刻轻则使命被长期堵塞,重则形成体系溃散。
图1 优先级回转示意图
优先级回转原因可概括为:高优先级的使命task1因为要等候被低优先级使命task3占有的临界资源而被task2堵塞,而此刻具有中优先级的使命task2抢占了task3的CPU时刻,导致task2先于task1履行。此类优先级回转问题的处理办法大致有2种:一种被称作优先级承继(inheritance);另一种被称作优先级极限(ceilings)。下面介绍本文所遇到的优先级回转问题。
优先级回转的实例
上节对一般意义上的优先级回转现象进行了描绘,本节触及的优先级回转则较上述更为杂乱,更具有隐蔽性。本文选用的嵌入式微处理器为SAMSUNG公司的S3C2510, CPU核为arm940T。应项目要求使命task1和task2中别离进行调用微秒级和毫秒级的守时器功用函数,因为S3C2510处理器有5个32位守时器,因而只使用其间的两个即可。这儿,ms级守时器完成的代码架构如下:
1) 中止处理函数:
LOCAL void Timer1_Int_Handle(void)
{
*S3C2510_TIC |= S3C2510_TIC_T1;/*铲除中止*/
。
semGive(TelID4_Stop);/*开释二进制信号量*/
。
}
2) 毫秒级守时函数
void ms_Delay(int ms)
{
。
semTake(TelID4_Stop,WAIT_FOREVER);
。
}
3) 时钟初始化函数
void msTImer_Init()
{
TelID4_Stop=semCreate (SEM_Q_FI FO,SEM_EMPTY);/*初始化二进制信号量*/
assert(TelID4_Stop);
。
}
us级守时器功用完成的代码与上面相似,这儿不再给出相应的代码。函数调用阐明:先进行初始化,然后使命可随意调用守时功用函数。当某个使命调用守时功用函数时,该使命被信号量堵塞,一起守时器开端进行减一计数,当计数器减到0时,会发生一个中止请求信号,此刻体系会调用中止处理函数,在中止处理函数时将信号量开释,此刻信号质变的可用,使命持续履行。
当两个不同优先级使命task1,task2(设优先级别离为93和94)一起运转,并别离调用us和ms级守时功用函数时,优先级回转呈现了,task1会被长期堵塞。其间,task1和task2的调用如下:
void task1(void)
{
。
FOREVER
{
。
us_Delay();
。
taskDelay(4);
}
void Task2(void)
{
。
FOREVER
{
。
ms_Delay();
。
}
上述两个使命之间资源是独立的,但两个使命在一起运转时,高优先级使命task1在通过一段时刻后会被长期堵塞。处理上述问题的办法比较简单,只需调整task1的使命优先级低于task2,这儿选为95,则两个使命可长期并行运转。
因为加入了中止和信号量,使体系使命调度变的杂乱,然后导致两个本来看似独立的使命task1和task2,不能正常并行运转。形成此类现象的原因剖析极端杂乱,可视为是体系使用的一个盲点,但此类问题可通过总结规则而有用绕开。例如在上述问题中,若task1调用的守时函数的守时时刻小于task2中的守时时刻,则相应的使命优先级也应设有task1Priority《 task2Priority,这样高优先级使命就不会被堵塞。
结 语
本文结合实践比如,对VxWorks中优先级回转问题进行了讨论,并对此类问题的处理办法进行了描绘。本文的讨论将使嵌入式体系开发人员更深入了解优先级回转问题。