UCOS互斥信号量操作函数分析
//建立并初始化一个互斥型信号量(优先级继承优先级(PIP)、出错代码指针)
OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_EVENT *pevent;
if (OSIntNesting > 0) { /* See if called from ISR ... */
*err = OS_ERR_CREATE_ISR; /* can''t CREATE mutex from an ISR */
return ((OS_EVENT *)0);
}//不能从ISR中建立,不允许在ISR中调用此函数
#if OS_ARG_CHK_EN > 0
if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */
*err = OS_PRIO_INVALID;
return ((OS_EVENT *)0);
}//不合理的PIP
#endif
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must nalready exist*/
//确认PIP没有被任何任务占用。OSTCBPrioTbl[ ]中的一个指向NULL的空指针指示//PIP有效
OS_EXIT_CRITICAL(); /* Task already exist at priority ... */
*err = OS_PRIO_EXIST; /* ... inheritance priority */
//如果优先级存在 ,则出错。
return ((OS_EVENT *)0);
}
OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the table entry */
//置非空指针,将这个优先级保留下来。
pevent = OSEventFreeList; /* Get next free event control block */
//从空余ECB中得到一块空的ECB。
if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */
//看ECB是否可用
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */
//如果不可用,释放此优先级表入口
OS_EXIT_CRITICAL();
*err = OS_ERR_PEVENT_NULL; /* No more event control blocks */
return (pevent);
}
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list
//如果可用,重新调整事件控制块的表头
OS_EXIT_CRITICAL();
pevent->OSEventType = OS_EVENT_TYPE_MUTEX; //将其标记为互斥型信号量
pevent->OSEventCnt = (prio << 8) | OS_MUTEX_AVAILABLE;/* Resource is available */ // (#define OS_MUTEX_AVAILABLE 0x00FF)
//mutex为有效值,同时将PIP保存起来。值得注意的是,事件计数器.OSEventCnt
//在此处的用法不同,高八位用于保存PIP的值,低侂位在资源无任务占用
//时的值为0xff,有任务占用时为占用mutex任务的优先级。这个避免了增加额
//外的空间,节约对RAM的占用量
pevent->OSEventPtr = (void *)0; /* No task owning the mutex */
//消息正在初始化,所以没有等待这个mutex的任务
OS_EventWaitListInit(pevent);//初始化事件等待列表
*err = OS_NO_ERR;
return (pevent);
}