Ucos ii task-to-task communication 5: Message Queue
If you compare a mailbox to an upgraded version of the semaphore, the message queue is an upgraded version of the mailbox. A mailbox can send a pointer variable from one task to another, while a Message Queue can send multiple pointer variables from one task to another. In addition, each pointer can point to a different data structure variable.
Note that a task or interrupt service subroutine can call osqpost (), osqpostfront (), osqflush (), or osqaccept () functions. However, only tasks can call the osqpend () and osqquery () functions.
We know that each event has a corresponding event control block to record information about this event. Message Queue is no exception. A Message Queue corresponds to a queue control block.
Compared with semaphores and mailboxes, ucos ii defines a Data Structure to store message queue information. Definition:
Typedef struct OS _q {
Struct OS _q * osqptr;
Void ** osqstart;
Void ** osqend;
Void ** osqin;
Void ** osqout;
Int16u osqsize;
Int16u osqentries;
} OS _q;
. OsqptrLink all the queue control blocks in the idle queue control block. Once a message queue is created, this domain is no longer useful.
. OsqstartIs the pointer to the starting address of the pointer array of the message queue. This array must be defined by your applications before using message queues.
. OsqendIs a pointer to the next address of the end unit of the message queue. This pointer makes the message queue a circular buffer.
. OsqinIs a pointer to the position where the next message is inserted in the message queue. When. osqin and. osqend are equal,. osqin is adjusted to the starting unit of the message queue.
. OsqoutIs a pointer to the next location in the message queue to retrieve messages. When. osqout and. osqend are equal,. osqout is adjusted to the starting unit of the message queue.
. OsqsizeThe total number of units in a message queue. This value is determined by the user application when a message queue is created. In μ c/OS-II, this value can be up to 65,535.
. OsqentriesThe current number of messages in the message queue. When the message queue is empty, the value is 0. When the message queue is full, the value is the same as the. osqsize value. When a message queue is created, the value is 0.
Ucos ii provides seven functions for Message Queue operations
1. Create a message queue, osqcreate ()
2. Wait for a message in a message queue, osqpend ()
3. Send a message (FIFO), osqpost () to the Message Queue ()
4. Send a message to the Message Queue (first-in-first-out LIFO), osqpostfront ()
5. Get a message from a message queue without waiting, osqaccept ()
6. Clear a message queue, osqflush ()
7. query the status of a message queue, osqquery ()
The most fundamental part of a message queue is a circular buffer, where each unit contains a pointer. When the queue is not full,. osqin points to the next address unit for storing messages. If the queue is full (. osqentries and. osqsize are equal),. osqin and. osqout point to the same unit. If a new pointer to the message is inserted into the Unit pointed to by. osqin, a first-in-first-out queue is formed. Conversely, if a new pointer is inserted to the next unit pointed to by. osqout, the LIFO Queue (last-in-first-out) is formed ). When. osqentries and. osqsize are equal, the queue is full. The message pointer is always taken from the Unit pointed to by. osqout. Pointer. osqstart and. osqend define the header and end of the message pointer array, so that the boundary check and necessary Pointer Adjustment can be performed when. osqin and. osqout reach the edge of the queue to implement the loop function.