Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <sys/heap.h>
00060 #include <sys/event.h>
00061 #include <sys/atom.h>
00062 #include <sys/thread.h>
00063 #include <sys/msg.h>
00064 #include <stddef.h>
00065
00066
00067 #define ASSERT(x)
00068
00069 struct _NUTMSGTMR {
00070 NUTMSGQ *mt_que;
00071 int mt_param;
00072 void *mt_data;
00073 HANDLE mt_handle;
00074 NUTMSGTMR *mt_next;
00075 uint8_t mt_flags;
00076 };
00077
00082
00086 NUTMSGQ *nutMsgQue;
00087
00088 NUTMSGTMR *nutMsgFreeTimers;
00089
00099 NUTMSGQ *NutMsgQCreate(uint8_t bits)
00100 {
00101
00102 NUTMSGQ *que;
00103 uint8_t len = 1 << bits;
00104
00105 ASSERT(bits < 7);
00106 ASSERT(bits > 0);
00107
00108 que = (NUTMSGQ *) (NutHeapAllocClear(sizeof(NUTMSGQ) + (sizeof(NUTMSG) * (len))));
00109
00110 if (!que)
00111 return que;
00112
00113 que->mq_mask = len - 1;
00114
00115
00116 que->mq_next = nutMsgQue;
00117 nutMsgQue = que;
00118
00119 return que;
00120 }
00121
00132 int NutMsgQBroadcast(uint8_t id, int param, void *data)
00133 {
00134
00135 NUTMSGQ *pCur = nutMsgQue;
00136 int ret = 0;
00137
00138 while (pCur) {
00139 ret -= NutMsgQPost(pCur, id, param, data);
00140 pCur = pCur->mq_next;
00141 }
00142
00143 return ret;
00144 }
00145
00157 int NutMsgQPost(NUTMSGQ * que, uint8_t id, int param, void *data)
00158 {
00159 NUTMSG *cur;
00160 NutEnterCritical();
00161
00162 if (NutMsgQFull(que)) {
00163 NutJumpOutCritical();
00164 return -1;
00165 }
00166
00167 cur = que->mq_que + que->mq_write;
00168
00169 cur->id = id;
00170 cur->param = param;
00171 cur->data = data;
00172
00173 que->mq_write++;
00174 que->mq_write &= que->mq_mask;
00175
00176 NutExitCritical();
00177
00178 NutEventPostAsync(&que->mq_wait);
00179
00180 return 0;
00181 }
00182
00197 int NutMsgQSend(NUTMSGQ * que, uint8_t id, int param, void *data)
00198 {
00199 if (NutMsgQPost(que, id, param, data) == 0) {
00200 NutThreadYield();
00201 return 0;
00202 }
00203 return -1;
00204 }
00205
00211 int NutMsgQFull(NUTMSGQ * que)
00212 {
00213 if (((que->mq_write + 1) & que->mq_mask) == que->mq_read) {
00214 return -1;
00215 }
00216 return 0;
00217 }
00218
00219
00220 static void NutMsgQTimerCb(HANDLE hndl, void *arg)
00221 {
00222 NUTMSGTMR *timer = (NUTMSGTMR *) arg;
00223
00224 if (NutMsgQPost(timer->mt_que, MSG_TIMER, 0, timer)) {
00225
00226
00227
00228
00229
00230 if (timer->mt_flags && TM_ONESHOT) {
00231 timer->mt_handle = NutTimerStartTicks(1, NutMsgQTimerCb, timer, TM_ONESHOT);
00232 }
00233 } else {
00234
00235 if (timer->mt_flags && TM_ONESHOT)
00236 timer->mt_handle = NULL;
00237 }
00238 }
00239
00240
00253 HANDLE NutMsgQStartTimer(NUTMSGQ * que, uint32_t ms, int param, void *data, uint8_t flags)
00254 {
00255 NUTMSGTMR *timer = nutMsgFreeTimers;
00256
00257 ASSERT(flags == TM_ONESHOT || flags == 0);
00258
00259 if (timer != NULL) {
00260 nutMsgFreeTimers = timer->mt_next;
00261 } else {
00262 timer = (NUTMSGTMR *) NutHeapAlloc(sizeof(NUTMSGTMR));
00263 }
00264
00265 timer->mt_que = que;
00266 timer->mt_data = data;
00267 timer->mt_param = param;
00268 timer->mt_flags = flags;
00269 timer->mt_handle = NutTimerStart(ms, NutMsgQTimerCb, timer, flags);
00270
00271 timer->mt_next = que->mq_timers;
00272 que->mq_timers = timer;
00273 return (HANDLE) timer;
00274 }
00275
00276 static void NutMsgQFreeTimer(NUTMSGQ * que, NUTMSGTMR * handle)
00277 {
00278 NUTMSGTMR *tnp = que->mq_timers;
00279 NUTMSGTMR **tnpp = &que->mq_timers;
00280
00281 while (tnp) {
00282 if (tnp == handle) {
00283 *tnpp = tnp->mt_next;
00284 tnp->mt_next = nutMsgFreeTimers;
00285 nutMsgFreeTimers = tnp;
00286 return;
00287 }
00288 tnpp = &tnp->mt_next;
00289 tnp = tnp->mt_next;
00290 }
00291
00292 ASSERT(0);
00293 }
00294
00305 void NutMsgQStopTimer(HANDLE timer)
00306 {
00307 NUTMSGTMR *t = (NUTMSGTMR *) timer;
00308 NUTMSGQ *que = t->mt_que;
00309
00310
00311
00312
00313
00314 NutEnterCritical();
00315 {
00316 uint8_t pos = que->mq_read;
00317
00318 while (pos != que->mq_write) {
00319 if (que->mq_que[pos].id == MSG_TIMER && que->mq_que[pos].data == t) {
00320 que->mq_que[pos].id = MSG_NULL;
00321 }
00322
00323 pos = (pos + 1) & que->mq_mask;
00324 }
00325 }
00326
00327 if (t->mt_handle)
00328 NutTimerStop(t->mt_handle);
00329
00330 NutExitCritical();
00331
00332 NutMsgQFreeTimer(que, t);
00333 }
00334
00345 int NutMsgQGetMessage(NUTMSGQ * que, NUTMSG * msg, uint32_t timeout)
00346 {
00347 NutEnterCritical();
00348
00349 if (NutEventWait(&que->mq_wait, timeout)) {
00350 NutJumpOutCritical();
00351 return -1;
00352 }
00353
00354 ASSERT(que->mq_read != que->mq_write);
00355
00356 *msg = *(que->mq_que + que->mq_read);
00357
00358 que->mq_read++;
00359 que->mq_read &= que->mq_mask;
00360
00361
00362 if (que->mq_read != que->mq_write)
00363 NutEventPostAsync(&que->mq_wait);
00364
00365 NutExitCritical();
00366
00367 if (msg->id == MSG_TIMER) {
00368 NUTMSGTMR *timer = (NUTMSGTMR *) msg->data;
00369 msg->data = timer->mt_data;
00370 msg->param = timer->mt_param;
00371
00372 if (timer->mt_flags & TM_ONESHOT) {
00373 NutMsgQFreeTimer(que, timer);
00374 }
00375 }
00376
00377 return 0;
00378 }
00379
00383 void NutMsgQFlush(NUTMSGQ * que)
00384 {
00385 NutEnterCritical();
00386
00387 que->mq_read = que->mq_write;
00388
00389
00390
00391
00392
00393
00394 que->mq_wait = 0;
00395 NutExitCritical();
00396 }
00397