?? os_q.c
字號:
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 清空消息隊列
*
* 函數描述 : 該函數用于清空消息隊列中的內容
*
* 輸入參數 : 無
*
* 返回值 : OS_NO_ERR 調用成功
* OS_ERR_EVENT_TYPE 從一個非消息隊列中獲取信息
* OS_ERR_PEVENT_NULL 'pevent' 是一個空指針
*********************************************************************************************************
*/
#if OS_Q_FLUSH_EN > 0
INT8U OSQFlush (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
OS_Q *pq;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 無效的 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q)
{ /* 無效的事件塊類型 */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
pq = (OS_Q *)pevent->OSEventPtr; /* 指向隊列的存儲結構 */
pq->OSQIn = pq->OSQStart;
pq->OSQOut = pq->OSQStart;
pq->OSQEntries = 0;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 等待隊列中的消息
*
* 函數描述: 該函數等待發送到隊列中的消息
*
* 輸入參數 : pevent 指向帶有期望隊列的ECB的指針
*
* timeout 選擇延時時間。如果非0,則任務將在指定的延時時間內等待到達隊列中的消息。如果為0,
* 則任務將一直等待隊列中消息的到來。
* err 指向出錯代碼的指針。其值為:
*
* OS_NO_ERR 調用成功,任務收到消息
* OS_TIMEOUT 在指定的延時時間內,沒有收到消息
* OS_ERR_EVENT_TYPE 無效的事件類型
* OS_ERR_PEVENT_NULL 'pevent' 是一個空指針
* OS_ERR_PEND_ISR 從ISR中調用該函數,將導致掛起
*
* Returns : != (void *)0 指向接收到消息的指針
* == (void *)0 沒有消息接收,,
* 'pevent' 是一個空指針,
* 沒有傳遞給隊列一個恰當的指針.
*********************************************************************************************************
*/
void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
void *msg;
OS_Q *pq;
if (OSIntNesting > 0)
{ /* 如果調用來自 ISR ... ... */
*err = OS_ERR_PEND_ISR; /* ... 從ISR中不能掛起 */
return ((void *)0);
}
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 無效的 'pevent' */
*err = OS_ERR_PEVENT_NULL;
return ((void *)0);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q)
{ /* 無效的事件塊類型 */
*err = OS_ERR_EVENT_TYPE;
return ((void *)0);
}
#endif
OS_ENTER_CRITICAL();
pq = (OS_Q *)pevent->OSEventPtr; /* 指向QCB */
if (pq->OSQEntries > 0) /* 看隊列中是否有消息? */
{
msg = *pq->OSQOut++; /* 是,提取最先進入的消息 */
pq->OSQEntries--; /* 更新隊列中的消息數 */
if (pq->OSQOut == pq->OSQEnd)
{ /* 進行邊界檢查 */
pq->OSQOut = pq->OSQStart;
}
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (msg); /* 返回接收到的消息 */
}
OSTCBCur->OSTCBStat |= OS_STAT_Q; /* 消息無效,任務將等待 */
OSTCBCur->OSTCBDly = timeout; /* 在TCB中加載延時數 */
OS_EventTaskWait(pevent); /* 掛起任務直到事件發生或延時到 */
OS_EXIT_CRITICAL();
OS_Sched(); /* 尋找最高優先級任務就緒運行 */
OS_ENTER_CRITICAL();
msg = OSTCBCur->OSTCBMsg;
if (msg != (void *)0)
{ /* 看是否有消息? */
OSTCBCur->OSTCBMsg = (void *)0; /* 有,清除已接收的消息 */
OSTCBCur->OSTCBStat = OS_STAT_RDY;
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* 不在等待事件 拆除TCB與ECB的鏈接 */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (msg); /* 返回接收的消息 */
}
OS_EventTO(pevent); /* 延時到,就緒任務 */
OS_EXIT_CRITICAL();
*err = OS_TIMEOUT; /* 顯示延時發生 */
return ((void *)0); /* 返回空消息 */
}
/*$PAGE*/
/*
*********************************************************************************************************
* 發送消息到隊列
*
* 函數描述: 該函數發送一個消息到隊列
*
* 輸入參數 : pevent 指向帶有期望隊列的ECB的指針
*
* msg 指向發送消息的指針. 不要發送空指針
*
* 返回值 : OS_NO_ERR 調用成功,消息被發送
* OS_Q_FULL 隊列由于滿不接收更多的消息
* OS_ERR_EVENT_TYPE 沒有傳遞一個指向隊列的指針
* OS_ERR_PEVENT_NULL 'pevent' 是一個空指針
* OS_ERR_POST_NULL_PTR 發送一個空指針
*********************************************************************************************************
*/
#if OS_Q_POST_EN > 0
INT8U OSQPost (OS_EVENT *pevent, void *msg)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
OS_Q *pq;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 無效的 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (msg == (void *)0)
{ /* 沒有發送一個空指針 */
return (OS_ERR_POST_NULL_PTR);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q)
{ /* 無效的事件塊類型 */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00)
{ /* 看是否任務正在等待消息隊列 */
OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* 就緒等待事件的最高優先級的任務,在TCB中放消息 */
OS_EXIT_CRITICAL();
OS_Sched(); /* 尋找HPT就緒運行 */
return (OS_NO_ERR);
}
pq = (OS_Q *)pevent->OSEventPtr; /* 指向QCB */
if (pq->OSQEntries >= pq->OSQSize)
{ /* 檢查消息是否已滿? */
OS_EXIT_CRITICAL();
return (OS_Q_FULL);
}
*pq->OSQIn++ = msg; /* 把消息插入隊列 */
pq->OSQEntries++; /* 增加隊列中的消息數 */
if (pq->OSQIn == pq->OSQEnd)
{ /* 邊界檢查 */
pq->OSQIn = pq->OSQStart;
}
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 發送消息到隊列前端
*
* 函數描述: 該函數發送消息到隊列,但是不象OSQPost(), 消息被放在隊列前端而不是末尾。實現后進先出。
*
* 輸入參數 : pevent 指向帶有期望隊列的ECB的指針
*
* msg 指向發送消息的指針. 不要發送空指針
*
* 返回值 : OS_NO_ERR 調用成功,消息被發送
* OS_Q_FULL 隊列由于滿不接收更多的消息
* OS_ERR_EVENT_TYPE 沒有傳遞一個指向隊列的指針
* OS_ERR_PEVENT_NULL 'pevent' 是一個空指針
* OS_ERR_POST_NULL_PTR 發送一個空指針
*********************************************************************************************************
*/
#if OS_Q_POST_FRONT_EN > 0
INT8U OSQPostFront (OS_EVENT *pevent, void *msg)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
OS_Q *pq;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 無效的 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (msg == (void *)0)
{ /* 沒有發送一個空指針 */
return (OS_ERR_POST_NULL_PTR);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q)
{ /* 無效的事件塊類型 */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00)
{ /* 看是否任務正在等待消息隊列 */
OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* 就緒等待事件的最高優先級的任務,在TCB中放消息 */
OS_EXIT_CRITICAL();
OS_Sched(); /* 尋找HPT就緒運行 */
return (OS_NO_ERR);
}
pq = (OS_Q *)pevent->OSEventPtr; /* 指向QCB */
if (pq->OSQEntries >= pq->OSQSize)
{ /* 檢查消息是否已滿? */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -