任务优先级反转:
原理是,信号量是稀缺资源,当一个低优先级的任务霸占了信号量,高优先级任务想要用这个信号量只好等待,于是呢,在这个间隙里,中优先级的任务(当然,这个任务是不想用该信号量的)就获得了CPU的使用权,等低优先级任务在中优先级任务的压迫下缓慢的完成了信号量的使用并做了释放,这时高优先级的任务才得以获得信号量继续运行。这样,看实际效果呢,中优先级任务就事实上比高优先级任务更加优先了,也就是所谓的任务优先级反转,这种现象是RTOS不能允许的,所以才会出现互斥型信号量的任务优先级提升解决措施。
此例中,有三个任务,分别为Task-1,Task-2,Task-3,优先级呢,Task-1最高,Task-3最低,Task-2居中。Task-3霸占了信号量的使用权,代码中用循环来模拟长期霸占,此期间,Task-1也申请使用该信号量,但是却只能等待,事实上Task-2获得了期间的运行权,实际运行效果如下。
代码如下:
void main (void)
{
OSInit(); /* Initialize uC/OS-II*/
init_devices();
LCD_init();
OSTaskCreate(Task_1,(void *)&TaskData[3],&Task_Stack[3][TASK_STK_SIZE - 1], 2);
OSTaskCreate(Task_2,(void *)&TaskData[1],&Task_Stack[1][TASK_STK_SIZE - 1], 3);
OSTaskCreate(Task_3, (void *)&TaskData[2],&Task_Stack[2][TASK_STK_SIZE - 1], 4);
Sem=OSSemCreate(1);
OSStart(); /* Start multitasking*/
}
/***********************************************************************************************************/
void Task_1 (void *pdata)
{
pdata=pdata;
for(;;)
{
serial('T');serial('a');serial('s');serial('k');serial('1');
serial(' ');
serial('R');serial('e');serial('q');serial('u');serial('i');serial('r');serial('e');
serial(' ');
serial('S');serial('e');serial('m');
serial(0x0d);serial(0x0a);
OSSemPend(Sem,0,&err);
serial('T');serial('a');serial('s');serial('k');serial('1');
serial(' ');
serial('G');serial('o');serial('t');
serial(' ');
serial('S');serial('e');serial('m');
serial(0x0d);serial(0x0a);
OSSemPost(Sem);
serial('T');serial('a');serial('s');serial('k');serial('1');
serial(' ');
serial('P');serial('o');serial('s');serial('t');serial('e');serial('d');
serial(' ');
serial('S');serial('e');serial('m');
serial(0x0d);serial(0x0a);
OSTimeDly(200); //?óê±2??
}
}
void Task_2 (void *pdata)
{ BOOLEAN led_state;
INT8U b=0;
pdata = pdata;
for (;;)
{
serial('T');serial('a');serial('s');serial('k');serial('2');
serial(' ');
serial('o');serial('p');serial('e');serial('r');
serial('a');serial('t');serial('e');serial('s');
serial(0x0d);serial(0x0a);
OSTimeDly(100); //?óê±1??
if(led_state==FALSE)
{
led_state=TRUE;
led_on();//?aLED
}
else
{
led_state=FALSE;
led_off();//1?LED
}
}
}
void Task_3 (void *pdata)
{
pdata=pdata;
for (;;)
{
//LCD_write_english_string(0,5,"NETPLAYER 2010");
serial('T');serial('a');serial('s');serial('k');serial('3');
serial(' ');
serial('R');serial('e');serial('q');serial('u');serial('i');serial('r');serial('e');
serial(' ');
serial('S');serial('e');serial('m');
serial(0x0d);serial(0x0a);
OSSemPend(Sem,0,&err);
serial('T');serial('a');serial('s');serial('k');serial('3');
serial(' ');
serial('G');serial('o');serial('t');
serial(' ');
serial('S');serial('e');serial('m');
serial(0x0d);serial(0x0a);
a=0;
while(a++<200000)
{
OS_Sched();
}
serial('T');serial('a');serial('s');serial('k');serial('3');
serial(' ');
serial('P');serial('o');serial('s');serial('t');serial('e');serial('d');
serial(' ');
serial('S');serial('e');serial('m');
serial(0x0d);serial(0x0a);
OSSemPost(Sem);//release
OSTimeDly(100); //?óê±1??
}
}
http://zhaolu386335605.blog.163.com/blog/static/1674090012012424101942267/