📄 os_q.c
字号:
} pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ OS_EXIT_CRITICAL(); return (OS_Q_FULL); } if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */ pq->OSQOut = pq->OSQEnd; } pq->OSQOut--; *pq->OSQOut = msg; /* Insert message into queue */ pq->OSQEntries++; /* Update the nbr of entries in the queue */ OS_EXIT_CRITICAL(); return (OS_NO_ERR);}#endif/*$PAGE*//*********************************************************************************************************** POST MESSAGE TO A QUEUE** Description: This function sends a message to a queue. This call has been added to reduce code size* since it can replace both OSQPost() and OSQPostFront(). Also, this function adds the * capability to broadcast a message to ALL tasks waiting on the message queue.** Arguments : pevent is a pointer to the event control block associated with the desired queue** msg is a pointer to the message to send. You MUST NOT send a NULL pointer.** opt determines the type of POST performed:* OS_POST_OPT_NONE POST to a single waiting task * (Identical to OSQPost())* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the queue* OS_POST_OPT_FRONT POST as LIFO (Simulates OSQPostFront())** Below is a list of ALL the possible combination of these flags:** 1) OS_POST_OPT_NONE* identical to OSQPost()** 2) OS_POST_OPT_FRONT * identical to OSQPostFront()** 3) OS_POST_OPT_BROADCAST* identical to OSQPost() but will broadcast 'msg' to ALL waiting tasks** 4) OS_POST_OPT_FRONT + OS_POST_OPT_BROADCAST is identical to* OSQPostFront() except that will broadcast 'msg' to ALL waiting tasks** Returns : OS_NO_ERR The call was successful and the message was sent* OS_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_POST_NULL_PTR If you are attempting to post a NULL pointer** Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the * interrupt disable time is proportional to the number of tasks waiting on the queue.**********************************************************************************************************/#if OS_Q_POST_OPT_EN > 0INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt){#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif OS_Q *pq;#if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ return (OS_ERR_PEVENT_NULL); } if (msg == (void *)0) { /* Make sure we are not posting a NULL pointer */ return (OS_ERR_POST_NULL_PTR); } if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); }#endif OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0x00) { /* See if any task pending on queue */ if ((opt & OS_POST_OPT_BROADCAST) != 0x00) { /* Do we need to post msg to ALL waiting tasks ? */ while (pevent->OSEventGrp != 0x00) { /* Yes, Post to ALL tasks waiting on queue */ OS_EventTaskRdy(pevent, msg, OS_STAT_Q); } } else { OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* No, Post to HPT waiting on queue */ } OS_EXIT_CRITICAL(); OS_Sched(); /* Find highest priority task ready to run */ return (OS_NO_ERR); } pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ OS_EXIT_CRITICAL(); return (OS_Q_FULL); } if ((opt & OS_POST_OPT_FRONT) != 0x00) { /* Do we post to the FRONT of the queue? */ if (pq->OSQOut == pq->OSQStart) { /* Yes, Post as LIFO, Wrap OUT pointer if we ... */ pq->OSQOut = pq->OSQEnd; /* ... are at the 1st queue entry */ } pq->OSQOut--; *pq->OSQOut = msg; /* Insert message into queue */ } else { /* No, Post as FIFO */ *pq->OSQIn++ = msg; /* Insert message into queue */ if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ pq->OSQIn = pq->OSQStart; } } pq->OSQEntries++; /* Update the nbr of entries in the queue */ OS_EXIT_CRITICAL(); return (OS_NO_ERR);}#endif/*$PAGE*//*********************************************************************************************************** QUERY A MESSAGE QUEUE** Description: This function obtains information about a message queue.** Arguments : pevent is a pointer to the event control block associated with the desired queue** pdata is a pointer to a structure that will contain information about the message* queue.** 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 queue.* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer**********************************************************************************************************/#if OS_Q_QUERY_EN > 0INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata){#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif OS_Q *pq; INT8U *psrc; INT8U *pdest;#if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ return (OS_ERR_PEVENT_NULL); } if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); }#endif OS_ENTER_CRITICAL(); pdata->OSEventGrp = pevent->OSEventGrp; /* Copy message queue wait list */ 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; /* Get next message to return if available */ } 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*//*********************************************************************************************************** QUEUE MODULE INITIALIZATION** Description : This function is called by uC/OS-II to initialize the message queue module. Your* application MUST NOT call this function.** Arguments : none** Returns : none** Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.**********************************************************************************************************/void OS_QInit (void){#if OS_MAX_QS == 1 OSQFreeList = &OSQTbl[0]; /* Only ONE queue! */ 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++) { /* Init. list of free QUEUE control blocks */ 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 + -