2、互斥信号量的创建
有这么一句很关键:pevent->OSEventCnt = ((INT16U)prio << 8) | OS_MUTEX_AVAILABLE;
//将继承优先级(专门预留给mutex的优先级,移至高八位,低八位用0xFF填充)
3、OSMutexPend()函数 核心代码 :
a、获得资源的情况:
if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE)
{
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Yes, Acquire the resource */
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save priority of owning task */
pevent->OSEventPtr = (void *)OSTCBCur; /* Point to owning task's OS_TCB */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return;
}
b、被挂起的情况太麻烦了: 要根据情况进行优先级翻转。
情况1、
当前运行且要申请处使用互斥资源的任务优先级比已经占有资源的优先级要小,那么就直接将当前任务通过函数OS_EventTaskWait()
挂在互斥事件的任务等待队列上。
情况2、
当前运行且要申请处使用互斥资源的任务优先级比已经占有资源的优先级要大,这是要进行优先级翻转,以防止高优先级的任务
把低优先级的任务打断。
该情况又有两种可能:
其一,正在占用互斥资源的任务正处于就绪状态.此时,应该将该任务从就绪队列中摘掉,然后再将优先级升级为mutex的继承优先级(保留的优先级),
并修改TCB中的个优先级各个位,并修改互斥事件中的该任务所对应的优先级位,然后再将该任务新的优先级对应的就绪队列表中的对应位置1,
最后挂起再次申请的任务,并调用调度程序。
其二、正在占用互斥资源的任务还未处于就绪状态.那么此时翻转该任务优先级,只修改该任务所对应的互斥事件等待队列中的相应位即可,最后挂起再次申请的任务,并调用调度程序。
c、当然,该函数也要处理任务超时的情况。