====== Queues ====== .. image:: Message_Queue_Diagram.png :width: 600 * Messages queues are like an array of mailboxes but with one wait list. * Each queue uses one Event Control Block (ECB) and one OS_Q block. The ECB points to the OS_Q. * The OS_Q is a set of pointers used to manage a circular buffer used to hold the queue's data. The buffer lives in the memory allocated by the caller to OSQCreate. A pointer to the memory for the buffer is pass in as a parameter when the queue is created. * By default the queue is FIFO, or First In First Out. OSQCreate ========= .. code-block:: c OS_EVENT *OSQCreate(void **start, INT16U size); * Must be called from a task. * Caller allocates the memory before the call. For example: .. code-block:: c void *ArrayOfMsg[size]; * The funciton takes an ECB and a OS_Q from the free lists and initialize the pointers. * The queue stars off empty. OSQDel ====== .. code-block:: c OS_EVENT *OSQDel(OS_EVENT *pevent, INT8U opt, INT8U *perr); * Deletes the queue. * Frees the Event Control Block (ECB) and the OS_Q used by the queue. * Requires an option * OS_DEL_NO_PEND - don't delete if tasks are waiting on the queue. * OS_DEL_ALWAYS - always delete. * If called with OS_DEL_ALWAYS, the queue will be deleted even if tasks are waiting on it. * All the waiting tasks will become ready. * Best practice is to first delete all tasks that use the queue before deleting the queue. OSQPend ======= .. code-block:: c void *OSQPend(OS_EVENT *pevent, INT16U timeout, INT8U *perr); * Must be called from a task. * Takes messages from the front of the queue. * If there is a message it returns it right away. * If there is no message it moves the task to the wait list. The task blocks on the queue. OSQPendAbort ============ .. code-block:: c INT8U OSQPendAbort(OS_EVENT *pevent, INT8U opt, INT8U *perr); OSQAccept ========= .. code-block:: c void *OSQAccept(OS_EVENT *pevent, INT8U *perr); * Can be called from a task or an ISR. * Checks if there is are any messages in the Queue. If there is it removes the first one from the queue and returns it to the task. * If there are no messages it returns 0. * Does not block. OSQPost ======= .. code-block:: c INT8U OSQPost(OS_EVENT *pevent, void *pmsg); * First In First Out (FIFO). * Can be called from a task or an ISR. * If there is are tasks waiting, then the highest priority task is made ready to run and gets the message at the front of the queue. * If there are no waiting tasks the message is added to the end of the queue. * If the queue was full it returns an OS_Q_FULL error. * If a task was made ready it calls the scheduler. OSQPostFront ============ .. code-block:: c INT8U OSQPostFront(OS_EVENT *pevent, void *pmsg); * Last In First Out (LIFO). Behaves like a stack. * Can be called from a task or an ISR. * If the queue is empty and there is a waiting task then the task is made ready and it gets the message. * If there are no waiting tasks, then the message is inserted at the front of the message queue ahead of older messages instead of going at the end of the queue. * If the queue was full it returns an OS_Q_FULL error. * If a task was made ready it calls the scheduler. OSQPostOpt ========== .. code-block:: c INT8U OSQPostOpt(OS_EVENT *pevent, void *pmsg, INT8U opt); * Newer function that can replace OSQPost and OSQPostFront. * Can be called from a task or an ISR. * Takes options that can be combined together. * OS_POST_OPT_BROADCAST * All waiting tasks are made ready and all get the message. * Calls the scheduler. * OS_POST_OPT_FRONT * If there are no waiting tasks the message is added to the front of the queue. * No option * If there are no waiting tasks the message is added to the back of the queue. OSQFlush ======== .. code-block:: c INT8U OSQFlush(OS_EVENT *pevent); * Reset the queue's buffer pointers which erases the messages. * Does not delete the messages memory. * Can be called from a task or an ISR. OSQQuery ======== .. code-block:: c INT8U OSQQuery(OS_EVENT *pevent, OS_Q_DATA *p_q_data); * Can be called from a task or an ISR. * Caller allocates a OS_Q_DATA struct and pass in a pointer to it. * Copies the queue's information into the OS_Q_DATA struct. * OS_Q_DATA * OSMSG - points to the message. * OSQSIZE - size of the queue. * OSNMSG - number of messages in the queue.