OS_Q.C(全)
- 從隊(duì)列中接收消息*OSQAccept (OS_EVENT ?*pevent,INT8U *perr)
- 建立一個(gè)消息隊(duì)列OS_EVENT ?*OSQCreate (void ?**start,INT16U size)
- 刪除消息隊(duì)列OS_EVENT *OSQDel (OS_EVENT *pevent,INT8U opt,INT8U ?perr)
- 清空消息隊(duì)列OSQFlush (OS_EVENT *pevent)
- 任務(wù)等待消息隊(duì)列中的消息*OSQPend (OS_EVENT ?*pevent,INT32U timeout,INT8U ?*perr)
- 取消等待消息的任務(wù)OSQPendAbort (OS_EVENT *pevent,INT8U opt,INT8U ? ? *perr)
- 給隊(duì)列發(fā)送消息INT8U OSQPost (OS_EVENT *pevent,void *pmsg)
- 通過(guò)消息隊(duì)列向任務(wù)發(fā)送消息INT8U ?OSQPostFront (OS_EVENT ?*pevent,void *pmsg)
- 消息隊(duì)列向任務(wù)發(fā)消息(允許廣播消息)INT8U ?OSQPostOpt (OS_EVENT ?*pevent,?void *pmsg,INT8U opt)
- 獲得消息隊(duì)列的信息INT8U ?OSQQuery (OS_EVENT ?*pevent,OS_Q_DATA *p_q_data)
- 隊(duì)列單元初始化?OS_QInit (void)
從隊(duì)列中接收消息*OSQAccept (OS_EVENT ?*pevent,INT8U *perr):
建立一個(gè)消息隊(duì)列OS_EVENT ?*OSQCreate (void ?**start,INT16U ?size):
/*$PAGE*/ /*2018/2/22 ********************************************************************************************************* * CREATE A MESSAGE QUEUE * 建立一個(gè)消息隊(duì)列 * Description: This function creates a message queue if free event control blocks are available. *描述:該功能是當(dāng)有空閑的事件控制塊時(shí)創(chuàng)建一個(gè)消息隊(duì)列。 * Arguments : start is a pointer to the base address of the message queue storage area. The * storage area MUST be declared as an array of pointers to 'void' as follows * void *MessageStorage[size] *參數(shù): --start:指向消息隊(duì)列存儲(chǔ)區(qū)域底部的指針。該存儲(chǔ)區(qū)域必須被聲明為void型指針數(shù)組。形式如下;void *MessageStorage[size] * size is the number of elements in the storage area * --size:該存儲(chǔ)區(qū)的成員數(shù)量。 * Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the * created queue * == (OS_EVENT *)0 if no event control blocks were available or an error was detected返回值:!= (OS_EVENT *)0:指向事件控制塊的指針。== (OS_EVENT *)0:如果事件控制塊不可獲得或者有其他錯(cuò)誤信息,返回空。 ********************************************************************************************************* */OS_EVENT *OSQCreate (void **start,INT16U size) {OS_EVENT *pevent;/*指向隊(duì)列對(duì)應(yīng)的事件控制塊*/OS_Q *pq;/*指向隊(duì)列控制塊的指針*/#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICAL_IEC61508if (OSSafetyCriticalStartFlag == OS_TRUE) {OS_SAFETY_CRITICAL_EXCEPTION();}#endifif (OSIntNesting > 0u) { return ((OS_EVENT *)0); }OS_ENTER_CRITICAL();/*進(jìn)入中斷*/pevent = OSEventFreeList;/* 得到空閑的事件控制塊*/if (OSEventFreeList != (OS_EVENT *)0) /*如果有可獲得事件控制塊*/{ OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;/*更新空閑事件列表*/}OS_EXIT_CRITICAL();/*退出中斷*/if (pevent != (OS_EVENT *)0) /*如果獲得了事件控制塊*/{ OS_ENTER_CRITICAL();/*進(jìn)入中斷*/pq = OSQFreeList; /*獲得空閑的隊(duì)列控制塊 */if (pq != (OS_Q *)0) /*如果獲得了空閑的隊(duì)列控制塊*/{ OSQFreeList = OSQFreeList->OSQPtr; /*調(diào)整空閑列表指針到下一個(gè)*/OS_EXIT_CRITICAL();/*退出中斷*/pq->OSQStart = start;/*初始化隊(duì)列 頭指針*/pq->OSQEnd = &start[size];/*尾指針*/pq->OSQIn = start;/*進(jìn)入的指針*/pq->OSQOut = start;/*出去的指針*/pq->OSQSize = size;/*隊(duì)列大小*/pq->OSQEntries = 0u;/*隊(duì)列內(nèi)的成員數(shù)初始化為0*/pevent->OSEventType = OS_EVENT_TYPE_Q;/*將事件控制塊類(lèi)型設(shè)置為隊(duì)列類(lèi)型*/pevent->OSEventCnt = 0u;pevent->OSEventPtr = pq;/*事件控制塊指針指向隊(duì)列*/#if OS_EVENT_NAME_EN > 0upevent->OSEventName = (INT8U *)(void *)"?";/*名字初始化為未命名*/#endifOS_EventWaitListInit(pevent);/*初始化等待列表 */} else/*如果沒(méi)有獲得空閑的隊(duì)列控制塊*/{pevent->OSEventPtr = (void *)OSEventFreeList; /*將事件控制塊還給事件空閑列表*/OSEventFreeList = pevent;OS_EXIT_CRITICAL();/*退出中斷*/pevent = (OS_EVENT *)0;}}return (pevent); }刪除消息隊(duì)列OS_EVENT ?*OSQDel (OS_EVENT ?*pevent,INT8U opt,INT8U *perr):
/*$PAGE*/ /*2018/2/22 ********************************************************************************************************* * DELETE A MESSAGE QUEUE * 刪除消息隊(duì)列 * Description: This function deletes a message queue and readies all tasks pending on the queue. *描述:該功能是刪除消息隊(duì)列并且將所有掛起的任務(wù)設(shè)置為就緒態(tài)。 * Arguments : pevent is a pointer to the event control block associated with the desired * queue. *參數(shù): --pevent:指向與隊(duì)列對(duì)應(yīng)的事件控制塊的指針 * opt determines delete options as follows: * opt == OS_DEL_NO_PEND Delete the queue ONLY if no task pending * opt == OS_DEL_ALWAYS Deletes the queue even if tasks are waiting. * In this case, all the tasks pending will be readied. * --opt:選擇刪除方式:opt == OS_DEL_NO_PEND:沒(méi)有任務(wù)掛起時(shí)才能刪除。opt == OS_DEL_ALWAYS:即使有任務(wù)正在等待也將隊(duì)列刪除。在這種情況下,所有掛起的任務(wù)都轉(zhuǎn)為就緒態(tài)。 * perr is a pointer to an error code that can contain one of the following values: * OS_ERR_NONE The call was successful and the queue was deleted * OS_ERR_DEL_ISR If you tried to delete the queue from an ISR * OS_ERR_INVALID_OPT An invalid option was specified * OS_ERR_TASK_WAITING One or more tasks were waiting on the queue * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. * --perr:指向錯(cuò)誤碼的指針:OS_ERR_NONE:調(diào)用成功,隊(duì)列被刪除;OS_ERR_DEL_ISR:從中斷服務(wù)子程序中刪除隊(duì)列;OS_ERR_INVALID_OPT:選擇無(wú)效;OS_ERR_TASK_WAITING:一個(gè)或者多個(gè)任務(wù)正在等待該隊(duì)列OS_ERR_EVENT_TYPE:沒(méi)有指向隊(duì)列的指針OS_ERR_PEVENT_NULL:pevent為空指針 * Returns : pevent upon error * (OS_EVENT *)0 if the queue was successfully deleted. *返回值:如果成功刪除隊(duì)列,返回值為空,如果沒(méi)有成功刪除,返回pevent。 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of * the queue MUST check the return code of OSQPend(). * 2) OSQAccept() callers will not know that the intended queue has been deleted unless * they check 'pevent' to see that it's a NULL pointer. * 3) This call can potentially disable interrupts for a long time. The interrupt disable * time is directly proportional to the number of tasks waiting on the queue. * 4) Because ALL tasks pending on the queue will be readied, you MUST be careful in * applications where the queue is used for mutual exclusion because the resource(s) * will no longer be guarded by the queue. * 5) If the storage for the message queue was allocated dynamically (i.e. using a malloc() * type call) then your application MUST release the memory storage by call the counterpart * call of the dynamic allocation scheme used. If the queue storage was created statically * then, the storage can be reused. 注釋:1)該函數(shù)一定要小心使用。等待隊(duì)列的任務(wù)要檢查OSQPend()的返回值。2)調(diào)用OSQAccept()的任務(wù)無(wú)法得知隊(duì)列是否被刪除,除非檢測(cè)pevent是否為空指針。3)該函數(shù)調(diào)用會(huì)中斷很長(zhǎng)時(shí)間,中斷的時(shí)間長(zhǎng)短與等待任務(wù)的數(shù)量成正比。4)因?yàn)樵趧h除后所有的任務(wù)都會(huì)從等待狀態(tài)轉(zhuǎn)為就緒態(tài)。所以如果隊(duì)列中的消息為互斥量,調(diào)用需要小心。因?yàn)榇藭r(shí)資源是開(kāi)放的。5)如果消息隊(duì)列內(nèi)存是動(dòng)態(tài)分配的,你的應(yīng)用程序一定要通過(guò)對(duì)應(yīng)的程序釋放存儲(chǔ)空間。如果空間是靜態(tài)的,該空間可以被重新使用。 ********************************************************************************************************* */#if OS_Q_DEL_EN > 0u OS_EVENT *OSQDel (OS_EVENT *pevent,INT8U opt,INT8U *perr) {BOOLEAN tasks_waiting;/*布爾型變量標(biāo)志是否有任務(wù)正在等待*/OS_EVENT *pevent_return;/*返回值*/OS_Q *pq;/*指向隊(duì)列的指針*/#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0) {OS_SAFETY_CRITICAL_EXCEPTION();}#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { *perr = OS_ERR_PEVENT_NULL;return (pevent);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q) { *perr = OS_ERR_EVENT_TYPE;return (pevent);}if (OSIntNesting > 0u) { *perr = OS_ERR_DEL_ISR; return (pevent);}OS_ENTER_CRITICAL();/*進(jìn)入中斷*/if (pevent->OSEventGrp != 0u)/*有任務(wù)正在等待隊(duì)列*/{ tasks_waiting = OS_TRUE; /* 將等待標(biāo)志設(shè)置為true */}else/*沒(méi)有任務(wù)等待隊(duì)列*/{tasks_waiting = OS_FALSE;/* 將等待標(biāo)志設(shè)置為false*/}switch (opt) /*選擇刪除方式并進(jìn)行對(duì)應(yīng)操作*/{case OS_DEL_NO_PEND: /* 無(wú)掛起才刪除*/if (tasks_waiting == OS_FALSE)/*無(wú)任務(wù)等待*/{#if OS_EVENT_NAME_EN > 0upevent->OSEventName = (INT8U *)(void *)"?";/*名字初始化為未命名*/#endif/*將隊(duì)列控制塊還給空閑隊(duì)列列表*/pq = (OS_Q *)pevent->OSEventPtr; pq->OSQPtr = OSQFreeList;OSQFreeList = pq;pevent->OSEventType = OS_EVENT_TYPE_UNUSED;/*將事件類(lèi)型設(shè)置為未使用類(lèi)型*/pevent->OSEventPtr = OSEventFreeList; /*將事件控制塊還給事件空閑列表*/pevent->OSEventCnt = 0u;OSEventFreeList = pevent; /*更新空閑事件列表*/ OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_NONE;pevent_return = (OS_EVENT *)0; /* 隊(duì)列已經(jīng)被刪除,返回空*/}else/*有任務(wù)正在等待*/{OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_TASK_WAITING;/*設(shè)置錯(cuò)誤類(lèi)型*/pevent_return = pevent;}break;case OS_DEL_ALWAYS: /*有掛起也刪除*/while (pevent->OSEventGrp != 0u)/*將所有等待的任務(wù)轉(zhuǎn)為就緒態(tài)*/{ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_OK);}#if OS_EVENT_NAME_EN > 0upevent->OSEventName = (INT8U *)(void *)"?";#endifpq = (OS_Q *)pevent->OSEventPtr; /*同上*/pq->OSQPtr = OSQFreeList;OSQFreeList = pq;pevent->OSEventType = OS_EVENT_TYPE_UNUSED;pevent->OSEventPtr = OSEventFreeList; pevent->OSEventCnt = 0u;OSEventFreeList = pevent; OS_EXIT_CRITICAL();if (tasks_waiting == OS_TRUE) /*有任務(wù)等待時(shí)才可能調(diào)度*/{ OS_Sched(); /*找到最高優(yōu)先級(jí)任務(wù)并進(jìn)行調(diào)度 */}*perr = OS_ERR_NONE;pevent_return = (OS_EVENT *)0; /*隊(duì)列被刪除,返回值為空 */break;default:/*兩種選擇都不是*/OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_INVALID_OPT;/*設(shè)置錯(cuò)誤類(lèi)型*/pevent_return = pevent;break;}return (pevent_return); } #endif清空消息隊(duì)列并且忽略發(fā)送往隊(duì)列的所有消息OSQFlush (OS_EVENT *pevent):
/*$PAGE*/ /*2018/2/22 ********************************************************************************************************* * FLUSH QUEUE * 清空消息隊(duì)列并且忽略發(fā)送往隊(duì)列的所有消息 * Description : This function is used to flush the contents of the message queue. *描述:該功能用來(lái)清空消息隊(duì)列的內(nèi)容。 * Arguments : none *參數(shù):無(wú) * Returns : OS_ERR_NONE upon success * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer *返回值:OS_ERR_NONE;成功調(diào)用。OS_ERR_EVENT_TYPE:沒(méi)有指向隊(duì)列的指針。OS_ERR_PEVENT_NULL:pevent為空指針。 * WARNING : You should use this function with great care because, when to flush the queue, you LOOSE * the references to what the queue entries are pointing to and thus, you could cause * 'memory leaks'. In other words, the data you are pointing to that's being referenced * by the queue entries should, most likely, need to be de-allocated (i.e. freed).警告:需要特別小心使用該函數(shù),因?yàn)楫?dāng)清空隊(duì)列的時(shí)候,會(huì)釋放隊(duì)列中成員指向的一些內(nèi)容,容易造成內(nèi)存泄漏。換句話(huà)說(shuō),在使用完隊(duì)列后應(yīng)該動(dòng)態(tài)釋放空間。 ********************************************************************************************************* */#if OS_Q_FLUSH_EN > 0u INT8U OSQFlush (OS_EVENT *pevent) {OS_Q *pq;/*指向隊(duì)列的指針*/#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { return (OS_ERR_PEVENT_NULL);}if (pevent->OSEventType != OS_EVENT_TYPE_Q) { return (OS_ERR_EVENT_TYPE);}#endifOS_ENTER_CRITICAL();/*進(jìn)入中斷*/pq = (OS_Q *)pevent->OSEventPtr; /* pq指向隊(duì)列存儲(chǔ)結(jié)構(gòu) */pq->OSQIn = pq->OSQStart;/*進(jìn)入隊(duì)列指針*/pq->OSQOut = pq->OSQStart;/*出隊(duì)列指針,首尾指向該隊(duì)列的開(kāi)始*/pq->OSQEntries = 0u;OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_NONE); } #endif任務(wù)等待消息隊(duì)列中的消息*OSQPend (OS_EVENT ?*pevent,INT32U timeout,INT8U *perr):
/*$PAGE*/ /*2018/2/22 ********************************************************************************************************* * PEND ON A QUEUE FOR A MESSAGE * ????任務(wù)等待消息隊(duì)列中的消息 * Description: This function waits for a message to be sent to a queue *描述:該功能是等待消息隊(duì)列中的消息 * Arguments : pevent is a pointer to the event control block associated with the desired queue *參數(shù): --pevent:指向事件控制塊的指針 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will * wait for a message to arrive at the queue up to the amount of time * specified by this argument. If you specify 0, however, your task will wait * forever at the specified queue or, until a message arrives. * --timeout:可選擇的時(shí)間片。如果不為0,任務(wù)將會(huì)等待消息,到時(shí)間到達(dá)了設(shè)定的時(shí)間后不再等待。如果是0,任務(wù)就會(huì)一直等待,知道有消息到來(lái)。 * perr is a pointer to where an error message will be deposited. Possible error * messages are: * OS_ERR_NONE The call was successful and your task received a message. * OS_ERR_TIMEOUT A message was not received within the specified 'timeout'. * OS_ERR_PEND_ABORT The wait on the queue was aborted. * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer * OS_ERR_PEND_ISR If you called this function from an ISR and the result * would lead to a suspension. * OS_ERR_PEND_LOCKED If you called this function with the scheduler is locked * --perr:指向錯(cuò)誤碼的指針:‘OS_ERR_NONE:成功調(diào)用,任務(wù)收到消息。OS_ERR_TIMEOUT:超時(shí)錯(cuò)。OS_ERR_PEND_ABORT:任務(wù)被取消。OS_ERR_EVENT_TYPE:沒(méi)有指向隊(duì)列的指針。OS_ERR_PEVENT_NULL:pevent為空指針。OS_ERR_PEND_ISR:從中斷服務(wù)子程序中調(diào)用該功能。OS_ERR_PEND_LOCKED:調(diào)度程序被鎖 * Returns : != (void *)0 is a pointer to the message received * == (void *)0 if you received a NULL pointer message or, * if no message was received or, * if 'pevent' is a NULL pointer or, * if you didn't pass a pointer to a queue. *返回值:!= (void *)0:指向收到的消息== (void *)0:以下幾種情況返回值為空:指向消息的指針為空;沒(méi)有收到消息;pevent為空指針;沒(méi)有指向隊(duì)列的指針。 * Note(s) : As of V2.60, this function allows you to receive NULL pointer messages. 注釋:對(duì)于V2.60版本,該功能允許收到空指針消息。 ********************************************************************************************************* */void *OSQPend (OS_EVENT *pevent,INT32U timeout,INT8U *perr) {void *pmsg;/*指向消息的指針*/OS_Q *pq;/*指向隊(duì)列控制塊的指針*/#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0) {OS_SAFETY_CRITICAL_EXCEPTION();}#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { *perr = OS_ERR_PEVENT_NULL;return ((void *)0);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q) {*perr = OS_ERR_EVENT_TYPE;return ((void *)0);}if (OSIntNesting > 0u) { *perr = OS_ERR_PEND_ISR; return ((void *)0);}if (OSLockNesting > 0u) { *perr = OS_ERR_PEND_LOCKED; return ((void *)0);}OS_ENTER_CRITICAL();/*進(jìn)入中斷*/pq = (OS_Q *)pevent->OSEventPtr;/*指向隊(duì)列控制塊的指針*/if (pq->OSQEntries > 0u)/*在隊(duì)列中有消息*/{ pmsg = *pq->OSQOut++; /*從隊(duì)列中取出最早進(jìn)入的消息 */pq->OSQEntries--; /*更新隊(duì)列的數(shù)量*/if (pq->OSQOut == pq->OSQEnd) /*隊(duì)列中沒(méi)有消息了*/{ pq->OSQOut = pq->OSQStart;/*將出隊(duì)列的指針指向隊(duì)列首*/}OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_NONE;return (pmsg);/* 返回收到的消息*/}/*隊(duì)列中沒(méi)有消息*/OSTCBCur->OSTCBStat |= OS_STAT_Q;/*將事件進(jìn)入睡眠狀態(tài),由消息隊(duì)列喚醒*/OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;OSTCBCur->OSTCBDly = timeout; /*等待時(shí)間置入任務(wù)控制中*/OS_EventTaskWait(pevent);/*使任務(wù)進(jìn)入等待消息隊(duì)列狀態(tài)*/OS_EXIT_CRITICAL();/*退出中斷*/OS_Sched(); /* 找到最高優(yōu)先級(jí)任務(wù)并調(diào)度 */OS_ENTER_CRITICAL();/*進(jìn)入中斷*/switch (OSTCBCur->OSTCBStatPend) /*看掛起狀態(tài)是超時(shí)還是被取消*/{ case OS_STAT_PEND_OK:/*得到消息*/pmsg = OSTCBCur->OSTCBMsg;*perr = OS_ERR_NONE;break;case OS_STAT_PEND_ABORT:/*任務(wù)被取消*/pmsg = (void *)0;*perr = OS_ERR_PEND_ABORT; break;case OS_STAT_PEND_TO:/*超時(shí)*/default:OS_EventTaskRemove(OSTCBCur, pevent);pmsg = (void *)0;*perr = OS_ERR_TIMEOUT; break;}OSTCBCur->OSTCBStat = OS_STAT_RDY;/*將任務(wù)狀態(tài)設(shè)置為就緒態(tài)*/OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* 清除掛起狀態(tài)*/OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;/* 清除事件指針 */#if (OS_EVENT_MULTI_EN > 0u)OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;#endifOSTCBCur->OSTCBMsg = (void *)0; /*清除收到的消息*/OS_EXIT_CRITICAL();/*退出中斷*/return (pmsg); /* 返回收到的消息*/ }取消等待的任務(wù)INT8U ?OSQPendAbort (OS_EVENT ?*pevent,INT8U ?opt,INT8U ?*perr):
/*$PAGE*/ /*2018/2/22 ********************************************************************************************************* * ABORT WAITING ON A MESSAGE QUEUE * 取消等待消息的任務(wù) * Description: This function aborts & readies any tasks currently waiting on a queue. This function * should be used to fault-abort the wait on the queue, rather than to normally signal * the queue via OSQPost(), OSQPostFront() or OSQPostOpt(). *描述:該功能是將所有等待隊(duì)列消息的任務(wù)取消并轉(zhuǎn)為就緒態(tài)。該功能是默認(rèn)取消等待,而不是通過(guò)OSQPost(),OSQPostFront()或者OSQPostOpt()通知隊(duì)列。 * Arguments : pevent is a pointer to the event control block associated with the desired queue. *參數(shù): --pevent:指向隊(duì)列對(duì)應(yīng)的事件控制塊的指針。 * opt determines the type of ABORT performed: * OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the * queue * OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the * queue * --opt:取消的方式:OS_PEND_OPT_NONE:只取消最高優(yōu)先級(jí)任務(wù);OS_PEND_OPT_BROADCAST:取消所有任務(wù)。 * perr is a pointer to where an error message will be deposited. Possible error * messages are: * OS_ERR_NONE No tasks were waiting on the queue. * OS_ERR_PEND_ABORT At least one task waiting on the queue was readied * and informed of the aborted wait; check return value * for the number of tasks whose wait on the queue * was aborted. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.--perr:指向錯(cuò)誤碼的指針:OS_ERR_NONE:沒(méi)有任務(wù)等待隊(duì)列消息。OS_ERR_PEND_ABORT:至少一個(gè)等待隊(duì)列消息的任務(wù)是就緒的并且被取消等待;檢查任務(wù)數(shù)的返回值。OS_ERR_EVENT_TYPE:沒(méi)有指向隊(duì)列的指針;OS_ERR_PEVENT_NULL:pevent為空指針。 * Returns : == 0 if no tasks were waiting on the queue, or upon error. * > 0 if one or more tasks waiting on the queue are now readied and informed.返回值:== 0:沒(méi)有任務(wù)等待隊(duì)列。> 0:一個(gè)或多個(gè)等待隊(duì)列的任務(wù)為就緒態(tài)并且被取消。 ********************************************************************************************************* */#if OS_Q_PEND_ABORT_EN > 0u INT8U OSQPendAbort (OS_EVENT *pevent,INT8U opt,INT8U *perr) {INT8U nbr_tasks;/*等待的任務(wù)數(shù)目*/#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0) {OS_SAFETY_CRITICAL_EXCEPTION();}#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { *perr = OS_ERR_PEVENT_NULL;return (0u);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q) { *perr = OS_ERR_EVENT_TYPE;return (0u);}OS_ENTER_CRITICAL();/*進(jìn)入中斷*/if (pevent->OSEventGrp != 0u) /*有任務(wù)正在等待*/{ nbr_tasks = 0u;/*數(shù)量先初始化為0*/switch (opt) /*選擇取消的類(lèi)型*/{case OS_PEND_OPT_BROADCAST: /*取消所有的任務(wù)*/while (pevent->OSEventGrp != 0u){ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT);nbr_tasks++;}break;case OS_PEND_OPT_NONE:/*只取消優(yōu)先級(jí)最高的那個(gè)任務(wù)*/default: /*取消任務(wù)就是不讓該任務(wù)處于等待狀態(tài),轉(zhuǎn)為就緒態(tài)*/(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT);nbr_tasks++;break;}OS_EXIT_CRITICAL();/*退出中斷*/OS_Sched(); /*找到最高優(yōu)先級(jí)任務(wù)并調(diào)度*/*perr = OS_ERR_PEND_ABORT;return (nbr_tasks);/*返回任務(wù)的數(shù)目*/}OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_NONE;return (0u); /*如果沒(méi)有任務(wù)等待的話(huà),返回0*/ } #endif該函數(shù)最后是返回取消的任務(wù)數(shù)目。如果有任務(wù)正在等待隊(duì)列消息,取消后返回任務(wù)數(shù)量。如果沒(méi)有任務(wù)等待,返回0。取消等待的任務(wù)實(shí)際上就是將任務(wù)從等待狀態(tài)轉(zhuǎn)為就緒態(tài)。
給隊(duì)列發(fā)送消息INT8U ?OSQPost (OS_EVENT ?*pevent,void ? *pmsg):
通過(guò)消息隊(duì)列向任務(wù)發(fā)送消息INT8U ?OSQPostFront (OS_EVENT ?*pevent,?void *pmsg):
/*$PAGE*/ /*2018/2/22 ********************************************************************************************************* * POST MESSAGE TO THE FRONT OF A QUEUE * 通過(guò)消息隊(duì)列向任務(wù)發(fā)送消息 * Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at * the front instead of the end of the queue. Using OSQPostFront() allows you to send * 'priority' messages. *描述:該功能是給隊(duì)列發(fā)送消息,但是與OSQPost()不同,這個(gè)消息是發(fā)送給隊(duì)列的開(kāi)始,而不是結(jié)尾。OSQPostFront()允許你發(fā)送優(yōu)先級(jí)高的消息。(消息隊(duì)列按照后入先出(LIFO)的方式工作, 而不是先入先出(FIFO)) * Arguments : pevent is a pointer to the event control block associated with the desired queue *參數(shù): --pevent:指向事件控制塊的指針。 * pmsg is a pointer to the message to send. * --pmsg:指向要發(fā)送的消息的指針。 * Returns : OS_ERR_NONE The call was successful and the message was sent * OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer *返回值:OS_ERR_NONE:調(diào)用成功,消息被發(fā)出。OS_ERR_Q_FULL:隊(duì)列已滿(mǎn),不能接收消息。OS_ERR_EVENT_TYPE:沒(méi)有指向隊(duì)列的指針。OS_ERR_PEVENT_NULL:pevent為空指針。 * Note(s) : As of V2.60, this function allows you to send NULL pointer messages.注釋:在V2.60版本中,該功能允許發(fā)送空指針消息。 ********************************************************************************************************* */#if OS_Q_POST_FRONT_EN > 0u INT8U OSQPostFront (OS_EVENT *pevent,void *pmsg) {OS_Q *pq;/*指向消息隊(duì)列的指針*/#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { return (OS_ERR_PEVENT_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q) { return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();/*進(jìn)入中斷*/if (pevent->OSEventGrp != 0u)/*有任務(wù)正在等待隊(duì)列消息*/{ /*將最高優(yōu)先級(jí)任務(wù)轉(zhuǎn)為就緒態(tài)*/(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);OS_EXIT_CRITICAL();/*退出中斷*/OS_Sched(); /* 找到最高優(yōu)先級(jí)任務(wù)并調(diào)度 */return (OS_ERR_NONE);}/*沒(méi)有任務(wù)等待消息*/pq = (OS_Q *)pevent->OSEventPtr; /* 指向隊(duì)列控制塊的指針*/if (pq->OSQEntries >= pq->OSQSize)/*隊(duì)列已滿(mǎn)*/{ OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_Q_FULL);}if (pq->OSQOut == pq->OSQStart) /*當(dāng)插入指針=指針的起始地址(指針)*/{ pq->OSQOut = pq->OSQEnd;/*插入指針跳轉(zhuǎn)到最后地址(指針)*/}pq->OSQOut--;/*插入指針減1*/*pq->OSQOut = pmsg; /*插入當(dāng)前消息(內(nèi)容) */pq->OSQEntries++;/* 消息數(shù)加1 */OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_NONE); } #endif該函數(shù)與上一個(gè)函數(shù)十分相似,不同點(diǎn)在于這個(gè)函數(shù)是將消息插入到隊(duì)列的最前端。這樣就讓隊(duì)列的進(jìn)出方式從FIFO(先進(jìn)先出)變成了LIFO(后進(jìn)先出)。
消息隊(duì)列向任務(wù)發(fā)消息(允許廣播消息)INT8U ?OSQPostOpt (OS_EVENT ?*pevent,void *pmsg,INT8U ?opt):
獲得消息隊(duì)列的信息INT8U ?OSQQuery (OS_EVENT ?*pevent,OS_Q_DATA *p_q_data):
/*$PAGE*/ /*2018/2/22 ********************************************************************************************************* * QUERY A MESSAGE QUEUE * 獲得消息隊(duì)列的信息 * Description: This function obtains information about a message queue. *描述:該功能是獲得消息隊(duì)列的信息。 * Arguments : pevent is a pointer to the event control block associated with the desired queue *參數(shù): --pevent:指向事件控制塊的指針。 * p_q_data is a pointer to a structure that will contain information about the message queue. * --p_q_data:指向結(jié)構(gòu)體的指針,該指針包含消息隊(duì)列的信息。 * Returns : OS_ERR_NONE The call was successful and the message was sent * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer * OS_ERR_PDATA_NULL If 'p_q_data' is a NULL pointer返回值:OS_ERR_NONE:調(diào)用成功,消息被發(fā)出。OS_ERR_EVENT_TYPE:對(duì)象不是隊(duì)列。OS_ERR_PEVENT_NULL:pevent為空指針。OS_ERR_PDATA_NULL:p_q_data為空指針。 ********************************************************************************************************* */#if OS_Q_QUERY_EN > 0u INT8U OSQQuery (OS_EVENT *pevent,OS_Q_DATA *p_q_data) {OS_Q *pq;/*指向隊(duì)列的指針*/INT8U i;OS_PRIO *psrc;/*指向源*/OS_PRIO *pdest;/*指向目的*/#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { return (OS_ERR_PEVENT_NULL);}if (p_q_data == (OS_Q_DATA *)0) { return (OS_ERR_PDATA_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q) { return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();/*進(jìn)入中斷*//*將事件(消息隊(duì)列)結(jié)構(gòu)中的等待任務(wù)列表復(fù)制到pdata數(shù)據(jù)結(jié)構(gòu)中*/p_q_data->OSEventGrp = pevent->OSEventGrp; /* 等待事件的任務(wù)組中的內(nèi)容傳送到狀態(tài)數(shù)據(jù)結(jié)構(gòu)中*/psrc = &pevent->OSEventTbl[0];/*保存pevent->OSEventTbl[0]對(duì)應(yīng)的地址*/pdest = &p_q_data->OSEventTbl[0];/*保存pdata->OSEventTbl[0]對(duì)應(yīng)的地址*/for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {*pdest++ = *psrc++;/*地址指針下移一個(gè)類(lèi)型地址,獲取信號(hào)量的值*/}pq = (OS_Q *)pevent->OSEventPtr;/*將隊(duì)列事件指針保存到pq 中*/if (pq->OSQEntries > 0u)/*如果消息隊(duì)列指針中有消息*/{p_q_data->OSMsg = *pq->OSQOut; /* 將最早進(jìn)入隊(duì)列得消息復(fù)制到數(shù)據(jù)結(jié)構(gòu)的OSMsg中 */} else{p_q_data->OSMsg = (void *)0;/*如果隊(duì)列中沒(méi)有消息(包含一個(gè)空指針)*/}p_q_data->OSNMsgs = pq->OSQEntries;/*消息隊(duì)列中的消息數(shù)放置在數(shù)據(jù)結(jié)構(gòu)的(OSNMsgs)中*/p_q_data->OSQSize = pq->OSQSize;/*消息隊(duì)列中的消息隊(duì)列容量放置在數(shù)據(jù)結(jié)構(gòu)得(OSQSize)中*/OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_NONE); } #endif獲得消息隊(duì)列的信息實(shí)際上就是將隊(duì)列中的消息復(fù)制到隊(duì)列對(duì)應(yīng)的結(jié)構(gòu)體中(p_q_data)。
隊(duì)列單元初始化void ?OS_QInit (void):
總結(jié)
- 上一篇: os_mbox.c(全)
- 下一篇: os_mem.c(全)