📄 os_q.lst
字号:
560 /*
561 *********************************************************************************************************
562 * POST MESSAGE TO A QUEUE
563 *
564 * Description: This function sends a message to a queue. This call has been added to reduce code size
565 * since it can replace both OSQPost() and OSQPostFront(). Also, this function adds the
566 * capability to broadcast a message to ALL tasks waiting on the message queue.
567 *
568 * Arguments : pevent is a pointer to the event control block associated with the desired queue
569 *
570 * msg is a pointer to the message to send.
571 *
572 * opt determines the type of POST performed:
573 * OS_POST_OPT_NONE POST to a single waiting task
574 * (Identical to OSQPost())
575 * OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the queue
576 * OS_POST_OPT_FRONT POST as LIFO (Simulates OSQPostFront())
577 *
578 * Below is a list of ALL the possible combination of these flags:
579 *
580 * 1) OS_POST_OPT_NONE
581 * identical to OSQPost()
582 *
583 * 2) OS_POST_OPT_FRONT
584 * identical to OSQPostFront()
585 *
586 * 3) OS_POST_OPT_BROADCAST
587 * identical to OSQPost() but will broadcast 'msg' to ALL waiting tasks
588 *
589 * 4) OS_POST_OPT_FRONT + OS_POST_OPT_BROADCAST is identical to
590 * OSQPostFront() except that will broadcast 'msg' to ALL waiting tasks
591 *
592 * Returns : OS_NO_ERR The call was successful and the message was sent
593 * OS_Q_FULL If the queue cannot accept any more messages because it is full.
594 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
595 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
596 *
597 * Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the
598 * interrupt disable time is proportional to the number of tasks waiting on the queue.
599 *********************************************************************************************************
600 */
601
602 #if OS_Q_POST_OPT_EN > 0
603 INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)
604 {
605 OS_Q *pq;
606 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
609
610
611
612 #if OS_ARG_CHK_EN > 0
613 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
614 return (OS_ERR_PEVENT_NULL);
615 }
616 #endif
617 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
618 return (OS_ERR_EVENT_TYPE);
C51 COMPILER V8.08 OS_Q 08/04/2008 21:49:52 PAGE 12
619 }
620 OS_ENTER_CRITICAL();
621 if (pevent->OSEventGrp != 0x00) { /* See if any task pending on queue */
622 if ((opt & OS_POST_OPT_BROADCAST) != 0x00) { /* Do we need to post msg to ALL waiting tasks ? */
623 while (pevent->OSEventGrp != 0) { /* Yes, Post to ALL tasks waiting on queue */
624 (void)OS_EventTaskRdy(pevent, msg, OS_STAT_Q);
625 }
626 } else {
627 (void)OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* No, Post to HPT waiting on queue */
628 }
629 OS_EXIT_CRITICAL();
630 OS_Sched(); /* Find highest priority task ready to run */
631 return (OS_NO_ERR);
632 }
633 pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */
634 if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
635 OS_EXIT_CRITICAL();
636 return (OS_Q_FULL);
637 }
638 if ((opt & OS_POST_OPT_FRONT) != 0x00) { /* Do we post to the FRONT of the queue? */
639 if (pq->OSQOut == pq->OSQStart) { /* Yes, Post as LIFO, Wrap OUT pointer if we ... */
640 pq->OSQOut = pq->OSQEnd; /* ... are at the 1st queue entry */
641 }
642 pq->OSQOut--;
643 *pq->OSQOut = msg; /* Insert message into queue */
644 } else { /* No, Post as FIFO */
645 *pq->OSQIn++ = msg; /* Insert message into queue */
646 if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
647 pq->OSQIn = pq->OSQStart;
648 }
649 }
650 pq->OSQEntries++; /* Update the nbr of entries in the queue */
651 OS_EXIT_CRITICAL();
652 return (OS_NO_ERR);
653 }
654 #endif
655 /*$PAGE*/
656 /*
657 *********************************************************************************************************
658 * QUERY A MESSAGE QUEUE
659 *
660 * Description: This function obtains information about a message queue.
661 *
662 * Arguments : pevent is a pointer to the event control block associated with the desired queue
663 *
664 * p_q_data is a pointer to a structure that will contain information about the message
665 * queue.
666 *
667 * Returns : OS_NO_ERR The call was successful and the message was sent
668 * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue.
669 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
670 * OS_ERR_PDATA_NULL If 'p_q_data' is a NULL pointer
671 *********************************************************************************************************
672 */
673
674 #if OS_Q_QUERY_EN > 0
675 INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *p_q_data)
676 {
677 OS_Q *pq;
678 INT8U i;
679 #if OS_LOWEST_PRIO <= 63
680 INT8U *psrc;
C51 COMPILER V8.08 OS_Q 08/04/2008 21:49:52 PAGE 13
681 INT8U *pdest;
682 #else
INT16U *psrc;
INT16U *pdest;
#endif
686 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
689
690
691
692 #if OS_ARG_CHK_EN > 0
693 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
694 return (OS_ERR_PEVENT_NULL);
695 }
696 if (p_q_data == (OS_Q_DATA *)0) { /* Validate 'p_q_data' */
697 return (OS_ERR_PDATA_NULL);
698 }
699 #endif
700 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
701 return (OS_ERR_EVENT_TYPE);
702 }
703 OS_ENTER_CRITICAL();
704 p_q_data->OSEventGrp = pevent->OSEventGrp; /* Copy message queue wait list */
705 psrc = &pevent->OSEventTbl[0];
706 pdest = &p_q_data->OSEventTbl[0];
707 for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
708 *pdest++ = *psrc++;
709 }
710 pq = (OS_Q *)pevent->OSEventPtr;
711 if (pq->OSQEntries > 0) {
712 p_q_data->OSMsg = *pq->OSQOut; /* Get next message to return if available */
713 } else {
714 p_q_data->OSMsg = (void *)0;
715 }
716 p_q_data->OSNMsgs = pq->OSQEntries;
717 p_q_data->OSQSize = pq->OSQSize;
718 OS_EXIT_CRITICAL();
719 return (OS_NO_ERR);
720 }
721 #endif /* OS_Q_QUERY_EN */
722
723 /*$PAGE*/
724 /*
725 *********************************************************************************************************
726 * QUEUE MODULE INITIALIZATION
727 *
728 * Description : This function is called by uC/OS-II to initialize the message queue module. Your
729 * application MUST NOT call this function.
730 *
731 * Arguments : none
732 *
733 * Returns : none
734 *
735 * Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.
736 *********************************************************************************************************
737 */
738
739 void OS_QInit (void)
740 {
741 #if OS_MAX_QS == 1
OSQFreeList = &OSQTbl[0]; /* Only ONE queue! */
C51 COMPILER V8.08 OS_Q 08/04/2008 21:49:52 PAGE 14
OSQFreeList->OSQPtr = (OS_Q *)0;
#endif
745
746 #if OS_MAX_QS >= 2
747 INT16U i;
748 OS_Q *pq1;
749 OS_Q *pq2;
750
751
752
753 OS_MemClr((INT8U *)&OSQTbl[0], sizeof(OSQTbl)); /* Clear the queue table */
754 pq1 = &OSQTbl[0];
755 pq2 = &OSQTbl[1];
756 for (i = 0; i < (OS_MAX_QS - 1); i++) { /* Init. list of free QUEUE control blocks */
757 pq1->OSQPtr = pq2;
758 pq1++;
759 pq2++;
760 }
761 pq1->OSQPtr = (OS_Q *)0;
762 OSQFreeList = &OSQTbl[0];
763 #endif
764 }
765 #endif /* OS_Q_EN */
C51 COMPILATION COMPLETE. 0 WARNING(S), 57 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -