Ucos ii Task Communication 5: Message Queue 2
Message queues can be used in the following two places;
1. Store external events: external events are collected by interruptions and then stored in the queue.
2. The receiving cycle buffer in the serial receiving program can be understood as a message queue.
To use a message queue, follow these steps;
1. Create a pointer to the Message array and the size of the array. the pointer array must be declared as void type, as shown below:
Void * myarrayofmsg [size];
2. Declare An OS _event pointer pointing to the generated queue as follows:
OS _event * qsem;
3. Call the osqcreate () function to create a message queue, as shown below:
Qsem = osqcreate (& myarrayofmsg [0], size );
4. Wait for the message in the message queue, osqpend ().
5. Send a message to the message queue.
To create a message queue, the implementation code of osqcreate () is as follows:
OS _event * osqcreate (void ** start, int16u size) |
{ |
OS _event * pevent; |
OS _q * PQ; |
|
|
OS _enter_critical (); |
Pevent = oseventfreelist; (1) |
If (oseventfreelist! = (OS _event *) 0 ){ |
Oseventfreelist = (OS _event *) oseventfreelist-> oseventptr; (2) |
} |
OS _exit_critical (); |
If (pevent! = (OS _event *) 0 ){ |
OS _enter_critical (); |
PQ = osqfreelist; (3) |
If (osqfreelist! = (OS _q *) 0 ){ |
Osqfreelist = osqfreelist-> osqptr; |
} |
OS _exit_critical (); |
If (PQ! = (OS _q *) 0 ){ |
PQ-> osqstart = start; (4) |
PQ-> osqend = & start [size]; |
PQ-> osqin = start; |
PQ-> osqout = start; |
PQ-> osqsize = size; |
PQ-> osqentries = 0; |
Pevent-> oseventtype = OS _event_type_q; (5) |
Pevent-> oseventptr = PQ; (6) |
Oseventwaitlistinit (pevent); (7) |
} Else { |
OS _enter_critical (); |
Pevent-> oseventptr = (void *) oseventfreelist; (8) |
Oseventfreelist = pevent; |
OS _exit_critical (); |
Pevent = (OS _event *) 0; |
} |
} |
Return (pevent); (9) |
} |
It is similar to creating a mailbox and creating a semaphore. First, apply for a control block, and then initialize this control block. It is different from creating a mailbox and a semaphore, when creating a message queue, an additional queue control block is applied. For more information, see the following description.
Osqcreate () first obtains an event control block [(1)] From the idle Event Control Block linked list, and adjusts the pointer of the remaining idle Event Control Block List accordingly, point it to the next idle Event Control Block [(2)]. Then, the osqcreate () function extracts a queue control block from the list of idle queue control blocks [(3)]. If an idle queue control block is available, initialize it [(4)]. The function then sets the type of the event control block to OS _event_type_q [(5)] and points its. oseventptr pointer to the queue control block [(6)]. Osqcreate () also calls the oseventwaitlistinit () function to initialize the wait task list of the Event Control Block [
(7)]. At this time, the message queue is initializing, and its waiting task list is obviously empty. Finally, osqcreate () returns a pointer to the event control block to its calling function [(9)]. This pointer will be used when calling Message Queue processing functions such as osqpend (), osqpost (), osqpostfront (), osqflush (), osqaccept (), and osqquery. Therefore, this pointer can be viewed as the handle of the corresponding message queue. It is worth noting that if there is no idle event control block at this time, the osqcreate () function returns a null pointer. If no queue control block is available, the osqcreate () function returns the acquired event control block to the list of idle event control blocks to avoid wasting event control block resources.
[(8)].