Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
OS.hxx
Go to the documentation of this file.
1
35#ifndef _OS_OS_HXX_
36#define _OS_OS_HXX_
37
38#include <endian.h>
39
40#include "utils/macros.h"
41#include "os/os.h"
42
46{
47public:
57 OSThread(const char *name, int priority, size_t stack_size,
58 void *(*start_routine)(void*), void *arg)
59 {
60 os_thread_create(&handle, name, priority, stack_size, start_routine, arg);
61 }
62
66 : handle(0)
67 {
68 }
69
78 void start(const char *name, int priority, size_t stack_size)
79 {
81 os_thread_create(&handle, name, priority, stack_size, start, this);
82 }
83
85 virtual ~OSThread()
86 {
87 }
88
91 {
92 return handle != 0;
93 }
94
96 void inherit()
97 {
100 entry();
101 }
102
107 static int getpriority(OSThread *thread)
108 {
109 return get_priority(thread);
110 }
111
116 static int get_priority(OSThread *thread)
117 {
118 return os_thread_get_priority(thread->handle);
119 }
120
124 static int get_priority_min()
125 {
127 }
128
132 static int get_priority_max()
133 {
135 }
136
138 os_thread_t get_handle()
139 {
140 return handle;
141 }
142
146 {
147 HASSERT(handle == 0);
149 }
150
153 {
154 handle = 0;
155 }
156
159 {
161 : parent_(parent)
162 {
163 parent_->lock_to_thread();
164 }
165
167 {
168 parent_->unlock_from_thread();
169 }
170
171 private:
172 OSThread *parent_;
173 };
174
175protected:
179 virtual void *entry()
180 {
181 HASSERT(0 && "forgot to overload OSThread entry point. This thread "
182 "would do nothing.");
183 return NULL;
184 }
185
186private:
191 static void *start(void *arg)
192 {
193 OSThread *thread = (OSThread*)arg;
194 return thread->entry();
195 }
196
198
200 os_thread_t handle;
201};
202
206{
207public:
211 OSThreadOnce(void (*routine)(void))
214 {
215 }
216
220 int once(void)
221 {
222 return os_thread_once(&handle, routine);
223 }
224
227 {
228 }
229
230private:
232
234 os_thread_once_t handle;
235
237 void (*routine)(void);
238};
239
242class OSSem
243{
244public:
248 OSSem(unsigned int value = 0)
249 {
250 os_sem_init(&handle, value);
251 }
252
253 ~OSSem()
254 {
256 }
257
260 void post()
261 {
263 }
264
265
266#if OPENMRN_FEATURE_RTOS_FROM_ISR
270 void post_from_isr(int *woken)
271 {
272 os_sem_post_from_isr(&handle, woken);
273 }
274#endif // OPENMRN_FEATURE_RTOS_FROM_ISR
275
276
279 void wait()
280 {
282 }
283
284#if OPENMRN_FEATURE_SEM_TIMEDWAIT
289 int timedwait(long long timeout)
290 {
291 return os_sem_timedwait(&handle, timeout);
292 }
293#endif
294
295private:
297
299 os_sem_t handle;
300};
301
304class OSMQ
305{
306public:
307
312 OSMQ(size_t length, size_t item_size)
313 : handle(os_mq_create(length, item_size))
314 {
315 HASSERT(handle != NULL);
316 }
317
321 {
323 }
324
328 void send(const void *data)
329 {
330 os_mq_send(handle, data);
331 }
332
338 int timedsend(const void *data, long long timeout)
339 {
340 return os_mq_timedsend(handle, data, timeout);
341 }
342
346 void receive(void *data)
347 {
348 os_mq_receive(handle, data);
349 }
350
356 int timedreceive(void *data, long long timeout)
357 {
358 return os_mq_timedreceive(handle, data, timeout);
359 }
360
366 int send_from_isr(const void *data, int *woken)
367 {
368 return os_mq_send_from_isr(handle, data, woken);
369 }
370
376 int receive_from_isr(void *data, int *woken)
377 {
378 return os_mq_receive_from_isr(handle, data, woken);
379 }
380
385 {
387 }
388
393 {
394 return os_mq_num_spaces(handle);
395 }
396
401 {
403 }
404
409 {
411 }
412
413private:
417
419 os_mq_t handle;
420
422};
423
427{
428public:
432 OSMutex(bool recursive = false)
433 {
434 if (recursive)
435 {
437 }
438 else
439 {
441 }
442 }
443
446 void lock()
447 {
449 }
450
453 void unlock()
454 {
456 }
457
460 {
462 }
463
464private:
466
467 friend class OSMutexLock;
469 os_mutex_t handle;
470};
471
494{
495public:
498 : mutex_(&mutex->handle)
499 {
501 }
502
504 OSMutexLock(os_mutex_t* mutex)
505 : mutex_(mutex)
506 {
508 }
509
511 {
512 os_mutex_unlock(mutex_);
513 }
514private:
516
518 os_mutex_t* mutex_;
519};
520
544#define OSMutexLock(l) int error_omitted_mutex_lock_variable[-1]
545
549extern "C"
550{
551extern long long rtcOffset;
552}
553
555{
556public:
560 static long long get_monotonic()
561 {
562 return os_get_time_monotonic();
563 }
564
568 static long long get_realtime()
569 {
571 return get_monotonic() + rtcOffset;
572 }
573
576 static void set_realtime(long long time)
577 {
579 rtcOffset = time - get_monotonic();
580 }
581
582private:
584
585 /* Private default constructor prevents instantiating this class. */
586 OSTime();
587
590};
591
592#if defined (__FreeRTOS__)
594typedef EventBits_t OSEventType;
597class OSEvent
598{
599public:
602 enum Test
603 {
604 WAIT_ANY = 0,
605 WAIT_ALL,
606 };
607
610 OSEvent()
611 : event(xEventGroupCreate())
612 {
613 HASSERT(event);
614 }
615
618 ~OSEvent()
619 {
620 vEventGroupDelete(event);
621 }
622
626 static int number_of_bits()
627 {
628#if configUSE_16_BIT_TICKS
629 return 8;
630#else
631 return 24;
632#endif
633 }
634
645 int wait(OSEventType mask, OSEventType *value, bool clear, Test test)
646 {
647 return timedwait(mask, value, clear, test, OPENMRN_OS_WAIT_FOREVER);
648 }
649
661 int timedwait(OSEventType mask, OSEventType *value, bool clear, Test test, long long timeout)
662 {
663 BaseType_t e_clear = clear ? pdTRUE : pdFALSE;
664 BaseType_t e_test = test ? pdTRUE : pdFALSE;
665 TickType_t e_timeout = timeout == OPENMRN_OS_WAIT_FOREVER ? portMAX_DELAY : timeout >> NSEC_TO_TICK_SHIFT;
666
667 OSEventType bits = xEventGroupWaitBits(event, mask, e_clear, e_test, e_timeout);
668
669 if (((bits & mask) == mask && test == WAIT_ALL) ||
670 ((bits & mask) != 0 && test == WAIT_ANY))
671 {
672 // success
673 if (value)
674 {
675 *value = bits;
676 }
677 return 0;
678 }
679 else
680 {
681 // timeout
682 errno = ETIMEDOUT;
683 return -1;
684 }
685 }
686
690 void set(OSEventType mask)
691 {
692 xEventGroupSetBits(event, mask);
693 }
694
699 void set_from_isr(OSEventType mask, int *woken)
700 {
701 portBASE_TYPE local_woken;
702 xEventGroupSetBitsFromISR(event, mask, &local_woken);
703 *woken |= local_woken;
704 }
705
709 void clear(OSEventType mask)
710 {
711 xEventGroupClearBits(event, mask);
712 }
713
717 void clear_from_isr(OSEventType mask)
718 {
719 xEventGroupClearBitsFromISR(event, mask);
720 }
721
725 OSEventType peek()
726 {
727 return xEventGroupGetBits(event);
728 }
729
730private:
732
734 EventGroupHandle_t event;
735};
736#elif defined(ARDUINO) && !defined(ESP_PLATFORM)
737
738typedef uint32_t OSEventType;
739
740extern "C" {
741extern unsigned critical_nesting;
742extern uint32_t SystemCoreClock;
743}
744
745#define cm3_cpu_clock_hz SystemCoreClock
746#define cpu_clock_hz SystemCoreClock
747
748#define portENTER_CRITICAL() \
749 do \
750 { \
751 noInterrupts(); \
752 ++critical_nesting; \
753 } while (0)
754#define portEXIT_CRITICAL() \
755 do \
756 { \
757 if (critical_nesting <= 1) \
758 { \
759 critical_nesting = 0; \
760 interrupts(); \
761 } \
762 else \
763 { \
764 --critical_nesting; \
765 } \
766 } while (0)
767
768#define configKERNEL_INTERRUPT_PRIORITY (0xa0)
769
770#endif // freertos or arduino/esp32
771
772#endif /* _OS_OS_HXX_ */
long long rtcOffset
Allows for OS abstracted access to time.
Definition os.c:98
This class provides a simple message queue.
Definition OS.hxx:305
int timedreceive(void *data, long long timeout)
Receive a message from a queue.
Definition OS.hxx:356
int num_spaces()
Return the number of spaces available.
Definition OS.hxx:392
int receive_from_isr(void *data, int *woken)
Receive a message from a queue from ISR context.
Definition OS.hxx:376
OSMQ(size_t length, size_t item_size)
Constructor.
Definition OS.hxx:312
void receive(void *data)
Blocking receive a message from a queue.
Definition OS.hxx:346
OSMQ()
Default Constructor.
os_mq_t handle
Private message queue handle.
Definition OS.hxx:419
int is_full_from_isr()
Check if a queue is full from ISR context.
Definition OS.hxx:408
int pending_from_isr()
Return the number of messages pending in the queue from ISR context.
Definition OS.hxx:400
int send_from_isr(const void *data, int *woken)
Send of a message to a queue from ISR context.
Definition OS.hxx:366
void send(const void *data)
Blocking send of a message to a queue.
Definition OS.hxx:328
int num_pending()
Return the number of messages pending in the queue.
Definition OS.hxx:384
~OSMQ()
Destructor.
Definition OS.hxx:320
int timedsend(const void *data, long long timeout)
Send a message to a queue with a timeout.
Definition OS.hxx:338
Class to allow convenient locking and unlocking of mutexes in a C context.
Definition OS.hxx:494
os_mutex_t * mutex_
Mutex we are having locked.
Definition OS.hxx:518
OSMutexLock(OSMutex *mutex)
Constructor.
Definition OS.hxx:497
OSMutexLock(os_mutex_t *mutex)
Constructor.
Definition OS.hxx:504
This class provides a mutex API.
Definition OS.hxx:427
os_mutex_t handle
Private mutex handle.
Definition OS.hxx:469
~OSMutex()
Destructor.
Definition OS.hxx:459
void lock()
Lock a mutex.
Definition OS.hxx:446
OSMutex(bool recursive=false)
Initialize a mutex.
Definition OS.hxx:432
void unlock()
Unlock a mutex.
Definition OS.hxx:453
This class provides a counting semaphore API.
Definition OS.hxx:243
os_sem_t handle
Private semaphore handle.
Definition OS.hxx:299
OSSem(unsigned int value=0)
Initialize a Semaphore.
Definition OS.hxx:248
void post()
Post (increment) a semaphore.
Definition OS.hxx:260
void wait()
Wait on (decrement) a semaphore.
Definition OS.hxx:279
This class provides support for one time initialization.
Definition OS.hxx:206
~OSThreadOnce()
Default Destructor.
Definition OS.hxx:226
int once(void)
call one time intialization routine
Definition OS.hxx:220
OSThreadOnce(void(*routine)(void))
One time intialization constructor.
Definition OS.hxx:211
os_thread_once_t handle
Private once handle.
Definition OS.hxx:234
void(* routine)(void)
One time initialization routine.
Definition OS.hxx:237
This class provides a threading API.
Definition OS.hxx:46
static int get_priority(OSThread *thread)
Return the current thread priority.
Definition OS.hxx:116
os_thread_t get_handle()
Definition OS.hxx:138
static int getpriority(OSThread *thread)
Return the current thread priority.
Definition OS.hxx:107
os_thread_t handle
Private thread handle.
Definition OS.hxx:200
static int get_priority_min()
Get the minimum thread priority.
Definition OS.hxx:124
static void * start(void *arg)
Starting point for a new thread.
Definition OS.hxx:191
bool is_created()
Definition OS.hxx:90
void inherit()
Inherits the current thread.
Definition OS.hxx:96
virtual ~OSThread()
Default destructor.
Definition OS.hxx:85
OSThread(const char *name, int priority, size_t stack_size, void *(*start_routine)(void *), void *arg)
Create a thread.
Definition OS.hxx:57
void unlock_from_thread()
Resets the thread handle to none.
Definition OS.hxx:152
void lock_to_thread()
Sets the thread handle to the current calling thread's.
Definition OS.hxx:145
virtual void * entry()
User entry point for the created thread.
Definition OS.hxx:179
static int get_priority_max()
Get the maximum thread priority.
Definition OS.hxx:132
void start(const char *name, int priority, size_t stack_size)
Starts the thread.
Definition OS.hxx:78
OSThread()
Creates a thread via inheritance.
Definition OS.hxx:65
Definition OS.hxx:555
static long long get_realtime()
Get the current RTC time.
Definition OS.hxx:568
static void set_realtime(long long time)
Set the current RTC time.
Definition OS.hxx:576
static long long get_monotonic()
Get the monotonic time since the system started.
Definition OS.hxx:560
~OSTime()
Default destructor.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
Definition macros.h:171
long long os_get_time_monotonic(void)
Get the monotonic time since the system started.
Definition os.c:571
int os_thread_create(os_thread_t *thread, const char *name, int priority, size_t stack_size, void *(*start_routine)(void *), void *arg)
Create a thread.
Definition os.c:450
OS_INLINE void os_mq_receive(os_mq_t queue, void *data)
Blocking receive a message from a queue.
Definition os.h:875
OS_INLINE int os_mq_num_pending_from_isr(os_mq_t queue)
Return the number of messages pending in the queue from ISR context.
Definition os.h:992
OS_INLINE os_mq_t os_mq_create(size_t length, size_t item_size)
Create a new message queue.
Definition os.h:800
OS_INLINE int os_recursive_mutex_init(os_mutex_t *mutex)
Initialize recursive mutex.
Definition os.h:480
OS_INLINE int os_mq_send_from_isr(os_mq_t queue, const void *data, int *woken)
Send of a message to a queue from ISR context.
Definition os.h:923
OS_INLINE int os_mutex_lock(os_mutex_t *mutex)
Lock a mutex.
Definition os.h:533
OS_INLINE int os_mq_is_full_from_isr(os_mq_t queue)
Check if a queue is full from ISR context.
Definition os.h:942
#define OPENMRN_OS_WAIT_FOREVER
maximum timeout period
Definition os.h:219
OS_INLINE int os_thread_once(os_thread_once_t *once, void(*routine)(void))
One time intialization routine.
Definition os.h:201
OS_INLINE int os_thread_get_priority_max(void)
Get the maximum thread priority.
Definition os.h:416
OS_INLINE int os_sem_init(os_sem_t *sem, unsigned int value)
Initialize a semaphore.
Definition os.h:604
OS_INLINE int os_mq_timedsend(os_mq_t queue, const void *data, long long timeout)
Send a message to a queue with a timeout.
Definition os.h:855
OS_INLINE int os_mutex_destroy(os_mutex_t *mutex)
Destroy a mutex.
Definition os.h:515
OS_INLINE int os_thread_get_priority_min(void)
Get the minimum thread priority.
Definition os.h:402
OS_INLINE int os_sem_post(os_sem_t *sem)
Post a semaphore.
Definition os.h:645
OS_INLINE int os_sem_wait(os_sem_t *sem)
Wait on a semaphore.
Definition os.h:681
OS_INLINE int os_mutex_unlock(os_mutex_t *mutex)
Unock a mutex.
Definition os.h:575
OS_INLINE int os_thread_get_priority(os_thread_t thread)
Return the current thread priority.
Definition os.h:385
OS_INLINE os_thread_t os_thread_self(void)
Return a handle to the calling thread.
Definition os.h:370
#define OS_THREAD_ONCE_INIT
initial value for one time intitialization instance
Definition os.h:185
OS_INLINE int os_mq_timedreceive(os_mq_t queue, void *data, long long timeout)
Receive a message from a queue.
Definition os.h:902
OS_INLINE int os_mq_receive_from_isr(os_mq_t queue, void *data, int *woken)
Receive a message from a queue from ISR context.
Definition os.h:959
OS_INLINE int os_mutex_init(os_mutex_t *mutex)
Initialize mutex.
Definition os.h:460
OS_INLINE int os_sem_destroy(os_sem_t *sem)
Destroy a semaphore.
Definition os.h:627
OS_INLINE int os_mq_num_spaces(os_mq_t queue)
Return the number of spaces available in the queue.
Definition os.h:1006
OS_INLINE void os_mq_send(os_mq_t queue, const void *data)
Blocking send of a message to a queue.
Definition os.h:828
OS_INLINE int os_mq_num_pending(os_mq_t queue)
Return the number of messages pending in the queue.
Definition os.h:978
Helper class for using lock_to_thread.
Definition OS.hxx:159