ucosiii之互斥信号量

在ucosiii中优秀级反转是非常常见的事,如:一个低优先级的任务一直独占着信号量而不释放,高优先级的任务只能进入挂起状态,等待低优秀级任务把信号量释放,而在发生任务切换时,高优先级任务就不能执行,而执行较低的优先级任务,从而造成优先级反转。如图:
ucosiii之互斥信号量
为了防止优先级反转,ucosiii支持一种特殊的二进制信号量:互斥信号量(解决优先级反转问题)如下图所示:
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
	}
}