?? os_sem.c
字號:
/*
*********************************************************************************************************
* PEND ON SEMAPHORE
*
* Description: This function waits for a semaphore.
*
* Arguments : pevent is a pointer to the event control block associated with the desired
* semaphore.
*
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will
* wait for the resource up to the amount of time specified by this argument.
* If you specify 0, however, your task will wait forever at the specified
* semaphore or, until the resource becomes available (or the event occurs).
*
* err is a pointer to where an error message will be deposited. Possible error
* messages are:
*
* OS_NO_ERR The call was successful and your task owns the resource
* or, the event you are waiting for occurred.
* OS_TIMEOUT The semaphore was not received within the specified
* timeout.
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
* would lead to a suspension.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
*
* Returns : none
等待一個信號量
描述:等待一個信號量
參數:pevent:指向事件控制塊結合目標信號量的指針
timeout:定時超時選項(以時鐘節拍為單位),如果非零,你的任務將等待
//資源的時間值就是這個參數,如果為零,將永遠等待直到資源變成可用(或者其它事件發生)
err 指向錯誤代碼的消息指針
* 消息為:
*
* OS_NO_ERR 調用成功,任務擁有資源或者目標事件發生
* OS_TIMEOUT 規定時間內信號量沒有發生
* OS_ERR_EVENT_TYPE 如果沒有傳遞指針到信號量
* OS_ERR_PEND_ISR 如果ISR調用此函數,結果將異常
* OS_ERR_PEVENT_NULL 如果 'pevent' 是一個空指針
*********************************************************************************************************
*/
void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
if (OSIntNesting > 0) { /* See if called from ISR ... */
*err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
return;
}//是不是在ISR中調用
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*err = OS_ERR_PEVENT_NULL;
return;
}//非法的pevent
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
*err = OS_ERR_EVENT_TYPE;
return;
}//不是事件塊類型
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */
pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return;
}
//如果信號量有效,則信號量計數值遞減,返回無錯給調用它的函數,如果此
//函數用于等待一共享資源的信號量,那么通過返回此值,知道代碼是否正確運行。
//如果信號量的計數值為0,則調用此函數的任務將進入睡眠狀態,等待另一個任務
//或者ISR發出信號量。
/* Otherwise, must wait until event occurs */
OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */
//資源不可用,掛起任務
OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */
//保存掛起定時到TCB
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
//使任務等待事件發生(將任務掛起)
OS_EXIT_CRITICAL();
OS_Sched(); /* Find next highest priority task ready */
//由于得不到信號量,當前任務不再處于就緒狀態,任務調度,讓下一個
//優先級最高的任務運行。這樣,調用此函數的任務被掛起,直到信號量出現,
//才能繼續運行。
OS_ENTER_CRITICAL();
if (OSTCBCur->OSTCBStat & OS_STAT_SEM) { /* Must have timed out if still waiting for event*/
//再次檢查任務控制塊中的狀態標志,是否仍處于等待信號量的狀態,如果是,
//則說明該任務并沒有被此函數發出的信號量喚醒;而實際上該任務是因為等待
//超時,而被TimeTick()函數置為就緒態。
OS_EventTO(pevent);//等待事件超時,將任務從等待列表中刪除,讓任務繼續運行。
OS_EXIT_CRITICAL();
*err = OS_TIMEOUT; /* Indicate that didn't get event within TO *///返回超時錯誤代碼
return;//超時了
}
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;//將指向信號量ECB的指針從該任務的任務控制塊中刪除
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
}
/*$PAGE*/
/*
*********************************************************************************************************
* POST TO A SEMAPHORE
*
* Description: This function signals a semaphore
*
* Arguments : pevent is a pointer to the event control block associated with the desired
* semaphore.
*
* Returns : OS_NO_ERR The call was successful and the semaphore was signaled.
* OS_SEM_OVF If the semaphore count exceeded its limit. In other words, you have
* signalled the semaphore more often than you waited on it with either
* OSSemAccept() or OSSemPend().
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
發出一個信號量
描述:發出一個信號量
參數:pevent :指向事件控制塊結合目標信號量的指針
返回:OS_NO_ERR 調用成功,信號量發出
* OS_SEM_OVF 信號量數目超出范圍. 也就是說你發送的信號量多于在either
* OSSemAccept() or OSSemPend()中等待的
* OS_ERR_EVENT_TYPE 沒有傳遞指針給信號量
* OS_ERR_PEVENT_NULL 如果 'pevent' 是空指針
*********************************************************************************************************
*/
INT8U OSSemPost (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}//非法的pevent
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}//不是事件塊類型
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00) { /* See if any task waiting for semaphore */
//是不是有任務等待
OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* Ready highest prio task waiting on event */
//就緒最高優先級的等待任務
OS_EXIT_CRITICAL();
OS_Sched(); /* Find highest priority task ready to run *///任務調度,找最高優先級的任務運行
return (OS_NO_ERR);
}
if (pevent->OSEventCnt < 65535) { /* Make sure semaphore will not overflow */
//保證信號量沒有溢出
pevent->OSEventCnt++; /* Increment semaphore count to register event */
//更新信號量數目
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum *///信號量滿了。
return (OS_SEM_OVF);
}
/*$PAGE*/
/*
*********************************************************************************************************
* QUERY A SEMAPHORE
*
* Description: This function obtains information about a semaphore
*
* Arguments : pevent is a pointer to the event control block associated with the desired
* semaphore
*
* pdata is a pointer to a structure that will contain information about the
* semaphore.
*
* Returns : OS_NO_ERR The call was successful and the message was sent
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non semaphore.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
查詢一個信號量的當前狀態
描述:獲得一個信號量的信息
參數:pevent:指向事件控制塊結合目標信號量的指針
pdata:指向包含信號量信息的結構指針
返回:OS_NO_ERR 調用成功,消息發送
* OS_ERR_EVENT_TYPE 如果想從非信號量獲得數據
* OS_ERR_PEVENT_NULL 如果 'pevent' 是空指針
*********************************************************************************************************
*/
#if OS_SEM_QUERY_EN > 0
INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U *psrc;
INT8U *pdest;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}//非法的pevent
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}//不是事件塊類型
#endif
OS_ENTER_CRITICAL();
pdata->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
//將OS_EVENT結構中的等待任務列表復制到OS_SEM_DATA數據結構中,
//此處使用條件編譯不不用循環語句,目的是使程序運行得更愉
psrc = &pevent->OSEventTbl[0];
pdest = &pdata->OSEventTbl[0];//指向表頭
#if OS_EVENT_TBL_SIZE > 0
*pdest++ = *psrc++;
#endif
#if OS_EVENT_TBL_SIZE > 1
*pdest++ = *psrc++;
#endif
#if OS_EVENT_TBL_SIZE > 2
*pdest++ = *psrc++;
#endif
#if OS_EVENT_TBL_SIZE > 3
*pdest++ = *psrc++;
#endif
#if OS_EVENT_TBL_SIZE > 4
*pdest++ = *psrc++;
#endif
#if OS_EVENT_TBL_SIZE > 5
*pdest++ = *psrc++;
#endif
#if OS_EVENT_TBL_SIZE > 6
*pdest++ = *psrc++;
#endif
#if OS_EVENT_TBL_SIZE > 7
*pdest = *psrc;
#endif
pdata->OSCnt = pevent->OSEventCnt; /* Get semaphore count */
//獲得信號量數。
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif /* OS_SEM_QUERY_EN */
#endif /* OS_SEM_EN */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -