?? os_q.c
字號:
OS_EXIT_CRITICAL();
return (OS_Q_FULL);
}
if (pq->OSQOut == pq->OSQStart)
{ /* 檢查邊界 */
pq->OSQOut = pq->OSQEnd;
}
pq->OSQOut--;
*pq->OSQOut = msg; /* 把消息插入隊列 */
pq->OSQEntries++; /* 增加隊列中的消息數 */
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 發送消息到隊列
*
* 函數描述: 該函數發送一個消息到隊列。該函數減少了代碼量因為它能代替OSQPost() 和 OSQPostFront()。同時,該
* 函數廣播發送消息給所有等待消息隊列的任務。
*
* 輸入參數 : pevent 指向帶有期望隊列的ECB的指針
*
* msg 指向發送消息的指針. 不要發送空指針
*
* opt 發送的類型:
* OS_POST_OPT_NONE 發送給單獨的等待任務 (與 OSQPost()功能一致)
* OS_POST_OPT_BROADCAST 發送給所有正等待消息隊列的任務
* OS_POST_OPT_FRONT 作為 LIFO 發送 (近似 OSQPostFront())
*
* 下面是這些標志的所有可能組合的列表:
*
* 1) OS_POST_OPT_NONE
* 與 OSQPost()一致
*
* 2) OS_POST_OPT_FRONT
* 與 OSQPostFront() 一致
*
* 3) OS_POST_OPT_BROADCAST
* 與 OSQPost()一致,而且還有廣播給所有等待的任務的消息。
*
* 4) OS_POST_OPT_FRONT + OS_POST_OPT_BROADCAST
* 與OSQPostFront()一致,而且還有廣播給所有等待的任務的消息
*
* 返回值 : OS_NO_ERR 調用成功,消息被發送
* OS_Q_FULL 隊列由于滿不接收更多的消息
* OS_ERR_EVENT_TYPE 沒有傳遞一個指向隊列的指針
* OS_ERR_PEVENT_NULL 'pevent' 是一個空指針
* OS_ERR_POST_NULL_PTR 發送一個空指針
*
* 警告 : 如果廣播發送,中斷將禁止較長時間。事實上,中斷禁止時間正比于等待消息隊列的任務的數量。
*********************************************************************************************************
*/
#if OS_Q_POST_OPT_EN > 0
INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)
{
#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) /* 看是否任務正在等待消息隊列 */
{
if ((opt & OS_POST_OPT_BROADCAST) != 0x00) /* 需要廣播發送嗎? */
{
while (pevent->OSEventGrp != 0x00)
{ /* 是,廣播發送給所有等待消息隊列的任務,在相應的TCB中放消息 */
OS_EventTaskRdy(pevent, msg, OS_STAT_Q);
}
}
else
{
OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* 不,發送給等待隊列的HPT,在其TCB中放消息 */
}
OS_EXIT_CRITICAL();
OS_Sched(); /* 尋找最高優先級就緒運行 */
return (OS_NO_ERR);
}
pq = (OS_Q *)pevent->OSEventPtr; /* 指向QCB */
if (pq->OSQEntries >= pq->OSQSize)
{ /* 檢查消息是否已滿? */
OS_EXIT_CRITICAL();
return (OS_Q_FULL);
}
if ((opt & OS_POST_OPT_FRONT) != 0x00) /* 是否發送到隊列的前端? */
{
if (pq->OSQOut == pq->OSQStart)
{ /* 是, 以后進先出發送 ... */
pq->OSQOut = pq->OSQEnd; /* 如果取隊列為頭,調整取隊列指針為尾 */
}
pq->OSQOut--;
*pq->OSQOut = msg; /* 把消息插入隊列 */
}
else
{ /* 否, 以先入先出發送 */
*pq->OSQIn++ = msg; /* 把消息插入隊列 */
if (pq->OSQIn == pq->OSQEnd)
{ /* 如果插入指針為尾,調整插入指針為頭 */
pq->OSQIn = pq->OSQStart;
}
}
pq->OSQEntries++; /* 增加隊列中的消息數 */
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 查詢消息隊列
*
* 函數描述: 該函數得到消息隊列的信息
*
* 輸入參數 : pevent 指向帶有期望隊列的ECB的指針
*
* pdata 指向包含消息隊列的數據結構的指針
*
* 返回值 : OS_NO_ERR 調用成功,消息被發送
* OS_ERR_EVENT_TYPE 從一個非消息隊列中獲取信息
* OS_ERR_PEVENT_NULL 'pevent' 是一個空指針
*********************************************************************************************************
*/
#if OS_Q_QUERY_EN > 0
INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
OS_Q *pq;
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_Q)
{ /* 無效的事件塊類型 */
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
pq = (OS_Q *)pevent->OSEventPtr;
if (pq->OSQEntries > 0)
{
pdata->OSMsg = *pq->OSQOut; /* 如果有效得到下一條消息返回 */
}
else
{
pdata->OSMsg = (void *)0;
}
pdata->OSNMsgs = pq->OSQEntries;
pdata->OSQSize = pq->OSQSize;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif /* OS_Q_QUERY_EN */
/*$PAGE*/
/*
*********************************************************************************************************
* 初始化隊列
*
* 函數描述 : 該函數由 uC/OS-II 調用初始化消息隊列。應用程序不必調用。
*
* 輸入參數 : 無
*
* 返回值 : 無
*
*********************************************************************************************************
*/
void OS_QInit (void)
{
#if OS_MAX_QS == 1
OSQFreeList = &OSQTbl[0]; /* 只有一個隊列 */
OSQFreeList->OSQPtr = (OS_Q *)0;
#endif
#if OS_MAX_QS >= 2
INT16U i;
OS_Q *pq1;
OS_Q *pq2;
pq1 = &OSQTbl[0];
pq2 = &OSQTbl[1];
for (i = 0; i < (OS_MAX_QS - 1); i++)
{ /* 初始化空余QCB */
pq1->OSQPtr = pq2;
pq1++;
pq2++;
}
pq1->OSQPtr = (OS_Q *)0;
OSQFreeList = &OSQTbl[0];
#endif
}
#endif /* OS_Q_EN */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -