📄 os_q.lst
字号:
218: * err is a pointer to where an error message will be deposited. Possible error
219: * messages are:
220: *
221: * OS_NO_ERR The call was successful and your task received a message.
222: * OS_TIMEOUT A message was not received within the specified timeout
223: * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
224: * OS_ERR_PEND_ISR If you called this function from an ISR and the result
225: * would lead to a suspension.
226: *
227: * Returns : != (void *)0 is a pointer to the message received
228: * == (void *)0 if no message was received or you didn't pass a pointer to a queue.
229: *********************************************************************************************************
230: */
231:
232: void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
233: {
234: void *msg;
235: OS_Q *pq;
236:
237:
238: OS_ENTER_CRITICAL();
239: if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
240: OS_EXIT_CRITICAL();
241: *err = OS_ERR_EVENT_TYPE;
242: return ((void *)0);
243: }
244: pq = pevent->OSEventPtr; /* Point at queue control block */
245: if (pq->OSQEntries != 0) { /* See if any messages in the queue */
246: msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
247: pq->OSQEntries--; /* Update the number of entries in the queue */
248: if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
249: pq->OSQOut = pq->OSQStart;
250: }
251: OS_EXIT_CRITICAL();
252: *err = OS_NO_ERR;
253: } else if (OSIntNesting > 0) { /* See if called from ISR ... */
254: OS_EXIT_CRITICAL(); /* ... can't PEND from an ISR */
255: *err = OS_ERR_PEND_ISR;
256: } else {
257: OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
258: OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
259: OSEventTaskWait(pevent); /* Suspend task until event or timeout occurs */
260: OS_EXIT_CRITICAL();
261: OSSched(); /* Find next highest priority task ready to run */
262: OS_ENTER_CRITICAL();
263: if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) {/* Did we get a message? */
264: OSTCBCur->OSTCBMsg = (void *)0; /* Extract message from TCB (Put there by QPost) */
265: OSTCBCur->OSTCBStat = OS_STAT_RDY;
266: OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */
267: OS_EXIT_CRITICAL();
268: *err = OS_NO_ERR;
269: } else if (OSTCBCur->OSTCBStat & OS_STAT_Q) { /* Timed out if status indicates pending on Q */
270: OSEventTO(pevent);
271: OS_EXIT_CRITICAL();
272: msg = (void *)0; /* No message received */
273: *err = OS_TIMEOUT; /* Indicate a timeout occured */
274: } else {
275: msg = *pq->OSQOut++; /* Extract message from queue */
276: pq->OSQEntries--; /* Update the number of entries in the queue */
277: if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of Q */
278: pq->OSQOut = pq->OSQStart;
279: }
280: OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
281: OS_EXIT_CRITICAL();
282: *err = OS_NO_ERR;
283: }
284: }
285: return (msg); /* Return message received (or NULL) */
286: }
287: /*$PAGE*/
288: /*
289: *********************************************************************************************************
290: * POST MESSAGE TO A QUEUE
291: *
292: * Description: This function sends a message to a queue
293: *
294: * Arguments : pevent is a pointer to the event control block associated with the desired queue
295: *
296: * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
297: *
298: * Returns : OS_NO_ERR The call was successful and the message was sent
299: * OS_Q_FULL If the queue cannot accept any more messages because it is full.
300: * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
301: *********************************************************************************************************
302: */
303:
304: INT8U OSQPost (OS_EVENT *pevent, void *msg)
305: {
306: OS_Q *pq;
307:
308:
309: OS_ENTER_CRITICAL();
310: if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
311: OS_EXIT_CRITICAL();
312: return (OS_ERR_EVENT_TYPE);
313: }
314: if (pevent->OSEventGrp) { /* See if any task pending on queue */
315: OSEventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
316: OS_EXIT_CRITICAL();
317: OSSched(); /* Find highest priority task ready to run */
318: return (OS_NO_ERR);
319: } else {
320: pq = pevent->OSEventPtr; /* Point to queue control block */
321: if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
322: OS_EXIT_CRITICAL();
323: return (OS_Q_FULL);
324: } else {
325: *pq->OSQIn++ = msg; /* Insert message into queue */
326: pq->OSQEntries++; /* Update the nbr of entries in the queue */
327: if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
328: pq->OSQIn = pq->OSQStart;
329: }
330: OS_EXIT_CRITICAL();
331: }
332: return (OS_NO_ERR);
333: }
334: }
335: /*$PAGE*/
336: /*
337: *********************************************************************************************************
338: * POST MESSAGE TO THE FRONT OF A QUEUE
339: *
340: * Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at
341: * the front instead of the end of the queue. Using OSQPostFront() allows you to send
342: * 'priority' messages.
343: *
344: * Arguments : pevent is a pointer to the event control block associated with the desired queue
345: *
346: * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
347: *
348: * Returns : OS_NO_ERR The call was successful and the message was sent
349: * OS_Q_FULL If the queue cannot accept any more messages because it is full.
350: * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
351: *********************************************************************************************************
352: */
353:
354: INT8U OSQPostFront (OS_EVENT *pevent, void *msg)
355: {
356: OS_Q *pq;
357:
358:
359: OS_ENTER_CRITICAL();
360: if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
361: OS_EXIT_CRITICAL();
362: return (OS_ERR_EVENT_TYPE);
363: }
364: if (pevent->OSEventGrp) { /* See if any task pending on queue */
365: OSEventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
366: OS_EXIT_CRITICAL();
367: OSSched(); /* Find highest priority task ready to run */
368: return (OS_NO_ERR);
369: } else {
370: pq = pevent->OSEventPtr; /* Point to queue control block */
371: if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
372: OS_EXIT_CRITICAL();
373: return (OS_Q_FULL);
374: } else {
375: if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */
376: pq->OSQOut = pq->OSQEnd;
377: }
378: pq->OSQOut--;
379: *pq->OSQOut = msg; /* Insert message into queue */
380: pq->OSQEntries++; /* Update the nbr of entries in the queue */
381: OS_EXIT_CRITICAL();
382: }
383: return (OS_NO_ERR);
384: }
385: }
386: /*$PAGE*/
387: /*
388: *********************************************************************************************************
389: * QUERY A MESSAGE QUEUE
390: *
391: * Description: This function obtains information about a message queue.
392: *
393: * Arguments : pevent is a pointer to the event control block associated with the desired mailbox
394: *
395: * pdata is a pointer to a structure that will contain information about the message
396: * queue.
397: *
398: * Returns : OS_NO_ERR The call was successful and the message was sent
399: * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue.
400: *********************************************************************************************************
401: */
402:
403: INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata)
404: {
405: OS_Q *pq;
406: INT8U i;
407: INT8U *psrc;
408: INT8U *pdest;
409:
410:
411: OS_ENTER_CRITICAL();
412: if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
413: OS_EXIT_CRITICAL();
414: return (OS_ERR_EVENT_TYPE);
415: }
416: pdata->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
417: psrc = &pevent->OSEventTbl[0];
418: pdest = &pdata->OSEventTbl[0];
419: for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
420: *pdest++ = *psrc++;
421: }
422: pq = (OS_Q *)pevent->OSEventPtr;
423: if (pq->OSQEntries > 0) {
424: pdata->OSMsg = pq->OSQOut; /* Get next message to return if available */
425: } else {
426: pdata->OSMsg = (void *)0;
427: }
428: pdata->OSNMsgs = pq->OSQEntries;
429: pdata->OSQSize = pq->OSQSize;
430: OS_EXIT_CRITICAL();
431: return (OS_NO_ERR);
432: }
433: #endif
434:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -