INT8U OSMutexPost(OS_EVENT *pevent){
INT8U pcp;/* Priority ceiling priority */
INT8U prio;#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr =0u;#endifif(OSIntNesting >0u)/* See if called from ISR ... */{return(OS_ERR_POST_ISR);/* ... can't POST mutex from an ISR */}#ifOS_ARG_CHK_EN >0uif(pevent ==(OS_EVENT *)0)/* Validate 'pevent' */{return(OS_ERR_PEVENT_NULL);}#endifif(pevent->OSEventType != OS_EVENT_TYPE_MUTEX)/* Validate event block type */{return(OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();
pcp =(INT8U)(pevent->OSEventCnt >>8u);/* Get priority ceiling priority of mutex */
prio =(INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);/* Get owner's original priority */if(OSTCBCur !=(OS_TCB *)pevent->OSEventPtr)/* See if posting task owns the MUTEX */{OS_EXIT_CRITICAL();return(OS_ERR_NOT_MUTEX_OWNER);}if(pcp != OS_PRIO_MUTEX_CEIL_DIS){if(OSTCBCur->OSTCBPrio == pcp)/* Did we have to raise current task's priority? */{OSMutex_RdyAtPrio(OSTCBCur, prio);/* Restore the task's original priority */}
OSTCBPrioTbl[pcp]= OS_TCB_RESERVED;/* Reserve table entry */}if(pevent->OSEventGrp !=0u)/* Any task waiting for the mutex? */{/* Yes, Make HPT waiting for mutex ready */
prio =OS_EventTaskRdy(pevent,(void*)0, OS_STAT_MUTEX, OS_STAT_PEND_OK);
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;/* Save priority of mutex's new owner */
pevent->OSEventCnt |= prio;
pevent->OSEventPtr = OSTCBPrioTbl[prio];/* Link to new mutex owner's OS_TCB */if((pcp != OS_PRIO_MUTEX_CEIL_DIS)&&(prio <= pcp))/* PCP 'must' have a SMALLER prio ... */{OS_EXIT_CRITICAL();/* ... than current task! */OS_Sched();/* Find highest priority task ready to run */return(OS_ERR_PCP_LOWER);}else{OS_EXIT_CRITICAL();OS_Sched();/* Find highest priority task ready to run */return(OS_ERR_NONE);}}
pevent->OSEventCnt |= OS_MUTEX_AVAILABLE;/* No, Mutex is now available */
pevent->OSEventPtr =(void*)0;OS_EXIT_CRITICAL();return(OS_ERR_NONE);}
互斥信号量获取/无等待
#ifOS_MUTEX_ACCEPT_EN >0u
BOOLEAN OSMutexAccept(OS_EVENT *pevent,
INT8U *perr){
INT8U pcp;/* Priority Ceiling Priority (PCP) */#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr =0u;#endif#ifdefOS_SAFETY_CRITICALif(perr ==(INT8U *)0){OS_SAFETY_CRITICAL_EXCEPTION();return(OS_FALSE);}#endif#ifOS_ARG_CHK_EN >0uif(pevent ==(OS_EVENT *)0)/* Validate 'pevent' */{*perr = OS_ERR_PEVENT_NULL;return(OS_FALSE);}#endifif(pevent->OSEventType != OS_EVENT_TYPE_MUTEX)/* Validate event block type */{*perr = OS_ERR_EVENT_TYPE;return(OS_FALSE);}if(OSIntNesting >0u)/* Make sure it's not called from an ISR */{*perr = OS_ERR_PEND_ISR;return(OS_FALSE);}OS_ENTER_CRITICAL();/* Get value (0 or 1) of Mutex */
pcp =(INT8U)(pevent->OSEventCnt >>8u);/* Get PCP from mutex */if((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8)== OS_MUTEX_AVAILABLE){
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;/* Mask off LSByte (Acquire Mutex) */
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;/* Save current task priority in LSByte */
pevent->OSEventPtr =(void*)OSTCBCur;/* Link TCB of task owning Mutex */if((pcp != OS_PRIO_MUTEX_CEIL_DIS)&&(OSTCBCur->OSTCBPrio <= pcp))/* PCP 'must' have a SMALLER prio ... */{OS_EXIT_CRITICAL();/* ... than current task! */*perr = OS_ERR_PCP_LOWER;}else{OS_EXIT_CRITICAL();*perr = OS_ERR_NONE;}return(OS_TRUE);}OS_EXIT_CRITICAL();*perr = OS_ERR_NONE;return(OS_FALSE);}#endif
互斥信号量状态查询
#ifOS_MUTEX_QUERY_EN >0u
INT8U OSMutexQuery(OS_EVENT *pevent,
OS_MUTEX_DATA *p_mutex_data){
INT8U i;
OS_PRIO *psrc;
OS_PRIO *pdest;#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr =0u;#endifif(OSIntNesting >0u)/* See if called from ISR ... */{return(OS_ERR_QUERY_ISR);/* ... can't QUERY mutex from an ISR */}#ifOS_ARG_CHK_EN >0uif(pevent ==(OS_EVENT *)0)/* Validate 'pevent' */{return(OS_ERR_PEVENT_NULL);}if(p_mutex_data ==(OS_MUTEX_DATA *)0)/* Validate 'p_mutex_data' */{return(OS_ERR_PDATA_NULL);}#endifif(pevent->OSEventType != OS_EVENT_TYPE_MUTEX)/* Validate event block type */{return(OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();
p_mutex_data->OSMutexPCP =(INT8U)(pevent->OSEventCnt >>8u);
p_mutex_data->OSOwnerPrio =(INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);if(p_mutex_data->OSOwnerPrio ==0xFFu){
p_mutex_data->OSValue = OS_TRUE;}else{
p_mutex_data->OSValue = OS_FALSE;}
p_mutex_data->OSEventGrp = pevent->OSEventGrp;/* Copy wait list */
psrc =&pevent->OSEventTbl[0];
pdest =&p_mutex_data->OSEventTbl[0];for(i =0u; i < OS_EVENT_TBL_SIZE; i++){*pdest++=*psrc++;}OS_EXIT_CRITICAL();return(OS_ERR_NONE);}#endif