Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Queue.h Source File

Queue.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2012 ARM Limited
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00020  * SOFTWARE.
00021  */
00022 #ifndef QUEUE_H
00023 #define QUEUE_H
00024 
00025 #include <stdint.h>
00026 #include <string.h>
00027 
00028 #include "cmsis_os2.h"
00029 #include "mbed_rtos_storage.h"
00030 #include "platform/mbed_error.h"
00031 #include "platform/NonCopyable.h"
00032 #include "mbed_rtos1_types.h"
00033 
00034 namespace rtos {
00035 /** \addtogroup rtos */
00036 /** @{*/
00037 /**
00038  * \defgroup rtos_EventFlags EventFlags class
00039  * @{
00040  */
00041  
00042 /** The Queue class allow to control, send, receive, or wait for messages.
00043  A message can be a integer or pointer value  to a certain type T that is send
00044  to a thread or interrupt service routine.
00045   @tparam  T         data type of a single message element.
00046   @tparam  queue_sz  maximum number of messages in queue.
00047 
00048  @note
00049  Memory considerations: The queue control structures will be created on current thread's stack, both for the mbed OS
00050  and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
00051 */
00052 template<typename T, uint32_t queue_sz>
00053 class Queue : private mbed::NonCopyable<Queue<T, queue_sz> > {
00054 public:
00055     /** Create and initialize a message Queue.
00056      *
00057      * @note You cannot call this function from ISR context.
00058     */
00059     Queue() {
00060         memset(&_obj_mem, 0, sizeof(_obj_mem));
00061         osMessageQueueAttr_t attr = { 0 };
00062         attr.mq_mem = _queue_mem;
00063         attr.mq_size = sizeof(_queue_mem);
00064         attr.cb_mem = &_obj_mem;
00065         attr.cb_size = sizeof(_obj_mem);
00066         _id = osMessageQueueNew(queue_sz, sizeof(T*), &attr);
00067         MBED_ASSERT(_id);
00068     }
00069     /** Queue destructor
00070      *
00071      * @note You cannot call this function from ISR context.
00072      */
00073     ~Queue() {
00074         osMessageQueueDelete(_id);
00075     }
00076 
00077     /** Check if the queue is empty
00078      *
00079      * @return True if the queue is empty, false if not
00080      *
00081      * @note You may call this function from ISR context.
00082      */
00083     bool empty() const {
00084         return osMessageQueueGetCount(_id) == 0;
00085     }
00086 
00087     /** Check if the queue is full
00088      *
00089      * @return True if the queue is full, false if not
00090      *
00091      * @note You may call this function from ISR context.
00092      */
00093     bool full() const {
00094         return osMessageQueueGetSpace(_id) == 0;
00095     }
00096 
00097     /** Put a message in a Queue.
00098       @param   data      message pointer.
00099       @param   millisec  timeout value or 0 in case of no time-out. (default: 0)
00100       @param   prio      priority value or 0 in case of default. (default: 0)
00101       @return  status code that indicates the execution status of the function:
00102                @a osOK the message has been put into the queue.
00103                @a osErrorTimeout the message could not be put into the queue in the given time.
00104                @a osErrorResource not enough space in the queue.
00105                @a osErrorParameter internal error or non-zero timeout specified in an ISR.
00106 
00107       @note You may call this function from ISR context if the millisec parameter is set to 0.
00108     */
00109     osStatus put(T* data, uint32_t millisec=0, uint8_t prio=0) {
00110         return osMessageQueuePut(_id, &data, prio, millisec);
00111     }
00112 
00113     /** Get a message or Wait for a message from a Queue. Messages are retrieved in a descending priority order or
00114         first in first out when the priorities are the same.
00115       @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
00116       @return  event information that includes the message in event.value and the status code in event.status:
00117                @a osEventMessage message received.
00118                @a osOK no message is available in the queue and no timeout was specified.
00119                @a osEventTimeout no message has arrived during the given timeout period.
00120                @a osErrorParameter a parameter is invalid or outside of a permitted range.
00121 
00122       @note You may call this function from ISR context if the millisec parameter is set to 0.
00123     */
00124     osEvent get(uint32_t millisec=osWaitForever) {
00125         osEvent event;
00126         T *data = NULL;
00127         osStatus_t res = osMessageQueueGet(_id, &data, NULL, millisec);
00128 
00129         switch (res) {
00130             case osOK:
00131                 event.status = (osStatus)osEventMessage;
00132                 event.value.p = data;
00133                 break;
00134             case osErrorResource:
00135                 event.status = osOK;
00136                 break;
00137             case osErrorTimeout:
00138                 event.status = (osStatus)osEventTimeout;
00139                 break;
00140             case osErrorParameter:
00141             default:
00142                 event.status = osErrorParameter;
00143                 break;
00144         }
00145         event.def.message_id = _id;
00146 
00147         return event;
00148     }
00149 
00150 private:
00151     osMessageQueueId_t            _id;
00152     char                          _queue_mem[queue_sz * (sizeof(T*) + sizeof(mbed_rtos_storage_message_t))];
00153     mbed_rtos_storage_msg_queue_t _obj_mem;
00154 };
00155 /** @}*/
00156 /** @}*/
00157 
00158 }
00159 #endif
00160