NetBurner 3.5.6
PDF Version
nbrtos.h
1/*NB_REVISION*/
2
3/*NB_COPYRIGHT*/
4
17#ifndef _NBRTOS_H
18#define _NBRTOS_H
19
20// NB Definitions
21#include <predef.h>
22
23// NB Constants
24#include <constants.h>
25
26// NB Libs
27#include <basictypes.h>
28#include <nbrtoscpu.h>
29#include <predef.h>
30
31/***********************************************************
32 * NBRTOS.H
33 * SYSTEM DECLARATIONS
34 ***********************************************************
35 */
36#define OS_LO_PRIO (OS_MAX_PRIOS-1) /*IDLE task priority */
37
45#define OS_STAT_RDY 0x00
46#define OS_STAT_MBOX 0x01
47#define OS_STAT_SEM 0x02
48#define OS_STAT_Q 0x04
49#define OS_STAT_FIFO 0x08
50#define OS_STAT_CRIT 0x10
51#define OS_STAT_DELAY 0x20
52#define OS_STAT_JOIN 0x40
53#define OS_STAT_RES4 0x40
54#define OS_STAT_RES5 0x80
63#define OS_NO_ERR 0
64#define OS_TIMEOUT 10
65#define OS_MBOX_FULL 20
66#define OS_Q_FULL 30
67#define OS_Q_EXISTS 31
68#define OS_PRIO_EXIST 40
69#define OS_PRIO_INVALID 41
70#define OS_SEM_ERR 50
71#define OS_SEM_OVF 51
72#define OS_CRIT_ERR 60
73#define OS_NO_MORE_TCB 70
83#define OS_TFLAG_IN_USE 0x80
86#define WAIT_FOREVER 0
87
88typedef volatile uint32_t tick_t;
89
91// GLOBAL VARIABLES
92//
93extern vuint32_t Secs; // Number of seconds since system start
94extern volatile tick_t TimeTick; // Number of time ticks since system start
95
96// Is test_time later than now (TimeTick)
97inline bool IsTickLater(uint32_t test_time)
98{
99 return ((int)(TimeTick - test_time) < 0);
100}
101
102// Is test_time NoworEarlier than TimeTick
103inline bool IsTickNowOrEarlier(uint32_t test_time)
104{
105 return ((int)(TimeTick - test_time) >= 0);
106}
107
108// Compare two timetick values
109inline bool Is2ndTickEarlier(uint32_t t1, uint32_t t2)
110{
111 return (((int)(t1 - t2)) > 0);
112}
113
114// Compare two timetick values
115inline bool Is2ndTickNowOrEarlier(uint32_t t1, uint32_t t2)
116{
117 return (((int)(t1 - t2)) >= 0);
118}
119
120class TickTimeout;
121struct RawTickTimeout_t
122{
123 tick_t expiration = 0;
124
125 inline bool expired() const { return expiration ? (((int)(expiration - TimeTick)) <= 0) : false; }
126 inline bool expired() volatile { return expiration ? (((int)(expiration - TimeTick)) <= 0) : false; }
127 inline operator bool() const { return !expired(); }
128 const RawTickTimeout_t &operator=(const TickTimeout &rhs);
129 volatile RawTickTimeout_t &operator=(const TickTimeout &rhs) volatile;
130
131 inline bool operator<(const RawTickTimeout_t &later)
132 {
133 if (!expiration)
134 return false;
135 if (!later.expiration)
136 return true;
137 return (((int)(expiration - later.expiration)) <= 0);
138 }
139
140 inline bool operator<(tick_t later)
141 {
142 if (!expiration)
143 return false;
144 return (((int)(expiration - later)) <= 0);
145 }
146
147 inline tick_t operator-(const tick_t &tick) { return expiration - tick; }
148 inline tick_t operator-(const tick_t &tick) const { return expiration - tick; }
149 inline tick_t operator-(const tick_t &tick) volatile { return expiration - tick; }
150};
151
152inline bool operator==(const RawTickTimeout_t &lhs, const int &rhs)
153{
154 return lhs.expiration == (tick_t)rhs;
155}
156
157inline bool operator==(const volatile RawTickTimeout_t &lhs, const int &rhs)
158{
159 return lhs.expiration == (tick_t)rhs;
160}
161
167class TickTimeout
168{
169 RawTickTimeout_t raw;
170
171 void set(uint32_t timeout)
172 {
173 if (!timeout) { raw.expiration = 0; }
174 else
175 {
176 raw.expiration = TimeTick + (timeout & 0x7FFFFFFF);
177 // A 1 tick delay extension is introduced on TimeTick overflow
178 // in order to allow for infinite delays to be indicated with an
179 // expiration of zero
180 if (timeout && !raw.expiration) { raw.expiration = 1; }
181 }
182 }
183
184 public:
185 class uint32_nonboolean_t
186 {
187 uint32_t value;
188
189 public:
190 uint32_nonboolean_t(uint32_t val) : value(val) {}
191 inline explicit operator bool() { return (bool)value; }
192 inline operator uint32_t() { return value; }
193 };
194
195 explicit TickTimeout() { set(0); }
196
202 TickTimeout(uint32_t timeout) { set(timeout); }
203 TickTimeout(uint16_t timeout) { set(timeout); }
204 TickTimeout(int timeout) { set(timeout); }
205
206
212 inline uint32_t val() const
213 {
214 if (!raw.expiration) { return raw.expiration; }
215 int ret = raw.expiration - TimeTick;
216 // Prevent passing an infinite or otherwise bogus timeout in a tick race
217 return (ret > 0) ? ret : 1;
218 }
219
226 inline bool expired() const { return raw.expired(); }
227
239 inline operator bool() const { return !expired(); }
240
241 inline operator uint32_t() const { return val(); }
242
243 inline operator uint16_t() const
244 {
245 uint32_t ret = val();
246 return ret > 0xFFFF ? 0xFFFE : ret;
247 }
248
249 inline TickTimeout &operator=(const TickTimeout &rhs)
250 {
251 raw.expiration = rhs.raw.expiration;
252 return *this;
253 }
254 inline TickTimeout &operator=(uint32_t val)
255 {
256 set(val);
257 return *this;
258 }
259 inline bool operator<(TickTimeout later)
260 {
261 return raw < later.raw;
262 }
263 inline bool operator<(tick_t later)
264 {
265 return raw < later;
266 }
267 inline TickTimeout &operator+=(uint32_t val)
268 {
269 if (raw.expiration)
270 {
271 raw.expiration += (val & 0x7FFFFFFF);
272 // A 1 tick delay extension is introduced on TimeTick overflow
273 // in order to allow for infinite delays to be indicated with an
274 // expiration of zero
275 if (val && !raw.expiration) { raw.expiration = 1; }
276 }
277 return *this;
278 }
279
285 inline void SetUntil(uint32_t when) {raw.expiration = when; }
286
287 friend void OSTimeWaitUntil(uint32_t systemTickValue);
288
289 friend class RawTickTimeout_t;
290};
291
292inline const RawTickTimeout_t &RawTickTimeout_t::operator=(const TickTimeout &rhs)
293{
294 expiration = rhs.raw.expiration;
295 return *this;
296}
297
298inline volatile RawTickTimeout_t &RawTickTimeout_t::operator=(const TickTimeout &rhs) volatile
299{
300 expiration = rhs.raw.expiration;
301 return *this;
302}
303
304// The following class holds a list of tasks
305
306class task_bit_list
307{
308 public:
309 volatile uint32_t OSTbl[TASK_TABLE_SIZE];
310
311 // task_bit_list();
312 void Init() volatile;
313 void Copy(volatile task_bit_list &rhs)
314 {
315 for (int i = 0; i < TASK_TABLE_SIZE; i++)
316 {
317 OSTbl[i] = rhs.OSTbl[i];
318 }
319 }
320
321 // The following functions are all guaranteed to be atomic
322 void set(int set_num) volatile;
323 void clr(int clr_num) volatile;
324
325 // The following functions return 0 if no bits are set.
326 uint32_t gethigh() volatile;
327 uint32_t get_high_and_clear() volatile;
328
329 inline bool isSet(int num) volatile const { return (OSTbl[num / 32] & (0x80000000 >> (num % 32))); }
330};
331
332class OS_TCB;
333
334// The common element of all the task objects
335class OS_TASK_DLY_OBJ
336{
337 task_bit_list tasks_waiting;
338
339 public:
340 OS_TASK_DLY_OBJ();
341 void Init();
342
343 // Returns true if woken up, returns false if timed out
344 bool Wait_when(uint8_t StatReason, TickTimeout &timeout);
345
346 inline bool Wait(uint8_t StatReason, uint32_t to_count)
347 {
348 TickTimeout to_when(to_count);
349 return Wait_when(StatReason, to_when);
350 }
351
352 // This releases the highest priority task waiting on this object.
353 void MakeHighTaskWaitingReady(uint8_t StatReason);
354 void MakeTaskWaitingReady(uint8_t taskPrio, uint8_t StatReason);
355 void MakeAllWaitingReady(uint8_t StatReason);
356 friend class OS_TCB;
357} __attribute__((packed));
358
359// class OS_TCB;//forward
360
361class OS_TCB : public cpu_tcb
362{
363 public:
364 uint8_t OSTCBStat; // Holds the current status of the TCB
365 uint8_t OSTCBResult; // Basically holds the timeout or not flag when woken.
366 uint8_t OSTCBPrio; // Index to prio table.... not sure if we need to keep this.
367 uint8_t OSTCBFlags; // Make 32 bit aligned.
368
369 RawTickTimeout_t OSTCBDly_when; // When to release timeout the task, 0= never.
370
371 const char *pOSTCBName;
372 OS_TCB *OSTCBNext;
373 OS_TCB *OSTCBPrev;
374
375#ifdef NBRTOS_PRIO_PROMOTION
376 // These pointers are for handling Priority Promotion when OS_CRITs create
377 // an inversion situation
378 volatile OS_TCB *pPromotedTo;
379 volatile OS_TCB *pDisplacedBy;
380 OS_TASK_DLY_OBJ *pWaiting;
381 uint32_t displacedByOrigPrio;
382
383 void PromoteToCurPrio() volatile;
384 void Demote() volatile;
385#endif
386
387 static volatile OS_TCB *GetCur();
388
389#ifdef NBRTOS_TIME
390 unsigned long switchTimeTick;
391 unsigned long switchTimeFraction;
392 unsigned long runningTime;
393 unsigned long runningTimeFraction;
394#endif
395 // OS_TCB(); //Zero everything
396 void Init();
397
398 // Set up TCB assuming that the STACK has already been setup and properly initalized.
399 bool Init(uint8_t prio, void *pActualTop, void *pstk, long *pbot, const char *name);
400};
401
402/* Forward Declaration */
403struct OS_CRIT;
404
410struct OS_SEM : public OS_TASK_DLY_OBJ
411{
412 volatile uint32_t OSSemCnt;
413 volatile uint32_t OSSemUsed;
414
415 private:
416 bool Claim();
417
418 public:
426 inline OS_SEM(int32_t cnt = 0) : OS_TASK_DLY_OBJ() { Init(cnt); }
427
437 uint8_t Init(int32_t cnt = 0);
438
448 uint8_t Post();
449
459 inline uint8_t Pend(uint32_t timeoutTicks = WAIT_FOREVER){TickTimeout tt(timeoutTicks); return Pend(tt);};
460
470 inline uint8_t PendUntil(uint32_t timeout_time){TickTimeout tt(0); tt.SetUntil(timeout_time); return Pend(tt);};
471
481 uint8_t Pend(TickTimeout &t);
482
492 uint8_t PendNoWait();
493
503 inline uint32_t Avail() { uint32_t v; USER_ENTER_CRITICAL(); v=OSSemCnt-OSSemUsed; USER_EXIT_CRITICAL(); return v;};
504
505} __attribute__((packed));
506
521struct OS_MBOX : public OS_TASK_DLY_OBJ
522{
523 void *OSMboxMsg;
524 bool OSMboxDataAvail;
525
526 bool Claim(void *&Result);
527
528 public:
534 inline OS_MBOX() : OS_TASK_DLY_OBJ() { Init(); }
535
543 inline OS_MBOX(void *msg) : OS_TASK_DLY_OBJ() { Init(msg); }
544
554 uint8_t Init(void *msg = NULL);
555
566 uint8_t Post(void *msg);
567
580 inline void *Pend(uint32_t timeoutTicks, uint8_t &result){TickTimeout tt(timeoutTicks); return Pend(tt,result);};
581
594 void *Pend(TickTimeout &t, uint8_t &result);
595
606 inline void *Pend(uint32_t timeoutTicks = WAIT_FOREVER)
607 {
608 uint8_t unused;
609 return Pend(timeoutTicks, unused);
610 };
611
624 inline void *PendUntil(uint32_t timeoutTime, uint8_t &result){TickTimeout tt(0); tt.SetUntil(timeoutTime); return Pend(tt,result);};
625
637 void *PendNoWait(uint8_t &result);
638
647 inline void *PendNoWait()
648 {
649 uint8_t unused;
650 return PendNoWait(unused);
651 };
652};
653
654
655template<typename T>
656class TEMPL_MBOX
657{
658 protected:
659 OS_MBOX m_mbox;
660
661 public:
662 TEMPL_MBOX(const T *msg) : m_mbox((void *)msg) {}
663 inline uint8_t Init(const T *msg) { return m_mbox.Init((void *)msg); }
664 inline uint8_t Post(const T *msg) { return m_mbox.Post((void *)msg); }
665
666 inline T *Pend(uint32_t timeoutTicks, uint8_t &result) { return static_cast<T *>(m_mbox.Pend(timeoutTicks, result)); };
667
668 inline T *PendNoWait(uint8_t &result) { return static_cast<T *>(m_mbox.PendNoWait(result)); };
669
670 inline T *Pend(uint32_t timeoutTicks = WAIT_FOREVER) { return static_cast<T *>(m_mbox.Pend(timeoutTicks)); };
671
672 inline T *PendNoWait() { return static_cast<T *>(m_mbox.PendNoWait()); };
673};
674
675
696struct OS_Q : public OS_TASK_DLY_OBJ
697{
698 void **OSQStart;
699 void **OSQEnd;
700 void **OSQIn;
701 void **OSQOut;
702 uint8_t OSQSize;
703 uint8_t OSQEntries;
704
705 bool Claim(void *&Result);
706
707 public:
723 inline OS_Q(void **pQueueStorage, uint8_t size) : OS_TASK_DLY_OBJ() { Init(pQueueStorage, size); }
724
733 uint8_t Init(void **pQueueStorage, uint8_t size);
734
745 uint8_t Post(void *pItem);
746
757 uint8_t PostFirst(void *pItem);
758
771 uint8_t PostUnique(void *pItem);
772
785 uint8_t PostUniqueFirst(void *msg);
786
799 inline void *Pend(uint32_t timeoutTicks, uint8_t &result){TickTimeout tt(timeoutTicks); return Pend(tt,result);};
800
813 void *Pend(TickTimeout &t, uint8_t &result);
814
825 inline void *Pend(uint32_t timeoutTicks = WAIT_FOREVER)
826 {
827 uint8_t unused;
828 return Pend(timeoutTicks, unused);
829 };
830
843 inline void *PendUntil(uint32_t timeoutTime, uint8_t &result){TickTimeout tt(0); tt.SetUntil(timeoutTime); return Pend(tt,result);};
844
856 void *PendNoWait(uint8_t &result);
857
866 inline void *PendNoWait()
867 {
868 uint8_t unused;
869 return PendNoWait(unused);
870 };
871};
872
877template<typename T>
878struct TEMPL_Q
879{
880 protected:
881 OS_Q m_q;
882
883 public:
884 TEMPL_Q() {}
885 TEMPL_Q(T **pQueueStorage, uint8_t size)
886 : m_q((void**)pQueueStorage,size) { }
887 uint8_t Init(T **pQueueStorage, uint8_t size) { return m_q.Init((void **)pQueueStorage, size); }
888 uint8_t Post(T *item) { return m_q.Post((void *)item); }
889 uint8_t PostFirst(T *item) { return m_q.PostFirst((void *)item); };
890 uint8_t PostUnique(T *item) { return m_q.PostUnique((void *)item); };
891 uint8_t PostUniqueFirst(T *item) { return m_q.PostUniqueFirst((void *)item); };
892
893 inline T *Pend(uint32_t timeoutTicks, uint8_t &result) { return static_cast<T *>(m_q.Pend(timeoutTicks, result)); };
894
895 inline T *Pend(uint32_t timeoutTicks = WAIT_FOREVER) { return static_cast<T *>(m_q.Pend(timeoutTicks)); };
896
897 inline T *PendNoWait() { return static_cast<T *>(m_q.PendNoWait()); };
898
899 inline T *PendNoWait(uint8_t &result) { return static_cast<T *>(m_q.PendNoWait(result)); };
900};
901
908typedef struct os_fifo_el
909{
915 union
916 {
917 struct os_fifo_el *pNextFifo_El;
918 puint8_t pAsBytePtr;
919 };
920} OS_FIFO_EL;
921
931struct OS_FIFO : public OS_TASK_DLY_OBJ
932{
933 OS_FIFO_EL *pHead;
934 OS_FIFO_EL *pTail;
935
936 bool Claim(volatile OS_FIFO_EL *&pToRet);
937
938 public:
944 inline OS_FIFO() : OS_TASK_DLY_OBJ() { Init(); }
945
953 uint8_t Init();
954
966 uint8_t Post(OS_FIFO_EL *pToPost);
967
979 uint8_t PostFirst(OS_FIFO_EL *pToPost);
980
993 inline OS_FIFO_EL *Pend(uint32_t timeoutTicks, uint8_t &result){TickTimeout tt(timeoutTicks); return Pend(tt,result);};
994
1007 OS_FIFO_EL *Pend(TickTimeout &t, uint8_t &result);
1008
1019 inline OS_FIFO_EL *Pend(uint32_t timeoutTicks = WAIT_FOREVER)
1020 {
1021 uint8_t unused;
1022 return Pend(timeoutTicks, unused);
1023 };
1024
1037 inline OS_FIFO_EL *PendUntil(uint32_t timeoutTime, uint8_t &result){TickTimeout tt(0); tt.SetUntil(timeoutTime); return Pend(tt,result);};
1038
1050 OS_FIFO_EL *PendNoWait(uint8_t &result);
1051
1052
1061 inline OS_FIFO_EL *PendNoWait()
1062 {
1063 uint8_t unused;
1064 return PendNoWait(unused);
1065 };
1066};
1067
1068
1069
1070template<typename T>
1071struct TEMPL_FIFO
1072{
1073 protected:
1074 OS_FIFO m_fifo;
1075
1076 public:
1077 TEMPL_FIFO() { m_fifo.Init(); }
1078 uint8_t Init() { return m_fifo.Init(); }
1079 uint8_t Post(T *item) { return m_fifo.Post((OS_FIFO_EL *)item); }
1080 uint8_t PostFirst(T *item) { return m_fifo.PostFirst((OS_FIFO_EL *)item); };
1081
1082 inline T *Pend(uint32_t timeoutTicks, uint8_t &result) { return static_cast<T *>(m_fifo.Pend(timeoutTicks, result)); };
1083
1084 inline T *Pend(uint32_t timeoutTicks = WAIT_FOREVER) { return static_cast<T *>(m_fifo.Pend(timeoutTicks)); };
1085
1086 inline T *PendNoWait() { return static_cast<T *>(m_fifo.PendNoWait()); };
1087
1088 inline T *PendNoWait(uint8_t &result) { return static_cast<T *>(m_fifo.PendNoWait(result)); };
1089
1090 inline OS_FIFO *GetRawFIFO() { return &m_fifo; }
1091};
1092
1093/*
1094 * Critical Section DATA STRUCTURES
1095 *
1096 * Added by PTB 5/09/99
1097 * Modified by DEC 3/21/16
1098 */
1099
1100class BufferCriticalLock;
1102class OS_RRCB;
1103
1109struct OS_CRIT : public OS_TASK_DLY_OBJ
1110{
1111 OS_TCB *OSCritOwnerTCB;
1112 uint32_t OSCritDepthCount;
1113
1114 bool Claim();
1115 OS_TCB *GetOwner() { return (OS_TCB*)(((uint32_t)OSCritOwnerTCB)&~0x1ul); }
1116 void SetOwner(OS_TCB *newOwner)
1117 {
1118 OSCritOwnerTCB =
1119 (OS_TCB*) (((uint32_t)newOwner) | (((uint32_t)OSCritOwnerTCB)&0x1));
1120 }
1121
1122 public:
1128 OS_CRIT() { Init(); }
1129
1137 uint8_t Init();
1138
1154 uint8_t LockAndEnter(uint32_t timeoutTicks = WAIT_FOREVER);
1155
1170 uint8_t Enter(TickTimeout &t);
1171
1186 inline uint8_t Enter(uint32_t timeoutTicks = WAIT_FOREVER) {TickTimeout tt(timeoutTicks); return Enter(tt);};
1187
1199 uint8_t EnterNoWait();
1200
1212 uint8_t Leave();
1213
1224 uint8_t LeaveAndUnlock();
1225
1226 friend class BufferCriticalLock;
1227 friend class fifo_buffer_storage;
1228 friend class OS_RRCB;
1229
1235 bool UsedFromISR() { return (((uint32_t)OSCritOwnerTCB)&0x1ul); }
1236
1244 void SetUseFromISR(bool enableFromISR)
1245 {
1246 if (enableFromISR)
1247 {
1248 OSCritOwnerTCB = (OS_TCB*)(((uint32_t)OSCritOwnerTCB)|0x1ul);
1249 }
1250 else
1251 {
1252 OSCritOwnerTCB = (OS_TCB*)(((uint32_t)OSCritOwnerTCB)&~0x1ul);
1253 }
1254 }
1255
1259 bool OwnedByCurTask();
1260
1266 uint32_t CurDepth() { return OSCritDepthCount; }
1267
1271 friend void ForceReboot(bool fromIRQ);
1272} __attribute__((packed));
1273
1274
1275
1276struct OS_FLAGS_WAIT;
1277
1288struct OS_FLAGS
1289{
1290 protected:
1291 vuint32_t m_current_flags;
1292 void *m_pWaitinglist;
1293 void TestFlags();
1294 void AddOFW(OS_FLAGS_WAIT *ofw);
1295 void RemoveOFW(OS_FLAGS_WAIT *ofw);
1296
1297 public:
1303 OS_FLAGS();
1304
1310 void Init();
1311
1319 void Set(uint32_t bits_to_set);
1320
1328 void Clear(uint32_t bits_to_clr);
1329
1330
1338 void Write(uint32_t bits_to_force);
1339
1347 uint32_t State();
1348
1363 uint8_t PendAny(uint32_t bit_mask, uint16_t timeout = WAIT_FOREVER){TickTimeout tt(timeout); return PendAny(bit_mask,tt);}
1364
1379 uint8_t PendAny(uint32_t bit_mask, TickTimeout & timeout);
1380
1381
1393 uint8_t PendAnyUntil(uint32_t bit_mask, uint32_t end_time){TickTimeout tt(0); tt.SetUntil(end_time); return PendAny(bit_mask,tt);}
1394
1395
1405 uint8_t PendAnyNoWait(uint32_t bit_mask);
1406
1420 uint8_t PendAll(uint32_t bit_mask, uint16_t timeout = WAIT_FOREVER){TickTimeout tt(timeout); return PendAll(bit_mask,tt);}
1421
1435 uint8_t PendAll(uint32_t bit_mask,TickTimeout & timeout);
1436
1448 uint8_t PendAllUntil(uint32_t bit_mask, uint32_t end_time){TickTimeout tt(0); tt.SetUntil(end_time); return PendAll(bit_mask,tt);}
1449
1450
1461 uint8_t PendAllNoWait(uint32_t bit_mask);
1462
1463};
1464
1465
1466/* Create and initialize an OS flags object
1467This function must be called before you use an OS_FLAGS object.
1468*/
1469[[deprecated]] inline void OSFlagCreate(OS_FLAGS *pf)
1470{
1471 pf->Init();
1472};
1473
1484[[deprecated]] inline void OSFlagSet(OS_FLAGS *flags, uint32_t bits_to_set)
1485{
1486 flags->Set(bits_to_set);
1487};
1488
1499[[deprecated]] inline void OSFlagClear(OS_FLAGS *flags, uint32_t bits_to_clr)
1500{
1501 flags->Clear(bits_to_clr);
1502};
1503
1518[[deprecated]] inline uint8_t OSFlagPendAny(OS_FLAGS *flags, uint32_t bit_mask, uint16_t timeout)
1519{
1520 return flags->PendAny(bit_mask, timeout);
1521};
1522
1536[[deprecated]] inline uint8_t OSFlagPendAnyNoWait(OS_FLAGS *flags, uint32_t bit_mask)
1537{
1538 return flags->PendAnyNoWait(bit_mask);
1539};
1540
1555[[deprecated]] inline uint8_t OSFlagPendAll(OS_FLAGS *flags, uint32_t bit_mask, uint16_t timeout)
1556{
1557 return flags->PendAll(bit_mask, timeout);
1558};
1559
1573[[deprecated]] inline uint8_t OSFlagPendAllNoWait(OS_FLAGS *flags, uint32_t bit_mask)
1574{
1575 return flags->PendAllNoWait(bit_mask);
1576};
1577
1589[[deprecated]] inline uint32_t OSFlagState(OS_FLAGS *flags)
1590{
1591 return flags->State();
1592};
1593
1594/*
1595 ***********************************************************
1596 * NBRTOS GLOBAL VARIABLES
1597 ***********************************************************
1598 */
1599// Pointers to each of the OS_TCB structure sorted by priority
1600extern volatile OS_TCB *OSTCBPrioTbl[OS_MAX_PRIOS];
1601
1602// taks bits for what tasks are ready to run
1603extern volatile task_bit_list OSTaskReadyList;
1604#ifdef NBRTOS_PRIO_PROMOTION
1605extern volatile task_bit_list OSInUsePrioList FAST_SYS_VAR;
1606extern volatile task_bit_list OSActivePrioList FAST_SYS_VAR;
1607#endif
1608
1609extern OS_TCB OSTCBTbl[OS_MAX_TASKS]; // All the possible TCB's
1610
1611extern OS_TCB *pOSActiveTCBList; // Linked list of activ TCB's
1612
1613// One of the following two variables wsill go away....
1614extern volatile uint32_t nPrioOfCurTask; // Current task priority number
1615extern volatile uint32_t nPrioOfHighReady; // highest task ready to run
1616extern volatile OS_TCB *OSTCBCur;
1617extern volatile OS_TCB *OSTCBHighRdy;
1618
1619extern OS_TCB *pOSTCBFreeList; // List of unused TCB's
1620
1621extern volatile uint32_t OSIntNesting;
1622extern volatile uint32_t OSLockNesting;
1623extern volatile uint32_t OSISRLevel32;
1624
1625extern volatile bool OSRunning;
1626
1627// So non-recompilable files can reference the right struct size
1628extern unsigned long OSTcbStructSize;
1629
1630#ifdef NBRTOS_TASK_LOG
1631extern void (*pTaskLogger)(uint8_t nextPrio);
1632#endif
1633/*
1634Removed
1635 extern volatile BOOLEAN OSShowTasksOnLeds;
1636*/
1637
1638/*
1639***********************************************************
1640* NBRTOS FUNCTION PROTOTYPES
1641***********************************************************
1642*/
1643void OSInit(uint8_t maxtasks);
1644void OSStart(void);
1645void OSCreateIdleTask();
1646
1719uint8_t OSTaskCreatewName(void (*task)(void *dptr), // Function to call
1720 void *data, // Data to pass as a parameter
1721 void *pstktop, // Stack top
1722 void *pstkbot, // Stack bottom
1723 uint8_t prio, // current priority
1724 const char *name, // task name
1725 OS_TCB **pRetHandle = NULL // ReturnPointer to task handle
1726);
1727
1767#define OSSimpleTaskCreatewName(x, p, n) \
1768 [&]() { \
1769 static uint32_t func_##x##_Stk[USER_TASK_STK_SIZE] __attribute__((aligned(4))); \
1770 return OSTaskCreatewName(x, NULL, (void *)&func_##x##_Stk[USER_TASK_STK_SIZE], (void *)func_##x##_Stk, p, n); \
1771 }()
1772
1789#define OSSimpleTaskCreatewNameSRAM(x, p, n) \
1790 [&]() { \
1791 static uint32_t func_##x##_Stk[USER_TASK_STK_SIZE] __attribute__((aligned(4))) FAST_USER_STK; \
1792 return OSTaskCreatewName(x, NULL, (void *)&func_##x##_Stk[USER_TASK_STK_SIZE], (void *)func_##x##_Stk, p, n); \
1793 }()
1794
1795
1796/* Helper macro*/
1797#define LambdaTask2(p,n,f,vn) static uint32_t func_##vn_Stk[USER_TASK_STK_SIZE] __attribute__((aligned(4)));OSTaskCreatewName(f, NULL, (void *)&func_##vn_Stk[USER_TASK_STK_SIZE], (void *)func_##vn_Stk, p, n)
1798
1814#define OSSimpleTaskCreateLambda(p,n,f) LambdaTask2(p,n,[]( void * pv)f,__COUNTER__)
1815
1816
1836void OSTimeWaitUntil(uint32_t systemTickValue);
1837
1850inline void OSTimeDly(uint32_t to_count)
1851{
1852 uint32_t to_when = to_count + TimeTick;
1853 if (!to_when) to_when++;
1854 OSTimeWaitUntil(to_when);
1855};
1856
1857// void OSIntEnter( void );
1858
1859extern "C"
1860{
1861 void OSIntExit(void);
1862 void OSCtxSw(void);
1863 void OSTickISR(void);
1864 void OSStartHighRdy(void);
1865 void OSSetupVBR(void);
1866 void OSSched(void);
1867 void OSTimeTick(void);
1868
1879 void OSTaskDelete(void);
1880}
1881
1882OS_TCB *OSTCBGetFree(void);
1883
1902uint8_t OSChangePrio(uint32_t newp);
1903
1910void OSSetName(const char *cp);
1911
1925void OSLock(void);
1926
1934void OSUnlock(void);
1935
1950[[deprecated]] inline uint8_t OSSemInit(OS_SEM *psem, long value)
1951{
1952 return (psem != nullptr) ? psem->Init(value) : OS_CRIT_ERR;
1953}
1954
1968[[deprecated]] inline uint8_t OSSemPost(OS_SEM *psem)
1969{
1970 return psem->Post();
1971}
1972
1987[[deprecated]] inline uint8_t OSSemPend(OS_SEM *psem, uint16_t timeout)
1988{
1989 return psem->Pend(timeout);
1990}
1991
2004[[deprecated]] inline uint8_t OSSemPendNoWait(OS_SEM *psem)
2005{
2006 return psem->PendNoWait();
2007}
2008
2022[[deprecated]] inline uint8_t OSMboxInit(OS_MBOX *pmbox, void *msg)
2023{
2024 return (pmbox != nullptr) ? pmbox->Init(msg) : OS_CRIT_ERR;
2025}
2026
2040[[deprecated]] inline uint8_t OSMboxPost(OS_MBOX *pmbox, void *msg)
2041{
2042 return pmbox->Post(msg);
2043}
2044
2056[[deprecated]] inline void *OSMboxPend(OS_MBOX *pmbox, uint16_t timeout, uint8_t *err)
2057{
2058 return pmbox->Pend(timeout, *err);
2059}
2060
2071[[deprecated]] inline void *OSMboxPendNoWait(OS_MBOX *pmbox, uint8_t *err)
2072{
2073 return pmbox->PendNoWait(*err);
2074}
2075
2090[[deprecated]] inline uint8_t OSQInit(OS_Q *pq, void **start, uint8_t size)
2091{
2092 return (pq != nullptr) ? pq->Init(start, size) : OS_CRIT_ERR;
2093}
2094
2108[[deprecated]] inline uint8_t OSQPost(OS_Q *pq, void *msg)
2109{
2110 return pq->Post(msg);
2111}
2112
2126[[deprecated]] inline uint8_t OSQPostFirst(OS_Q *pq, void *msg)
2127{
2128 return pq->PostFirst(msg);
2129}
2130
2146[[deprecated]] inline uint8_t OSQPostUnique(OS_Q *pq, void *msg)
2147{
2148 return pq->PostUnique(msg);
2149}
2150
2166[[deprecated]] inline uint8_t OSQPostUniqueFirst(OS_Q *pq, void *msg)
2167{
2168 return pq->PostUniqueFirst(msg);
2169}
2170
2182[[deprecated]] inline void *OSQPend(OS_Q *pq, uint16_t timeout, uint8_t *err)
2183{
2184 return pq->Pend(timeout, *err);
2185}
2186
2197[[deprecated]] inline void *OSQPendNoWait(OS_Q *pq, uint8_t *err)
2198{
2199 return pq->PendNoWait(*err);
2200}
2201
2214[[deprecated]] inline uint8_t OSFifoInit(OS_FIFO *pFifo)
2215{
2216 return (pFifo != nullptr) ? pFifo->Init() : OS_CRIT_ERR;
2217}
2218
2231[[deprecated]] inline uint8_t OSFifoPost(OS_FIFO *pFifo, OS_FIFO_EL *pToPost)
2232{
2233 return pFifo->Post(pToPost);
2234}
2247[[deprecated]] inline uint8_t OSFifoPostFirst(OS_FIFO *pFifo, OS_FIFO_EL *pToPost)
2248{
2249 return pFifo->PostFirst(pToPost);
2250};
2251
2262[[deprecated]] inline OS_FIFO_EL *OSFifoPend(OS_FIFO *pFifo, uint16_t timeout)
2263{
2264 return pFifo->Pend(timeout);
2265};
2266
2276[[deprecated]] inline OS_FIFO_EL *OSFifoPendNoWait(OS_FIFO *pFifo)
2277{
2278 return pFifo->PendNoWait();
2279 ;
2280}
2281
2293[[deprecated]] inline uint8_t OSCritInit(OS_CRIT *pCrit)
2294{
2295 return pCrit->Init();
2296}
2297[[deprecated]] inline uint8_t OSCritLockAndEnter(OS_CRIT *pCrit, uint16_t timeout)
2298{
2299 return pCrit->LockAndEnter(timeout);
2300}
2301
2315[[deprecated]] inline uint8_t OSCritEnter(OS_CRIT *pCrit, uint16_t timeout)
2316{
2317 return pCrit->Enter(timeout);
2318}
2319
2332[[deprecated]] inline uint8_t OSCritEnterNoWait(OS_CRIT *pCrit)
2333{
2334 return pCrit->EnterNoWait();
2335}
2336
2349[[deprecated]] inline uint8_t OSCritLeave(OS_CRIT *pCrit)
2350{
2351 return pCrit->Leave();
2352}
2353[[deprecated]] inline uint8_t OSCritLeaveAndUnlock(OS_CRIT *pCrit)
2354{
2355 return pCrit->LeaveAndUnlock();
2356}
2357
2363uint8_t OSTaskID(void);
2364
2369enum class OSNextPrio {
2370 Maximum = -2,
2371 Above = -1,
2372 Below = 0,
2373 Next = Below,
2374 Minimum = 1
2375};
2376
2385int OSGetNextPrio(OSNextPrio where=OSNextPrio::Below, int startingPrio = -1);
2386
2390const char *OSTaskName();
2391
2392void OSChangeTaskWhen(uint16_t task_prio, uint32_t to_when);
2393
2404inline void OSChangeTaskDly(uint16_t task_prio, uint32_t to_count)
2405{
2406 uint32_t to_when = to_count + TimeTick;
2407 if (!to_when) to_when++;
2408 OSChangeTaskWhen(task_prio, to_when);
2409}
2410
2419OS_TCB * OSGetTaskBlock(uint16_t task_prio);
2420
2432uint8_t OSTaskJoin(OS_TCB *pTask, uint32_t timeoutDly = 0);
2433
2437void OSDumpStack(void);
2438
2439#if (defined NBRTOS_STACKOVERFLOW) || (defined NBRTOS_STACKUNDERFLOW)
2440void EnableOSStackProtector();
2441extern "C" void OSStackProtectCtxSw(); // ASM task switcher
2442extern "C" void OSStackProtectIntCtxSw(); // ASM task switcher
2443extern "C" void OSStackProtector(); // extern because must be called from ASM
2444#endif
2445
2446#ifdef NBRTOS_STACKCHECK
2455void OSDumpTCBStacks(void);
2456
2465void OSDumpTasks(void);
2466
2475void OSStartTaskDumper(uint8_t prio, uint32_t reportInterval);
2476#endif
2477
2478#ifdef NBRTOS_TASKLIST
2484void ShowTaskList(void);
2485#endif
2486
2487#ifdef NBRTOS_TIME
2488uint32_t GetCurrentTaskTime(uint32_t *const TotalTicks);
2489void ShowTaskTimes(void);
2490void ClearTaskTimes(void);
2491#endif
2492
2504class OSLockObj
2505{
2506 public:
2510 OSLockObj() { OSLock(); };
2511
2515 ~OSLockObj() { OSUnlock(); };
2516} __attribute__((packed));
2517
2527class OSCriticalSectionObj
2528{
2529 OS_CRIT *pcrit;
2530
2531 public:
2538 OSCriticalSectionObj(OS_CRIT &ocrit)
2539 {
2540 pcrit = &ocrit;
2541 ocrit.Enter(0);
2542 };
2543
2552 OSCriticalSectionObj(OS_CRIT &ocrit, bool NoWait, TickTimeout &timeout)
2553 {
2554 pcrit = &ocrit;
2555 if (NoWait)
2556 ocrit.EnterNoWait();
2557 else
2558 ocrit.Enter(timeout);
2559 };
2560
2565 ~OSCriticalSectionObj() { pcrit->Leave(); }
2566} __attribute__((packed));
2567
2578class OSLockAndCritObj
2579{
2580 OS_CRIT *pcrit;
2581
2582 public:
2589 OSLockAndCritObj(OS_CRIT &ocrit) : pcrit(&ocrit) { pcrit->LockAndEnter(0); }
2590
2595 ~OSLockAndCritObj() { pcrit->LeaveAndUnlock(); }
2596};
2597
2609class OSSpinCrit
2610{
2611 OS_CRIT *pcrit;
2612
2613 public:
2620 OSSpinCrit(OS_CRIT &ocrit) : pcrit(&ocrit)
2621 {
2622 while (pcrit->EnterNoWait() == OS_TIMEOUT) {}
2623 }
2624
2629 ~OSSpinCrit() { pcrit->Leave(); }
2630};
2631
2632
2636class USERCritObj
2637{
2638 public:
2639 USERCritObj() { USER_ENTER_CRITICAL(); }
2640 ~USERCritObj() { USER_EXIT_CRITICAL(); }
2641};
2642
2643
2644
2651inline bool OS_CRIT::OwnedByCurTask()
2652{
2653 return OSCritOwnerTCB == OSTCBCur;
2654}
2655
2667class NBRtosInitObj
2668{
2669 static NBRtosInitObj * pHead;
2670 static bool bAlreadInited;
2671 NBRtosInitObj *pNext;
2672
2673 protected:
2674 inline bool WasInitDone() {return bAlreadInited; }
2675 NBRtosInitObj();
2676 ~NBRtosInitObj();
2677
2678 public:
2682 virtual void Notify()=0;
2683 static void InitWholeSet(); //Used internally
2684};
2685
2686
2687#endif
2688
2689
2690
2691
FIFO buffer storage using linked pool buffers.
Definition buffers.h:443
#define OS_MAX_TASKS
Max number of system tasks.
Definition constants.h:97
#define OS_MAX_PRIOS
Maximum number of system priorities (NBRTOS limit: 256)
Definition constants.h:101
void ForceReboot(bool fromIRQ=false)
Initiates an immediate hardware-level system reset of the NetBurner device.