Message queue to synchronize and share information between threads. It is a template class, so it can hold elements of different types.

Dependents:   Nucleo_modbus_protocol_test F103RB_tcp_rtu_modbus_copy_v1_0

Committer:
gabrielrivas
Date:
Mon Jan 19 08:09:02 2015 +0000
Revision:
2:5e151e3834db
Parent:
1:c5b6cfae502d
Documentation added.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gabrielrivas 2:5e151e3834db 1 /** Message Queue Library
gabrielrivas 1:c5b6cfae502d 2 * Copyright (c) 2015 Gabriel Rivas
gabrielrivas 1:c5b6cfae502d 3 *
gabrielrivas 1:c5b6cfae502d 4 * Licensed under the Apache License, Version 2.0 (the "License");
gabrielrivas 1:c5b6cfae502d 5 * you may not use this file except in compliance with the License.
gabrielrivas 1:c5b6cfae502d 6 * You may obtain a copy of the License at
gabrielrivas 1:c5b6cfae502d 7 *
gabrielrivas 1:c5b6cfae502d 8 * http://www.apache.org/licenses/LICENSE-2.0
gabrielrivas 1:c5b6cfae502d 9 *
gabrielrivas 1:c5b6cfae502d 10 * Unless required by applicable law or agreed to in writing, software
gabrielrivas 1:c5b6cfae502d 11 * distributed under the License is distributed on an "AS IS" BASIS,
gabrielrivas 1:c5b6cfae502d 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
gabrielrivas 1:c5b6cfae502d 13 * See the License for the specific language governing permissions and
gabrielrivas 1:c5b6cfae502d 14 * limitations under the License.
gabrielrivas 1:c5b6cfae502d 15 */
gabrielrivas 0:faed68cc9fff 16 #ifndef _MESSAGE_QUEUE_H_
gabrielrivas 0:faed68cc9fff 17 #define _MESSAGE_QUEUE_H_
gabrielrivas 0:faed68cc9fff 18
gabrielrivas 0:faed68cc9fff 19 #include "mbed.h"
gabrielrivas 0:faed68cc9fff 20 #include "rtos.h"
gabrielrivas 0:faed68cc9fff 21 #include <queue>
gabrielrivas 0:faed68cc9fff 22
gabrielrivas 0:faed68cc9fff 23 #define MESSAGE_QUEUE_MAX_SIZE (256)
gabrielrivas 0:faed68cc9fff 24
gabrielrivas 1:c5b6cfae502d 25 /**
gabrielrivas 1:c5b6cfae502d 26 * Message queue class that is a wrapper for the STL queue container intended to
gabrielrivas 1:c5b6cfae502d 27 * be used to share data among threads using the mbed-rtos so the write and read access
gabrielrivas 1:c5b6cfae502d 28 * to the queue is protected from simultaneous access.
gabrielrivas 1:c5b6cfae502d 29 */
gabrielrivas 0:faed68cc9fff 30 template <class T>
gabrielrivas 0:faed68cc9fff 31 class MessageQueue
gabrielrivas 0:faed68cc9fff 32 {
gabrielrivas 0:faed68cc9fff 33 public:
gabrielrivas 1:c5b6cfae502d 34 /**
gabrielrivas 1:c5b6cfae502d 35 * Create a message queue object.
gabrielrivas 1:c5b6cfae502d 36 * @param size The size for the queue.
gabrielrivas 1:c5b6cfae502d 37 */
gabrielrivas 0:faed68cc9fff 38 MessageQueue(uint32_t size);
gabrielrivas 0:faed68cc9fff 39
gabrielrivas 0:faed68cc9fff 40 public:
gabrielrivas 1:c5b6cfae502d 41 /**
gabrielrivas 1:c5b6cfae502d 42 * Write a data element into the back of the queue.
gabrielrivas 1:c5b6cfae502d 43 * @param data Value or object to be writen into the queue.
gabrielrivas 1:c5b6cfae502d 44 */
gabrielrivas 0:faed68cc9fff 45 void write(T data);
gabrielrivas 1:c5b6cfae502d 46
gabrielrivas 1:c5b6cfae502d 47 /**
gabrielrivas 1:c5b6cfae502d 48 * Reads a element from the queue.
gabrielrivas 1:c5b6cfae502d 49 * @return The element in the front of the queue.
gabrielrivas 1:c5b6cfae502d 50 */
gabrielrivas 0:faed68cc9fff 51 T read();
gabrielrivas 1:c5b6cfae502d 52
gabrielrivas 1:c5b6cfae502d 53 /**
gabrielrivas 1:c5b6cfae502d 54 * Tells if a number of elements written has reached the size of the queue.
gabrielrivas 1:c5b6cfae502d 55 *
gabrielrivas 1:c5b6cfae502d 56 * @return The full status flag.
gabrielrivas 1:c5b6cfae502d 57 */
gabrielrivas 0:faed68cc9fff 58 bool isFull();
gabrielrivas 1:c5b6cfae502d 59
gabrielrivas 1:c5b6cfae502d 60 /**
gabrielrivas 1:c5b6cfae502d 61 * Tells if no data elements can be read from the queue.
gabrielrivas 1:c5b6cfae502d 62 * @return The empty status flag.
gabrielrivas 1:c5b6cfae502d 63 */
gabrielrivas 0:faed68cc9fff 64 bool isEmpty();
gabrielrivas 1:c5b6cfae502d 65
gabrielrivas 1:c5b6cfae502d 66 /**
gabrielrivas 1:c5b6cfae502d 67 * Get the number of elements written into the queue.
gabrielrivas 1:c5b6cfae502d 68 * @return Index of the last element written in the queue.
gabrielrivas 1:c5b6cfae502d 69 */
gabrielrivas 0:faed68cc9fff 70 uint32_t getWriteIndex();
gabrielrivas 1:c5b6cfae502d 71
gabrielrivas 1:c5b6cfae502d 72 /**
gabrielrivas 1:c5b6cfae502d 73 * Get the number of elements read from the queue.
gabrielrivas 1:c5b6cfae502d 74 * @return Index of the last element read from the queue.
gabrielrivas 1:c5b6cfae502d 75 */
gabrielrivas 0:faed68cc9fff 76 uint32_t getReadIndex();
gabrielrivas 1:c5b6cfae502d 77
gabrielrivas 1:c5b6cfae502d 78 /**
gabrielrivas 1:c5b6cfae502d 79 * Removes all the elements in the queue and reset all its internal counters and status.
gabrielrivas 1:c5b6cfae502d 80 */
gabrielrivas 0:faed68cc9fff 81 void reset();
gabrielrivas 0:faed68cc9fff 82
gabrielrivas 0:faed68cc9fff 83 private:
gabrielrivas 1:c5b6cfae502d 84 /** Internal queue that holds data elements.
gabrielrivas 1:c5b6cfae502d 85 */
gabrielrivas 0:faed68cc9fff 86 std::queue<T> m_queue;
gabrielrivas 1:c5b6cfae502d 87
gabrielrivas 1:c5b6cfae502d 88 /** Mutex to protect the queue from simultaneous access.
gabrielrivas 1:c5b6cfae502d 89 */
gabrielrivas 0:faed68cc9fff 90 Mutex m_mutex;
gabrielrivas 1:c5b6cfae502d 91
gabrielrivas 1:c5b6cfae502d 92 /** Number of elements allowed to be written into the queue.
gabrielrivas 1:c5b6cfae502d 93 */
gabrielrivas 0:faed68cc9fff 94 uint32_t m_size;
gabrielrivas 1:c5b6cfae502d 95
gabrielrivas 1:c5b6cfae502d 96 /** Internal full status flag.
gabrielrivas 1:c5b6cfae502d 97 */
gabrielrivas 0:faed68cc9fff 98 bool m_full;
gabrielrivas 1:c5b6cfae502d 99
gabrielrivas 1:c5b6cfae502d 100 /** Internal empty status flag.
gabrielrivas 1:c5b6cfae502d 101 */
gabrielrivas 0:faed68cc9fff 102 bool m_empty;
gabrielrivas 1:c5b6cfae502d 103
gabrielrivas 1:c5b6cfae502d 104 /** Internal index for elements read from the queue.
gabrielrivas 1:c5b6cfae502d 105 */
gabrielrivas 0:faed68cc9fff 106 uint32_t m_readIndex;
gabrielrivas 1:c5b6cfae502d 107
gabrielrivas 1:c5b6cfae502d 108 /** Internal index for elements written into the queue.
gabrielrivas 1:c5b6cfae502d 109 */
gabrielrivas 0:faed68cc9fff 110 uint32_t m_writeIndex;
gabrielrivas 0:faed68cc9fff 111
gabrielrivas 0:faed68cc9fff 112 };
gabrielrivas 0:faed68cc9fff 113
gabrielrivas 0:faed68cc9fff 114
gabrielrivas 0:faed68cc9fff 115 template <class T>
gabrielrivas 0:faed68cc9fff 116 MessageQueue<T>::MessageQueue(uint32_t size)
gabrielrivas 0:faed68cc9fff 117 {
gabrielrivas 0:faed68cc9fff 118 // assert(size < MESSAGE_QUEUE_MAX_SIZE);
gabrielrivas 0:faed68cc9fff 119 m_size = size;
gabrielrivas 0:faed68cc9fff 120 m_full = false;
gabrielrivas 0:faed68cc9fff 121 m_empty = true;
gabrielrivas 0:faed68cc9fff 122 m_readIndex = 0;
gabrielrivas 0:faed68cc9fff 123 m_writeIndex = 0;
gabrielrivas 0:faed68cc9fff 124 }
gabrielrivas 0:faed68cc9fff 125
gabrielrivas 0:faed68cc9fff 126 template <class T>
gabrielrivas 0:faed68cc9fff 127 void MessageQueue<T>::write(T data)
gabrielrivas 0:faed68cc9fff 128 {
gabrielrivas 0:faed68cc9fff 129 m_mutex.lock();
gabrielrivas 0:faed68cc9fff 130
gabrielrivas 0:faed68cc9fff 131 if (m_writeIndex == m_size) {
gabrielrivas 0:faed68cc9fff 132 m_full = true;
gabrielrivas 0:faed68cc9fff 133 } else {
gabrielrivas 0:faed68cc9fff 134 m_queue.push(data);
gabrielrivas 0:faed68cc9fff 135 m_empty = false;
gabrielrivas 0:faed68cc9fff 136 m_writeIndex++;
gabrielrivas 0:faed68cc9fff 137 }
gabrielrivas 0:faed68cc9fff 138 m_mutex.unlock();
gabrielrivas 0:faed68cc9fff 139 }
gabrielrivas 0:faed68cc9fff 140
gabrielrivas 0:faed68cc9fff 141 template <class T>
gabrielrivas 0:faed68cc9fff 142 T MessageQueue<T>::read()
gabrielrivas 0:faed68cc9fff 143 {
gabrielrivas 2:5e151e3834db 144 T data = 0;
gabrielrivas 0:faed68cc9fff 145
gabrielrivas 0:faed68cc9fff 146 m_mutex.lock();
gabrielrivas 0:faed68cc9fff 147
gabrielrivas 0:faed68cc9fff 148 if (m_readIndex == m_writeIndex) {
gabrielrivas 0:faed68cc9fff 149 m_empty = true;
gabrielrivas 0:faed68cc9fff 150 } else {
gabrielrivas 0:faed68cc9fff 151 data = m_queue.front();
gabrielrivas 0:faed68cc9fff 152 m_full = false;
gabrielrivas 0:faed68cc9fff 153 m_queue.pop();
gabrielrivas 0:faed68cc9fff 154 m_readIndex++;
gabrielrivas 0:faed68cc9fff 155 }
gabrielrivas 0:faed68cc9fff 156
gabrielrivas 0:faed68cc9fff 157 m_mutex.unlock();
gabrielrivas 0:faed68cc9fff 158
gabrielrivas 0:faed68cc9fff 159 return data;
gabrielrivas 0:faed68cc9fff 160 }
gabrielrivas 0:faed68cc9fff 161
gabrielrivas 0:faed68cc9fff 162 template <class T>
gabrielrivas 0:faed68cc9fff 163 bool MessageQueue<T>::isFull()
gabrielrivas 0:faed68cc9fff 164 {
gabrielrivas 0:faed68cc9fff 165 return m_full;
gabrielrivas 0:faed68cc9fff 166 }
gabrielrivas 0:faed68cc9fff 167
gabrielrivas 0:faed68cc9fff 168 template <class T>
gabrielrivas 0:faed68cc9fff 169 bool MessageQueue<T>::isEmpty()
gabrielrivas 0:faed68cc9fff 170 {
gabrielrivas 0:faed68cc9fff 171 return m_empty;
gabrielrivas 0:faed68cc9fff 172 }
gabrielrivas 0:faed68cc9fff 173
gabrielrivas 0:faed68cc9fff 174 template <class T>
gabrielrivas 0:faed68cc9fff 175 uint32_t MessageQueue<T>::getWriteIndex()
gabrielrivas 0:faed68cc9fff 176 {
gabrielrivas 0:faed68cc9fff 177 return m_writeIndex;
gabrielrivas 0:faed68cc9fff 178 }
gabrielrivas 0:faed68cc9fff 179
gabrielrivas 0:faed68cc9fff 180 template <class T>
gabrielrivas 0:faed68cc9fff 181 uint32_t MessageQueue<T>::getReadIndex()
gabrielrivas 0:faed68cc9fff 182 {
gabrielrivas 0:faed68cc9fff 183 return m_readIndex;
gabrielrivas 0:faed68cc9fff 184 }
gabrielrivas 0:faed68cc9fff 185
gabrielrivas 0:faed68cc9fff 186 template <class T>
gabrielrivas 0:faed68cc9fff 187 void MessageQueue<T>::reset()
gabrielrivas 0:faed68cc9fff 188 {
gabrielrivas 0:faed68cc9fff 189 m_mutex.lock();
gabrielrivas 0:faed68cc9fff 190
gabrielrivas 0:faed68cc9fff 191 while(!isEmpty()) read();
gabrielrivas 0:faed68cc9fff 192 m_full = false;
gabrielrivas 0:faed68cc9fff 193 m_empty = true;
gabrielrivas 0:faed68cc9fff 194 m_readIndex = 0;
gabrielrivas 0:faed68cc9fff 195 m_writeIndex = 0;
gabrielrivas 0:faed68cc9fff 196
gabrielrivas 0:faed68cc9fff 197 m_mutex.unlock();
gabrielrivas 0:faed68cc9fff 198 }
gabrielrivas 0:faed68cc9fff 199
gabrielrivas 0:faed68cc9fff 200 #endif