?? os_sem.c
字號:
default:
OS_EXIT_CRITICAL();
*err = OS_ERR_INVALID_OPT;
return (pevent);
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 掛起信號量
*
* 函數描述: 該函數用于等待一個信號量
*
* 輸入參數: pevent 指向已建有期望的信號量的ECB的指針
*
* timeout 選擇延時時間。如果非0,則任務等待資源指定的延時時間。如果為0,則任務一直等到
* 資源有效或事件發生為止。
*
* 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 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
if (OSIntNesting > 0)
{ /* 如果調用來自 ISR ... */
*err = OS_ERR_PEND_ISR; /* ... 從 ISR調用將不能掛起 */
return;
}
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 空指針 'pevent' */
*err = OS_ERR_PEVENT_NULL;
return;
}
if (pevent->OSEventType != OS_EVENT_TYPE_SEM)
{ /* 無效的事件類型 */
*err = OS_ERR_EVENT_TYPE;
return;
}
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventCnt > 0) /* 如果信號量是正,則有效 ... */
{
pevent->OSEventCnt--; /* ... 只有為正,信號量減1. */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return;
}
/* 否則等,直到事件發生 */
OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* 資源無效, 掛起 */
OSTCBCur->OSTCBDly = timeout; /* 在TCB中寫入,延時時間 */
OS_EventTaskWait(pevent); /* 掛起任務直到事件發生或延時時間到 */
OS_EXIT_CRITICAL();
OS_Sched(); /* 尋找最高優先級任務,就緒運行它 */
OS_ENTER_CRITICAL();
if (OSTCBCur->OSTCBStat & OS_STAT_SEM)
{ /* 如果仍等待事件發生,就緒任務*/
OS_EventTO(pevent);
OS_EXIT_CRITICAL();
*err = OS_TIMEOUT; /* 顯示在延時時間內沒有等到事件 */
return;
}
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* 將指向信號量ECB的指針從該任務的TCB中刪除 */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
}
/*$PAGE*/
/*
*********************************************************************************************************
* 發送一個信號量
*
* 函數描述: 該函數發送一個信號量
*
* 輸入參數 : pevent 指向已建有期望的信號量的ECB的指針
*
* 返回值 : OS_NO_ERR 調用成功信號量被發送
* OS_SEM_OVF 信號量計數器超過限值.換句話說,信號量的發送數超過OSSemAccept()或OSSemPend()
* 等待的數目。
* OS_ERR_EVENT_TYPE 傳遞的不是信號量的指針
* OS_ERR_PEVENT_NULL 'pevent' 是空指針.
*********************************************************************************************************
*/
INT8U OSSemPost (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 無效的 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (pevent->OSEventType != OS_EVENT_TYPE_SEM)
{ /* 無效的事件控制塊型 */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00)
{ /* 看是否有任務在等待信號量? */
OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* 就緒等待事件中的最高優先級任務 */
OS_EXIT_CRITICAL();
OS_Sched(); /* 任務切換,找最高優先級任務就緒運行 */
return (OS_NO_ERR);
}
if (pevent->OSEventCnt < 65535)
{ /* 確信信號量沒有溢出 */
pevent->OSEventCnt++; /* 加信號量計數器以注冊事件 */
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL(); /* 信號量達到最大值 */
return (OS_SEM_OVF);
}
/*$PAGE*/
/*
*********************************************************************************************************
* 得到一個信號量的信息
*
* 函數描述: 該函數得到信號量的信息
*
* 輸入參數 : pevent 指向已建有期望的信號量的ECB的指針
*
* 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 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
INT8U *psrc;
INT8U *pdest;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* 無效的 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* 無效的事件控制塊型 */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
pdata->OSEventGrp = pevent->OSEventGrp; /* 復制消息郵箱的等待列表 */
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; /* 得到信號量計數器 */
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 + -