反转现象
任务优先级:H>M>L
绿色部分:任务占用共享资源
理想状态:7释放信号量后,最高优先级H任务抢占CPU
反转原因:H和L等待同一个信号量,H的任务优先级被降至和L相同优先级,此时M已经成为最高优先级
实验举例
void start_task(void *p_arg)
{
OS_CRITICAL_ENTER(); //进入临界区
//创建一个信号量
OSSemCreate ((OS_SEM* )&TEST_SEM,
(CPU_CHAR* )"TEST_SEM",
(OS_SEM_CTR)1, //信号量初始值为1
(OS_ERR* )&err);
//创建HIGH任务
OSTaskCreate((OS_TCB * )&High_TaskTCB,
(CPU_CHAR * )"High task",
(OS_TASK_PTR )high_task,
(void * )0,
(OS_PRIO )HIGH_TASK_PRIO,
(CPU_STK * )&HIGH_TASK_STK[0],
(CPU_STK_SIZE)HIGH_STK_SIZE/10,
(CPU_STK_SIZE)HIGH_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void * )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR * )&err);
//创建MIDDLE任务
OSTaskCreate((OS_TCB * )&Middle_TaskTCB,
(CPU_CHAR * )"Middle task",
(OS_TASK_PTR )middle_task,
(void * )0,
(OS_PRIO )MIDDLE_TASK_PRIO,
(CPU_STK * )&MIDDLE_TASK_STK[0],
(CPU_STK_SIZE)MIDDLE_STK_SIZE/10,
(CPU_STK_SIZE)MIDDLE_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void * )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR * )&err);
//创建LOW任务
OSTaskCreate((OS_TCB * )&Low_TaskTCB,
(CPU_CHAR * )"Low task",
(OS_TASK_PTR )low_task,
(void * )0,
(OS_PRIO )LOW_TASK_PRIO,
(CPU_STK * )&LOW_TASK_STK[0],
(CPU_STK_SIZE)LOW_STK_SIZE/10,
(CPU_STK_SIZE)LOW_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void * )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR * )&err);
OS_CRITICAL_EXIT(); //退出临界区
}
//高优先级任务的任务函数
void high_task(void *p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();
while(1)
{
OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_PERIODIC,&err); //延时500ms
printf("high task Pend Sem\r\n");
OSSemPend(&TEST_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量
printf("high task Running!\r\n");
OSSemPost(&TEST_SEM,OS_OPT_POST_1,&err); //释放信号量
OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_PERIODIC,&err); //延时500ms
}
}
//中等优先级任务的任务函数
void middle_task(void *p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();
while(1)
{
printf("middle task Running!\r\n");
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
}
}
//低优先级任务的任务函数
void low_task(void *p_arg)
{
static u32 times;
OS_ERR err;
while(1)
{
OSSemPend(&TEST_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量
printf("low task Running!\r\n");
for(times=0;times<5000000;times++)
{
OSSched(); //发起任务调度
}
OSSemPost(&TEST_SEM,OS_OPT_POST_1,&err);
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
}
}
实验现象
解决办法 UCOSIII互斥信号量:
http://blog.csdn.net/zhangxuechao_/article/details/78912647