ucosiii之互斥信号量
在ucosiii中优秀级反转是非常常见的事,如:一个低优先级的任务一直独占着信号量而不释放,高优先级的任务只能进入挂起状态,等待低优秀级任务把信号量释放,而在发生任务切换时,高优先级任务就不能执行,而执行较低的优先级任务,从而造成优先级反转。如图:
为了防止优先级反转,ucosiii支持一种特殊的二进制信号量:互斥信号量(解决优先级反转问题)如下图所示:
//互斥信号量常用函数如下图所示 :
//互斥信号量的例子如下:
//定义一个互斥信号量
OS_MUTEX SEM_MUTEX; //定义一个互斥信号量
//创建互斥信号量
OSMutexCreate((OS_MUTEX* )&SEM_MUTEX,
(CPU_CHAR* )"SEM_MUTEX",
(OS_ERR* )&err);
//测试互斥信号量
//最高优先级任务
void SemMutexH_task(void *p_arg)
{
OS_ERR err;
while(1)
{
OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_PERIODIC,&err); //延时500ms
printf("high task Pend Mutex\r\n");
OSMutexPend (&SEM_MUTEX,0,OS_OPT_PEND_BLOCKING,0,&err); //请求互斥信号量
printf("high task Running!\r\n");
OSMutexPost(&SEM_MUTEX,OS_OPT_POST_NONE,&err); //释放互斥信号量
OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_PERIODIC,&err); //延时500ms
}
}
//中等优秀级
void SemMutexM_task(void *p_arg)
{
OS_ERR err;
while(1)
{
printf("middle task Running!\r\n");
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
}
}
//最低优先级(当其独占互斥信号量时,"当前任务"会将任务的优先级提高到"申请该互斥信号量的任务"的优先级别一样高),这样优先级就不会反转了
void SemMutexL_task(void *p_arg)
{
static u32 times;
OS_ERR err;
while(1)
{
OSMutexPend (&SEM_MUTEX,0,OS_OPT_PEND_BLOCKING,0,&err);//请求互斥信号量
printf("low task Running!\r\n");
for(times=0;times<100;times++)
{
OSSched(); //发起任务调度(此时当前任务优先级跟请求信号量的任务优先级一样,就是跟SemMutexH_task()任务优先级一样)
}
OSMutexPost(&SEM_MUTEX,OS_OPT_POST_NONE,&err); //释放互斥信号量
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
}
}