USB CDC library for MBED on STM32

Dependents:   PushToGo-F429

Committer:
caoyuan9642
Date:
Sun Sep 09 19:03:18 2018 +0000
Revision:
0:7cf972f622d3
usb

Who changed what in which revision?

UserRevisionLine numberNew contents of line
caoyuan9642 0:7cf972f622d3 1 /*
caoyuan9642 0:7cf972f622d3 2 * DQueue.h
caoyuan9642 0:7cf972f622d3 3 *
caoyuan9642 0:7cf972f622d3 4 * Created on: 2018Äê4ÔÂ15ÈÕ
caoyuan9642 0:7cf972f622d3 5 * Author: caoyuan9642
caoyuan9642 0:7cf972f622d3 6 */
caoyuan9642 0:7cf972f622d3 7
caoyuan9642 0:7cf972f622d3 8 #ifndef IOQUEUE_H_
caoyuan9642 0:7cf972f622d3 9 #define IOQUEUE_H_
caoyuan9642 0:7cf972f622d3 10
caoyuan9642 0:7cf972f622d3 11 #include "mbed.h"
caoyuan9642 0:7cf972f622d3 12
caoyuan9642 0:7cf972f622d3 13 #define SIGNAL_QUEUE 0x00000010
caoyuan9642 0:7cf972f622d3 14 #define MAX_THREAD_QUEUE 16
caoyuan9642 0:7cf972f622d3 15
caoyuan9642 0:7cf972f622d3 16 struct ThreadQueue
caoyuan9642 0:7cf972f622d3 17 {
caoyuan9642 0:7cf972f622d3 18 osThreadId_t threads[MAX_THREAD_QUEUE];
caoyuan9642 0:7cf972f622d3 19 osThreadId_t *head, *tail;
caoyuan9642 0:7cf972f622d3 20
caoyuan9642 0:7cf972f622d3 21 ThreadQueue()
caoyuan9642 0:7cf972f622d3 22 {
caoyuan9642 0:7cf972f622d3 23 head = tail = threads;
caoyuan9642 0:7cf972f622d3 24 }
caoyuan9642 0:7cf972f622d3 25
caoyuan9642 0:7cf972f622d3 26 bool empty()
caoyuan9642 0:7cf972f622d3 27 {
caoyuan9642 0:7cf972f622d3 28 return head == tail;
caoyuan9642 0:7cf972f622d3 29 }
caoyuan9642 0:7cf972f622d3 30
caoyuan9642 0:7cf972f622d3 31 bool full()
caoyuan9642 0:7cf972f622d3 32 {
caoyuan9642 0:7cf972f622d3 33 return ((tail - head + 1) % MAX_THREAD_QUEUE) == 0;
caoyuan9642 0:7cf972f622d3 34 }
caoyuan9642 0:7cf972f622d3 35
caoyuan9642 0:7cf972f622d3 36 osThreadId_t get()
caoyuan9642 0:7cf972f622d3 37 {
caoyuan9642 0:7cf972f622d3 38 if (empty())
caoyuan9642 0:7cf972f622d3 39 return NULL;
caoyuan9642 0:7cf972f622d3 40 osThreadId_t th = *head;
caoyuan9642 0:7cf972f622d3 41 if (++head == threads + MAX_THREAD_QUEUE)
caoyuan9642 0:7cf972f622d3 42 head = threads;
caoyuan9642 0:7cf972f622d3 43 return th;
caoyuan9642 0:7cf972f622d3 44 }
caoyuan9642 0:7cf972f622d3 45
caoyuan9642 0:7cf972f622d3 46 int put(osThreadId_t th)
caoyuan9642 0:7cf972f622d3 47 {
caoyuan9642 0:7cf972f622d3 48 if (full())
caoyuan9642 0:7cf972f622d3 49 {
caoyuan9642 0:7cf972f622d3 50 return -1;
caoyuan9642 0:7cf972f622d3 51 }
caoyuan9642 0:7cf972f622d3 52 *tail = th;
caoyuan9642 0:7cf972f622d3 53 if (++tail == threads + MAX_THREAD_QUEUE)
caoyuan9642 0:7cf972f622d3 54 tail = threads;
caoyuan9642 0:7cf972f622d3 55 return 0;
caoyuan9642 0:7cf972f622d3 56 }
caoyuan9642 0:7cf972f622d3 57
caoyuan9642 0:7cf972f622d3 58 /*
caoyuan9642 0:7cf972f622d3 59 * Wait on the current thread until awaken by other operations in the queue
caoyuan9642 0:7cf972f622d3 60 */
caoyuan9642 0:7cf972f622d3 61 osStatus qwait(uint32_t wait)
caoyuan9642 0:7cf972f622d3 62 {
caoyuan9642 0:7cf972f622d3 63 if (wait == 0)
caoyuan9642 0:7cf972f622d3 64 {
caoyuan9642 0:7cf972f622d3 65 return osErrorTimeout;
caoyuan9642 0:7cf972f622d3 66 }
caoyuan9642 0:7cf972f622d3 67 core_util_critical_section_exit();
caoyuan9642 0:7cf972f622d3 68
caoyuan9642 0:7cf972f622d3 69 Thread::signal_clr(0x7FFFFFFF); // Clear all signals before adding to queue. Important!
caoyuan9642 0:7cf972f622d3 70 if (put(Thread::gettid()) != 0)
caoyuan9642 0:7cf972f622d3 71 {
caoyuan9642 0:7cf972f622d3 72 // Queue full
caoyuan9642 0:7cf972f622d3 73 printf("Queue full");
caoyuan9642 0:7cf972f622d3 74 core_util_critical_section_enter();
caoyuan9642 0:7cf972f622d3 75 return osErrorTimeout;
caoyuan9642 0:7cf972f622d3 76 }
caoyuan9642 0:7cf972f622d3 77 Thread::signal_wait(SIGNAL_QUEUE, wait);
caoyuan9642 0:7cf972f622d3 78 core_util_critical_section_enter();
caoyuan9642 0:7cf972f622d3 79 return osOK;
caoyuan9642 0:7cf972f622d3 80 }
caoyuan9642 0:7cf972f622d3 81 };
caoyuan9642 0:7cf972f622d3 82
caoyuan9642 0:7cf972f622d3 83 template<typename T, unsigned int N>
caoyuan9642 0:7cf972f622d3 84 class OutputQueue: private mbed::NonCopyable<OutputQueue<T, N> >
caoyuan9642 0:7cf972f622d3 85 {
caoyuan9642 0:7cf972f622d3 86 public:
caoyuan9642 0:7cf972f622d3 87
caoyuan9642 0:7cf972f622d3 88 typedef void (*notify_cb)(OutputQueue<T, N> *);
caoyuan9642 0:7cf972f622d3 89
caoyuan9642 0:7cf972f622d3 90 /** Create and initialize a message Queue.
caoyuan9642 0:7cf972f622d3 91 *
caoyuan9642 0:7cf972f622d3 92 * @note You cannot call this function from ISR context.
caoyuan9642 0:7cf972f622d3 93 */
caoyuan9642 0:7cf972f622d3 94 OutputQueue()
caoyuan9642 0:7cf972f622d3 95 {
caoyuan9642 0:7cf972f622d3 96 memset(buf, 0, sizeof(buf));
caoyuan9642 0:7cf972f622d3 97 ntf = NULL;
caoyuan9642 0:7cf972f622d3 98 head = buf;
caoyuan9642 0:7cf972f622d3 99 tail = buf;
caoyuan9642 0:7cf972f622d3 100 }
caoyuan9642 0:7cf972f622d3 101 /** Queue destructor
caoyuan9642 0:7cf972f622d3 102 *
caoyuan9642 0:7cf972f622d3 103 * @note You cannot call this function from ISR context.
caoyuan9642 0:7cf972f622d3 104 */
caoyuan9642 0:7cf972f622d3 105 virtual ~OutputQueue()
caoyuan9642 0:7cf972f622d3 106 {
caoyuan9642 0:7cf972f622d3 107 }
caoyuan9642 0:7cf972f622d3 108
caoyuan9642 0:7cf972f622d3 109 /** Check if the queue is empty
caoyuan9642 0:7cf972f622d3 110 *
caoyuan9642 0:7cf972f622d3 111 * @return True if the queue is empty, false if not
caoyuan9642 0:7cf972f622d3 112 *
caoyuan9642 0:7cf972f622d3 113 * @note You may call this function from ISR context.
caoyuan9642 0:7cf972f622d3 114 */
caoyuan9642 0:7cf972f622d3 115 bool empty() const
caoyuan9642 0:7cf972f622d3 116 {
caoyuan9642 0:7cf972f622d3 117 return head == tail;
caoyuan9642 0:7cf972f622d3 118 }
caoyuan9642 0:7cf972f622d3 119
caoyuan9642 0:7cf972f622d3 120 /** Check if the queue is full
caoyuan9642 0:7cf972f622d3 121 *
caoyuan9642 0:7cf972f622d3 122 * @return True if the queue is full, false if not
caoyuan9642 0:7cf972f622d3 123 *
caoyuan9642 0:7cf972f622d3 124 * @note You may call this function from ISR context.
caoyuan9642 0:7cf972f622d3 125 */
caoyuan9642 0:7cf972f622d3 126 bool full() const
caoyuan9642 0:7cf972f622d3 127 {
caoyuan9642 0:7cf972f622d3 128 return (tail - head == -1) || (tail - head == N - 1);
caoyuan9642 0:7cf972f622d3 129 }
caoyuan9642 0:7cf972f622d3 130
caoyuan9642 0:7cf972f622d3 131 /** Check if the queue is full
caoyuan9642 0:7cf972f622d3 132 *
caoyuan9642 0:7cf972f622d3 133 * @return number of empty space
caoyuan9642 0:7cf972f622d3 134 *
caoyuan9642 0:7cf972f622d3 135 * @note You may call this function from ISR context.
caoyuan9642 0:7cf972f622d3 136 */
caoyuan9642 0:7cf972f622d3 137 int capacity() const
caoyuan9642 0:7cf972f622d3 138 {
caoyuan9642 0:7cf972f622d3 139 return N - (tail - head + N) % N - 1;
caoyuan9642 0:7cf972f622d3 140 }
caoyuan9642 0:7cf972f622d3 141 /** Check if the queue is full
caoyuan9642 0:7cf972f622d3 142 *
caoyuan9642 0:7cf972f622d3 143 * @return number of empty space
caoyuan9642 0:7cf972f622d3 144 *
caoyuan9642 0:7cf972f622d3 145 * @note You may call this function from ISR context.
caoyuan9642 0:7cf972f622d3 146 */
caoyuan9642 0:7cf972f622d3 147 int count() const
caoyuan9642 0:7cf972f622d3 148 {
caoyuan9642 0:7cf972f622d3 149 return (tail - head + N) % N;
caoyuan9642 0:7cf972f622d3 150 }
caoyuan9642 0:7cf972f622d3 151
caoyuan9642 0:7cf972f622d3 152 /** Put a message in a Queue.
caoyuan9642 0:7cf972f622d3 153 @param data message pointer.
caoyuan9642 0:7cf972f622d3 154 @param millisec timeout value or 0 in case of no time-out. (default: osWaitForever)
caoyuan9642 0:7cf972f622d3 155 @return status code that indicates the execution status of the function:
caoyuan9642 0:7cf972f622d3 156 @a osOK the message has been put into the queue.
caoyuan9642 0:7cf972f622d3 157 @a osErrorTimeout the message could not be put into the queue in the given time.
caoyuan9642 0:7cf972f622d3 158
caoyuan9642 0:7cf972f622d3 159 @note You may call this function from ISR context if the millisec parameter is set to 0.
caoyuan9642 0:7cf972f622d3 160 */
caoyuan9642 0:7cf972f622d3 161 osStatus put(const T &data, uint32_t wait = osWaitForever)
caoyuan9642 0:7cf972f622d3 162 {
caoyuan9642 0:7cf972f622d3 163 core_util_critical_section_enter();
caoyuan9642 0:7cf972f622d3 164
caoyuan9642 0:7cf972f622d3 165 // Wait for signal
caoyuan9642 0:7cf972f622d3 166 while (full())
caoyuan9642 0:7cf972f622d3 167 {
caoyuan9642 0:7cf972f622d3 168 if (thq.qwait(wait) == osErrorTimeout)
caoyuan9642 0:7cf972f622d3 169 {
caoyuan9642 0:7cf972f622d3 170 core_util_critical_section_exit();
caoyuan9642 0:7cf972f622d3 171 return osErrorTimeout;
caoyuan9642 0:7cf972f622d3 172 }
caoyuan9642 0:7cf972f622d3 173 }
caoyuan9642 0:7cf972f622d3 174
caoyuan9642 0:7cf972f622d3 175 *tail = data;
caoyuan9642 0:7cf972f622d3 176 if (++tail == buf + N)
caoyuan9642 0:7cf972f622d3 177 tail = buf;
caoyuan9642 0:7cf972f622d3 178
caoyuan9642 0:7cf972f622d3 179 if (ntf)
caoyuan9642 0:7cf972f622d3 180 {
caoyuan9642 0:7cf972f622d3 181 ntf(this);
caoyuan9642 0:7cf972f622d3 182 }
caoyuan9642 0:7cf972f622d3 183 core_util_critical_section_exit();
caoyuan9642 0:7cf972f622d3 184
caoyuan9642 0:7cf972f622d3 185 return osOK;
caoyuan9642 0:7cf972f622d3 186 }
caoyuan9642 0:7cf972f622d3 187
caoyuan9642 0:7cf972f622d3 188 /** Get a message or Wait for a message from a Queue. Messages are retrieved in a descending priority order or
caoyuan9642 0:7cf972f622d3 189 first in first out when the priorities are the same.
caoyuan9642 0:7cf972f622d3 190 @param pdata pointer for return value
caoyuan9642 0:7cf972f622d3 191 @param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
caoyuan9642 0:7cf972f622d3 192 @return status code that indicates the execution status of the function:
caoyuan9642 0:7cf972f622d3 193 @a osOK data retrieved in pdata
caoyuan9642 0:7cf972f622d3 194 @a osEventTimeout no message has arrived during the given timeout period.
caoyuan9642 0:7cf972f622d3 195
caoyuan9642 0:7cf972f622d3 196 @note You may call this function from ISR context if the millisec parameter is set to 0.
caoyuan9642 0:7cf972f622d3 197 */
caoyuan9642 0:7cf972f622d3 198 osStatus get(T *pdata)
caoyuan9642 0:7cf972f622d3 199 {
caoyuan9642 0:7cf972f622d3 200 if (empty())
caoyuan9642 0:7cf972f622d3 201 return osErrorResource;
caoyuan9642 0:7cf972f622d3 202
caoyuan9642 0:7cf972f622d3 203 core_util_critical_section_enter();
caoyuan9642 0:7cf972f622d3 204
caoyuan9642 0:7cf972f622d3 205 *pdata = *head;
caoyuan9642 0:7cf972f622d3 206 if (++head == buf + N)
caoyuan9642 0:7cf972f622d3 207 head = buf;
caoyuan9642 0:7cf972f622d3 208 if (!thq.empty())
caoyuan9642 0:7cf972f622d3 209 {
caoyuan9642 0:7cf972f622d3 210 osThreadId_t th = thq.get();
caoyuan9642 0:7cf972f622d3 211 if (th)
caoyuan9642 0:7cf972f622d3 212 osThreadFlagsSet(th, SIGNAL_QUEUE);
caoyuan9642 0:7cf972f622d3 213 }
caoyuan9642 0:7cf972f622d3 214
caoyuan9642 0:7cf972f622d3 215 core_util_critical_section_exit();
caoyuan9642 0:7cf972f622d3 216
caoyuan9642 0:7cf972f622d3 217 return osOK;
caoyuan9642 0:7cf972f622d3 218 }
caoyuan9642 0:7cf972f622d3 219
caoyuan9642 0:7cf972f622d3 220 void notify(notify_cb cb)
caoyuan9642 0:7cf972f622d3 221 {
caoyuan9642 0:7cf972f622d3 222 ntf = cb;
caoyuan9642 0:7cf972f622d3 223 }
caoyuan9642 0:7cf972f622d3 224
caoyuan9642 0:7cf972f622d3 225 protected:
caoyuan9642 0:7cf972f622d3 226 notify_cb ntf;
caoyuan9642 0:7cf972f622d3 227 T buf[N];
caoyuan9642 0:7cf972f622d3 228 T* head;
caoyuan9642 0:7cf972f622d3 229 T* tail;
caoyuan9642 0:7cf972f622d3 230 ThreadQueue thq;
caoyuan9642 0:7cf972f622d3 231
caoyuan9642 0:7cf972f622d3 232 };
caoyuan9642 0:7cf972f622d3 233
caoyuan9642 0:7cf972f622d3 234 template<typename T, unsigned int N>
caoyuan9642 0:7cf972f622d3 235 class InputQueue: private mbed::NonCopyable<InputQueue<T, N> >
caoyuan9642 0:7cf972f622d3 236 {
caoyuan9642 0:7cf972f622d3 237 public:
caoyuan9642 0:7cf972f622d3 238
caoyuan9642 0:7cf972f622d3 239 typedef void (*notify_cb)(InputQueue<T, N> *);
caoyuan9642 0:7cf972f622d3 240
caoyuan9642 0:7cf972f622d3 241 /** Create and initialize a message Queue.
caoyuan9642 0:7cf972f622d3 242 *
caoyuan9642 0:7cf972f622d3 243 * @note You cannot call this function from ISR context.
caoyuan9642 0:7cf972f622d3 244 */
caoyuan9642 0:7cf972f622d3 245 InputQueue()
caoyuan9642 0:7cf972f622d3 246 {
caoyuan9642 0:7cf972f622d3 247 memset(buf, 0, sizeof(buf));
caoyuan9642 0:7cf972f622d3 248 ntf = NULL;
caoyuan9642 0:7cf972f622d3 249 head = buf;
caoyuan9642 0:7cf972f622d3 250 tail = buf;
caoyuan9642 0:7cf972f622d3 251 }
caoyuan9642 0:7cf972f622d3 252 /** Queue destructor
caoyuan9642 0:7cf972f622d3 253 *
caoyuan9642 0:7cf972f622d3 254 * @note You cannot call this function from ISR context.
caoyuan9642 0:7cf972f622d3 255 */
caoyuan9642 0:7cf972f622d3 256 virtual ~InputQueue()
caoyuan9642 0:7cf972f622d3 257 {
caoyuan9642 0:7cf972f622d3 258 }
caoyuan9642 0:7cf972f622d3 259
caoyuan9642 0:7cf972f622d3 260 /** Check if the queue is empty
caoyuan9642 0:7cf972f622d3 261 *
caoyuan9642 0:7cf972f622d3 262 * @return True if the queue is empty, false if not
caoyuan9642 0:7cf972f622d3 263 *
caoyuan9642 0:7cf972f622d3 264 * @note You may call this function from ISR context.
caoyuan9642 0:7cf972f622d3 265 */
caoyuan9642 0:7cf972f622d3 266 bool empty() const
caoyuan9642 0:7cf972f622d3 267 {
caoyuan9642 0:7cf972f622d3 268 return head == tail;
caoyuan9642 0:7cf972f622d3 269 }
caoyuan9642 0:7cf972f622d3 270
caoyuan9642 0:7cf972f622d3 271 /** Check if the queue is full
caoyuan9642 0:7cf972f622d3 272 *
caoyuan9642 0:7cf972f622d3 273 * @return True if the queue is full, false if not
caoyuan9642 0:7cf972f622d3 274 *
caoyuan9642 0:7cf972f622d3 275 * @note You may call this function from ISR context.
caoyuan9642 0:7cf972f622d3 276 */
caoyuan9642 0:7cf972f622d3 277 bool full() const
caoyuan9642 0:7cf972f622d3 278 {
caoyuan9642 0:7cf972f622d3 279 return (tail - head == -1) || (tail - head == N - 1);
caoyuan9642 0:7cf972f622d3 280 }
caoyuan9642 0:7cf972f622d3 281
caoyuan9642 0:7cf972f622d3 282 /** Check if the queue is full
caoyuan9642 0:7cf972f622d3 283 *
caoyuan9642 0:7cf972f622d3 284 * @return number of empty space
caoyuan9642 0:7cf972f622d3 285 *
caoyuan9642 0:7cf972f622d3 286 * @note You may call this function from ISR context.
caoyuan9642 0:7cf972f622d3 287 */
caoyuan9642 0:7cf972f622d3 288 int capacity() const
caoyuan9642 0:7cf972f622d3 289 {
caoyuan9642 0:7cf972f622d3 290 return N - (tail - head + N) % N - 1;
caoyuan9642 0:7cf972f622d3 291 }
caoyuan9642 0:7cf972f622d3 292 /** Check if the queue is full
caoyuan9642 0:7cf972f622d3 293 *
caoyuan9642 0:7cf972f622d3 294 * @return number of empty space
caoyuan9642 0:7cf972f622d3 295 *
caoyuan9642 0:7cf972f622d3 296 * @note You may call this function from ISR context.
caoyuan9642 0:7cf972f622d3 297 */
caoyuan9642 0:7cf972f622d3 298 int count() const
caoyuan9642 0:7cf972f622d3 299 {
caoyuan9642 0:7cf972f622d3 300 return (tail - head + N) % N;
caoyuan9642 0:7cf972f622d3 301 }
caoyuan9642 0:7cf972f622d3 302
caoyuan9642 0:7cf972f622d3 303 /** Put a message in a Queue.
caoyuan9642 0:7cf972f622d3 304 @param data message pointer.
caoyuan9642 0:7cf972f622d3 305 @param millisec timeout value or 0 in case of no time-out. (default: osWaitForever)
caoyuan9642 0:7cf972f622d3 306 @return status code that indicates the execution status of the function:
caoyuan9642 0:7cf972f622d3 307 @a osOK the message has been put into the queue.
caoyuan9642 0:7cf972f622d3 308 @a osErrorTimeout the message could not be put into the queue in the given time.
caoyuan9642 0:7cf972f622d3 309
caoyuan9642 0:7cf972f622d3 310 @note You may call this function from ISR context if the millisec parameter is set to 0.
caoyuan9642 0:7cf972f622d3 311 */
caoyuan9642 0:7cf972f622d3 312 osStatus put(const T &data)
caoyuan9642 0:7cf972f622d3 313 {
caoyuan9642 0:7cf972f622d3 314 core_util_critical_section_enter();
caoyuan9642 0:7cf972f622d3 315
caoyuan9642 0:7cf972f622d3 316 *tail = data;
caoyuan9642 0:7cf972f622d3 317 if (++tail == buf + N)
caoyuan9642 0:7cf972f622d3 318 tail = buf;
caoyuan9642 0:7cf972f622d3 319
caoyuan9642 0:7cf972f622d3 320 if (!thq.empty())
caoyuan9642 0:7cf972f622d3 321 {
caoyuan9642 0:7cf972f622d3 322 osThreadId_t th = thq.get();
caoyuan9642 0:7cf972f622d3 323 if (th)
caoyuan9642 0:7cf972f622d3 324 osThreadFlagsSet(th, SIGNAL_QUEUE);
caoyuan9642 0:7cf972f622d3 325 }
caoyuan9642 0:7cf972f622d3 326
caoyuan9642 0:7cf972f622d3 327 core_util_critical_section_exit();
caoyuan9642 0:7cf972f622d3 328
caoyuan9642 0:7cf972f622d3 329 return osOK;
caoyuan9642 0:7cf972f622d3 330 }
caoyuan9642 0:7cf972f622d3 331
caoyuan9642 0:7cf972f622d3 332 /** Get a message or Wait for a message from a Queue. Messages are retrieved in a descending priority order or
caoyuan9642 0:7cf972f622d3 333 first in first out when the priorities are the same.
caoyuan9642 0:7cf972f622d3 334 @param pdata pointer for return value
caoyuan9642 0:7cf972f622d3 335 @param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
caoyuan9642 0:7cf972f622d3 336 @return status code that indicates the execution status of the function:
caoyuan9642 0:7cf972f622d3 337 @a osOK data retrieved in pdata
caoyuan9642 0:7cf972f622d3 338 @a osEventTimeout no message has arrived during the given timeout period.
caoyuan9642 0:7cf972f622d3 339
caoyuan9642 0:7cf972f622d3 340 @note You may call this function from ISR context if the millisec parameter is set to 0.
caoyuan9642 0:7cf972f622d3 341 */
caoyuan9642 0:7cf972f622d3 342 osStatus get(T *pdata, uint32_t wait = osWaitForever)
caoyuan9642 0:7cf972f622d3 343 {
caoyuan9642 0:7cf972f622d3 344 core_util_critical_section_enter();
caoyuan9642 0:7cf972f622d3 345
caoyuan9642 0:7cf972f622d3 346 // Wait for non-empty
caoyuan9642 0:7cf972f622d3 347 while (empty())
caoyuan9642 0:7cf972f622d3 348 {
caoyuan9642 0:7cf972f622d3 349 if (thq.qwait(wait) == osErrorTimeout)
caoyuan9642 0:7cf972f622d3 350 {
caoyuan9642 0:7cf972f622d3 351 core_util_critical_section_exit();
caoyuan9642 0:7cf972f622d3 352 return osErrorTimeout;
caoyuan9642 0:7cf972f622d3 353 }
caoyuan9642 0:7cf972f622d3 354 }
caoyuan9642 0:7cf972f622d3 355
caoyuan9642 0:7cf972f622d3 356 *pdata = *head;
caoyuan9642 0:7cf972f622d3 357 if (++head == buf + N)
caoyuan9642 0:7cf972f622d3 358 head = buf;
caoyuan9642 0:7cf972f622d3 359
caoyuan9642 0:7cf972f622d3 360 if (ntf)
caoyuan9642 0:7cf972f622d3 361 {
caoyuan9642 0:7cf972f622d3 362 ntf(this);
caoyuan9642 0:7cf972f622d3 363 }
caoyuan9642 0:7cf972f622d3 364
caoyuan9642 0:7cf972f622d3 365 core_util_critical_section_exit();
caoyuan9642 0:7cf972f622d3 366
caoyuan9642 0:7cf972f622d3 367 return osOK;
caoyuan9642 0:7cf972f622d3 368 }
caoyuan9642 0:7cf972f622d3 369
caoyuan9642 0:7cf972f622d3 370 void notify(notify_cb cb)
caoyuan9642 0:7cf972f622d3 371 {
caoyuan9642 0:7cf972f622d3 372 ntf = cb;
caoyuan9642 0:7cf972f622d3 373 }
caoyuan9642 0:7cf972f622d3 374
caoyuan9642 0:7cf972f622d3 375 protected:
caoyuan9642 0:7cf972f622d3 376 notify_cb ntf;
caoyuan9642 0:7cf972f622d3 377 T buf[N];
caoyuan9642 0:7cf972f622d3 378 T* head;
caoyuan9642 0:7cf972f622d3 379 T* tail;
caoyuan9642 0:7cf972f622d3 380 ThreadQueue thq;
caoyuan9642 0:7cf972f622d3 381
caoyuan9642 0:7cf972f622d3 382 };
caoyuan9642 0:7cf972f622d3 383 /** @}*/
caoyuan9642 0:7cf972f622d3 384 /** @}*/
caoyuan9642 0:7cf972f622d3 385
caoyuan9642 0:7cf972f622d3 386 #endif
caoyuan9642 0:7cf972f622d3 387