Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

A message queue is a kernel object allocated by the application. In fact, you can allocate any number of message queues. The only limit is the amount of RAM available.

There are a number of operations that the user can perform on message queues, summarized in Figure 15-1. However, an ISR can only call OSQPost(). A message queue must be created before sending messages through it.

Message queues are drawn as a first-in, first-out pipe (FIFO). However, with µC/OS-III, it is possible to post messages in last-in, first-out order (LIFO). The LIFO mechanism is useful when a task or an ISR must send an “urgent” message to a task. In this case, the message bypasses all other messages already in the message queue. The size of the message queue is configurable at run-time.

The small hourglass close to the receiving task (F15-1) indicates that the task has an option to specify a timeout. This timeout indicates that the task is willing to wait for a message to be sent to the message queue within a certain amount of time. If the message is not sent within that time, µC/OS-III resumes the task and returns an error code indicating that the task was made ready-to-run because of a timeout, and not because the message was received. It is possible to specify an infinite timeout and indicate that the task is willing to wait forever for the message to arrive.

The message queue also contains a list of tasks waiting for messages to be sent to the message queue. Multiple tasks can wait on a message queue as shown in Figure 15-2. When a message is sent to the message queue, the highest priority task waiting on the message queue receives the message. Optionally, the sender can broadcast a message to all tasks waiting on the message queue. In this case, if any of the tasks receiving the message from the broadcast has a higher priority than the task sending the message (or interrupted task, if the message is sent by an ISR), µC/OS-III will run the highest-priority task that is waiting. Notice that not all tasks must specify a timeout; some tasks may want to wait foreverThis table shows the difference in API for message-queue management.

Panel
titleMessage Queues API


µC/OS-II (os_q.c)µC/OS-III (os_q.c)Note
void * 
 OSQAccept( 
     OS_EVENT  *pevent, 
     INT8U     *perr);

(1)
OS_EVENT * 
 OSQCreate( 
     void     **start, 
     INT16U     size);
void 
 OSQCreate( 
     OS_Q         *p_q, 
     CPU_CHAR     *p_name, 
     OS_MSG_QTY    max_qty, 
     OS_ERR       *p_err);
(2)
OS_EVENT * 
 OSQDel( 
     OS_EVENT  *pevent, 
     INT8U      opt, 
     INT8U     *perr);
OS_OBJ_QTY, 
 OSQDel( 
     OS_Q         *p_q, 
     OS_OPT        opt, 
     OS_ERR       *p_err);

INT8U 
 OSQFlush( 
     OS_EVENT  *pevent);
OS_MSG_QTY 
 OSQFlush( 
     OS_Q         *p_q, 
     OS_ERR       *p_err);

void * 
 OSQPend( 
     OS_EVENT  *pevent, 
     INT32U     timeout, 
     INT8U     *perr);
void * 
 OSQPend( 
     OS_Q         *p_q, 
     OS_MSG_SIZE  *p_msg_size, 
     OS_TICK       timeout, 
     OS_OPT        opt,  
     CPU_TS       *p_ts, 
     OS_ERR       *p_err);
(3)
INT8U 
 OSQPendAbort( 
     OS_EVENT  *pevent, 
     INT8U      opt, 
     INT8U     *perr);
OS_OBJ_QTY 
 OSQPendAbort( 
     OS_Q         *p_q, 
     OS_OPT        opt, 
     OS_ERR       *p_err);

INT8U 
 OSQPost( 
     OS_EVENT  *pevent, 
     void      *pmsg);
void 
 OSQPost( 
     OS_Q         *p_q, 
     void         *p_void, 
     OS_MSG_SIZE   msg_size, 
     OS_OPT        opt, 
     OS_ERR       *p_err);
(4)
INT8U 
 OSQPostFront( 
     OS_EVENT  *pevent, 
     void      *pmsg);


INT8U 
 OSQPostOpt( 
     OS_EVENT  *pevent, 
     void      *pmsg, 
     INT8U      opt);

(4)
INT8U 
 OSQQuery( 
     OS_EVENT  *pevent, 
     OS_Q_DATA *p_q_data);

(5)



Panel
bgColor#f0f0f0

(1) In µC/OS-III, there is no “accept” API as this feature is built into the OSQPend() by specifying the OS_OPT_PEND_NON_BLOCKING option.

(2) In µC/OS-II, OSQCreate() returns the address of an OS_EVENT, which is used as the “handle” to the message queue. In µC/OS-III, the application must allocate storage for an OS_Q object, which serves the same purpose as the OS_EVENT. The benefit in µC/OS-III is that it is not necessary to predetermine at compile time, the number of message queues.

(3) µC/OS-III returns additional information when a message queue is posted. Specifically, the sender includes the size of the message and takes a snapshot of the current timestamp and stores it in the message. The receiver of the message therefore knows when the message was posted.

(4) In µC/OS-III, OSQPost() offers a number of options that replaces the three post functions provided in µC/OS-II.

(5) µC/OS-III does not provide query services as they were rarely used.