Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
os.h
Go to the documentation of this file.
1
35#ifndef _OS_OS_H_
36#define _OS_OS_H_
37
38#include <sys/time.h>
39#include <stdlib.h>
40#include <errno.h>
41#include <string.h>
42#include <limits.h>
43#include <stdint.h>
44
45#include "openmrn_features.h"
46
47#if OPENMRN_FEATURE_MUTEX_FREERTOS
48#include "freertos_includes.h"
49#endif
50#if OPENMRN_FEATURE_DEVICE_SELECT
51#include <event_groups.h>
52#endif
53
54#if OPENMRN_FEATURE_MUTEX_PTHREAD
55#include <pthread.h>
56#include <semaphore.h>
57#endif
58
59#if defined (__MACH__)
60#include <mach/mach_time.h>
61#endif
62
63#if defined (__WIN32__)
64#include <sys/time.h>
65#include <unistd.h>
66#endif
67
68#include "utils/macros.h"
69
70#ifdef __cplusplus
71extern "C" {
72#endif
73
74
75#ifndef OS_INLINE
77#define OS_INLINE extern inline __attribute__((__gnu_inline__))
78#endif
79
85int appl_main(int argc, char *argv[]);
86
88ssize_t os_get_free_heap(void);
89
90#if defined (__FreeRTOS__)
91
92extern void hw_init(void);
93
95extern const size_t main_stack_size;
96
98extern const int main_priority;
99#endif
100
101#if OPENMRN_FEATURE_MUTEX_FREERTOS
102typedef xTaskHandle os_thread_t;
103typedef struct
104{
105 xSemaphoreHandle sem;
106 char recursive;
107} os_mutex_t;
108typedef xQueueHandle os_mq_t;
109typedef struct
110{
111 unsigned char state;
112} os_thread_once_t;
113typedef xSemaphoreHandle os_sem_t;
114#endif
115#if OPENMRN_FEATURE_MUTEX_FAKE
116typedef struct {
117 int locked;
118 uint8_t recursive;
119} os_mutex_t;
120typedef struct
121{
122 unsigned char state;
123} os_thread_once_t;
124typedef struct {
125 unsigned counter;
126} os_sem_t;
127
128typedef unsigned os_thread_t;
129typedef void *os_mq_t;
130#endif
131#if OPENMRN_FEATURE_MUTEX_PTHREAD
132typedef pthread_t os_thread_t;
133typedef pthread_mutex_t os_mutex_t;
134typedef void *os_mq_t;
135typedef pthread_once_t os_thread_once_t;
137typedef struct
138{
140 pthread_cond_t cond;
142 pthread_mutex_t mutex;
144 int counter;
145} os_sem_t;
146#endif
147
148#ifndef container_of
155#define container_of(_ptr, _type, _member) \
156({ \
157 const typeof( ((_type *)0)->_member ) *__mptr = (_ptr); \
158 (_type *)( (char *)__mptr - offsetof(_type,_member) ); \
159})
160#endif
161
165extern long long os_get_time_monotonic(void);
166
170extern long long os_get_fake_time(void);
171
172#ifndef OPENMRN_FEATURE_MUTEX_PTHREAD
175enum
176{
177 OS_THREAD_ONCE_NEVER = 0,
178 OS_THREAD_ONCE_INPROGRESS,
179 OS_THREAD_ONCE_DONE
180};
182#define OS_THREAD_ONCE_INIT { OS_THREAD_ONCE_NEVER }
183#else
185#define OS_THREAD_ONCE_INIT PTHREAD_ONCE_INIT
186#endif
187
188#ifndef OPENMRN_FEATURE_MUTEX_PTHREAD
194int os_thread_once(os_thread_once_t *once, void (*routine)(void));
195#else
201OS_INLINE int os_thread_once(os_thread_once_t *once, void (*routine)(void))
202{
203 return pthread_once(once, routine);
204}
205#endif
206
207#define OS_PRIO_MIN 1
208#define OS_PRIO_DEFAULT 0
209#define OS_PRIO_MAX 32
211#define OS_MQ_NONE 0
212#define OS_MQ_TIMEDOUT 1
213#define OS_MQ_EMPTY 2
214#define OS_MQ_FULL 3
216#if defined LLONG_MAX
217#define OPENMRN_OS_WAIT_FOREVER LLONG_MAX
218#else
219#define OPENMRN_OS_WAIT_FOREVER __LONG_LONG_MAX__
220#endif
221
226#define NSEC_TO_USEC(_nsec) (((long long)_nsec) / 1000LL)
227
232#define NSEC_TO_MSEC(_nsec) (((long long)_nsec) / 1000000LL)
233
238#define NSEC_TO_SEC(_nsec) (((long long)_nsec) / 1000000000LL)
239
244#define NSEC_TO_MIN(_nsec) (((long long)_nsec) / 60000000000LL)
245
250#define USEC_TO_NSEC(_usec) (((long long)_usec) * 1000LL)
251
256#define USEC_TO_MSEC(_usec) (((long long)_usec) / 1000LL)
257
262#define USEC_TO_SEC(_usec) (((long long)_usec) / 1000000LL)
263
268#define MSEC_TO_NSEC(_msec) (((long long)_msec) * 1000000LL)
269
274#define MSEC_TO_USEC(_msec) (((long long)_msec) * 1000LL)
275
280#define MSEC_TO_SEC(_msec) (((long long)_msec) / 1000LL)
281
286#define SEC_TO_NSEC(_sec) (((long long)_sec) * 1000000000LL)
287
292#define SEC_TO_USEC(_sec) (((long long)_sec) * 1000000LL)
293
298#define SEC_TO_MSEC(_sec) (((long long)_sec) * 1000LL)
299
304#define NSEC_TO_USEC_ROUNDED(_nsec) \
305 ((((long long)_nsec) + 500LL) / 1000LL)
306
311#define NSEC_TO_MSEC_ROUNDED(_nsec) \
312 ((((long long)_nsec) + 500000LL) / 1000000LL)
313
318#define NSEC_TO_SEC_ROUNDED(_nsec) \
319 ((((long long)_nsec) + 500000000LL) / 1000000000LL)
320
325#define NSEC_TO_MIN_ROUNDED(_nsec) \
326 ((((long long)_nsec) + 30000000000LL) / 60000000000LL)
327
332#define USEC_TO_MSEC_ROUNDED(_usec) \
333 ((((long long)_usec) + 500LL) / 1000LL)
334
339#define USEC_TO_SEC_ROUNDED(_usec) \
340 ((((long long)_usec) +500000LL) / 1000000LL)
341
346#define MSEC_TO_SEC_ROUNDED(_msec) \
347 ((((long long)_msec) + 500LL) / 1000LL)
348
358int os_thread_create(os_thread_t *thread, const char *name, int priority,
359 size_t stack_size,
360 void *(*start_routine) (void *), void *arg);
361
365void os_thread_cancel(os_thread_t thread);
366
370OS_INLINE os_thread_t os_thread_self(void)
371{
372#if OPENMRN_FEATURE_MUTEX_FREERTOS
373 return xTaskGetCurrentTaskHandle();
374#elif OPENMRN_FEATURE_SINGLE_THREADED
375 return 0xdeadbeef;
376#elif OPENMRN_FEATURE_MUTEX_PTHREAD
377 return pthread_self();
378#endif
379}
380
385OS_INLINE int os_thread_get_priority(os_thread_t thread)
386{
387#if OPENMRN_FEATURE_MUTEX_FREERTOS
388 return uxTaskPriorityGet(thread);
389#elif OPENMRN_FEATURE_SINGLE_THREADED
390 return 2;
391#elif OPENMRN_FEATURE_MUTEX_PTHREAD
392 struct sched_param params;
393 int policy;
394 pthread_getschedparam(thread, &policy, &params);
395 return params.sched_priority;
396#endif
397}
398
403{
404#if OPENMRN_FEATURE_MUTEX_FREERTOS
405 return 1;
406#elif OPENMRN_FEATURE_SINGLE_THREADED
407 return 2;
408#elif OPENMRN_FEATURE_MUTEX_PTHREAD
409 return sched_get_priority_min(SCHED_FIFO);
410#endif
411}
412
417{
418#if OPENMRN_FEATURE_MUTEX_FREERTOS
419 return configMAX_PRIORITIES - 1;
420#elif OPENMRN_FEATURE_SINGLE_THREADED
421 return 2;
422#elif OPENMRN_FEATURE_MUTEX_PTHREAD
423 return sched_get_priority_max(SCHED_FIFO);
424#endif
425}
426
427#if OPENMRN_FEATURE_MUTEX_FREERTOS
429#define OS_MUTEX_INITIALIZER {NULL, 0}
431#define OS_RECURSIVE_MUTEX_INITIALIZER {NULL, 1}
432#elif OPENMRN_FEATURE_MUTEX_FAKE
434#define OS_MUTEX_INITIALIZER {0, 0}
436#define OS_RECURSIVE_MUTEX_INITIALIZER {0, 1}
437#elif OPENMRN_FEATURE_MUTEX_PTHREAD
439#define OS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
440
441#if defined (__nuttx__)
443#define OS_RECURSIVE_MUTEX_INITIALIZER {0, SEM_INITIALIZER(1), PTHREAD_MUTEX_RECURSIVE, 0}
444#elif defined (__MACH__)
445#define OS_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER
446#else
448#define OS_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
449#endif
450#endif
451
452#ifdef __EMSCRIPTEN__
453extern void os_emscripten_yield();
454#endif
455
460OS_INLINE int os_mutex_init(os_mutex_t *mutex)
461{
462#if OPENMRN_FEATURE_MUTEX_FREERTOS
463 mutex->recursive = 0;
464 mutex->sem = xSemaphoreCreateMutex();
465
466 return 0;
467#elif OPENMRN_FEATURE_MUTEX_FAKE
468 mutex->locked = 0;
469 mutex->recursive = 0;
470 return 0;
471#elif OPENMRN_FEATURE_MUTEX_PTHREAD
472 return pthread_mutex_init(mutex, NULL);
473#endif
474}
475
480OS_INLINE int os_recursive_mutex_init(os_mutex_t *mutex)
481{
482#if OPENMRN_FEATURE_MUTEX_FREERTOS
483 mutex->recursive = 1;
484 mutex->sem = xSemaphoreCreateRecursiveMutex();
485
486 return 0;
487#elif OPENMRN_FEATURE_MUTEX_FAKE
488 mutex->locked = 0;
489 mutex->recursive = 1;
490 return 0;
491#elif OPENMRN_FEATURE_MUTEX_PTHREAD
492 pthread_mutexattr_t attr;
493 int result;
494
495 result = pthread_mutexattr_init(&attr);
496 if (result != 0)
497 {
498 return result;
499 }
500
501 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
502 if (result != 0)
503 {
504 return result;
505 }
506
507 return pthread_mutex_init(mutex, &attr);
508#endif
509}
510
515OS_INLINE int os_mutex_destroy(os_mutex_t *mutex)
516{
517#if OPENMRN_FEATURE_MUTEX_FREERTOS
518 vSemaphoreDelete(mutex->sem);
519
520 return 0;
521#elif OPENMRN_FEATURE_MUTEX_FAKE
522 mutex->locked = 0;
523 return 0;
524#elif OPENMRN_FEATURE_MUTEX_PTHREAD
525 return pthread_mutex_destroy(mutex);
526#endif
527}
528
533OS_INLINE int os_mutex_lock(os_mutex_t *mutex)
534{
535#if OPENMRN_FEATURE_MUTEX_FREERTOS
536 vTaskSuspendAll();
537 if (mutex->sem == NULL)
538 {
539 if (mutex->recursive)
540 {
541 mutex->sem = xSemaphoreCreateRecursiveMutex();
542 }
543 else
544 {
545 mutex->sem = xSemaphoreCreateMutex();
546 }
547 }
548 xTaskResumeAll();
549
550 if (mutex->recursive)
551 {
552 xSemaphoreTakeRecursive(mutex->sem, portMAX_DELAY);
553 }
554 else
555 {
556 xSemaphoreTake(mutex->sem, portMAX_DELAY);
557 }
558 return 0;
559#elif OPENMRN_FEATURE_MUTEX_FAKE
560 if (mutex->locked && !mutex->recursive)
561 {
562 DIE("Mutex deadlock.");
563 }
564 mutex->locked++;
565 return 0;
566#elif OPENMRN_FEATURE_MUTEX_PTHREAD
567 return pthread_mutex_lock(mutex);
568#endif
569}
570
575OS_INLINE int os_mutex_unlock(os_mutex_t *mutex)
576{
577#if OPENMRN_FEATURE_MUTEX_FREERTOS
578 if (mutex->recursive)
579 {
580 xSemaphoreGiveRecursive(mutex->sem);
581 }
582 else
583 {
584 xSemaphoreGive(mutex->sem);
585 }
586 return 0;
587#elif OPENMRN_FEATURE_MUTEX_FAKE
588 if (mutex->locked <= 0)
589 {
590 DIE("Unlocking a not locked mutex");
591 }
592 --mutex->locked;
593 return 0;
594#elif OPENMRN_FEATURE_MUTEX_PTHREAD
595 return pthread_mutex_unlock(mutex);
596#endif
597}
598
604OS_INLINE int os_sem_init(os_sem_t *sem, unsigned int value)
605{
606#if OPENMRN_FEATURE_MUTEX_FREERTOS
607 *sem = xSemaphoreCreateCounting(LONG_MAX, value);
608 if (!*sem) {
609 abort();
610 }
611 return 0;
612#elif OPENMRN_FEATURE_MUTEX_FAKE
613 sem->counter = value;
614 return 0;
615#elif OPENMRN_FEATURE_MUTEX_PTHREAD
616 pthread_cond_init(&sem->cond, NULL);
617 pthread_mutex_init(&sem->mutex, NULL);
618 sem->counter = value;
619 return 0;
620#endif
621}
622
628{
629#if OPENMRN_FEATURE_MUTEX_FREERTOS
630 vSemaphoreDelete(*sem);
631 return 0;
632#elif OPENMRN_FEATURE_MUTEX_FAKE
633 return 0;
634#elif OPENMRN_FEATURE_MUTEX_PTHREAD
635 pthread_cond_destroy(&sem->cond);
636 pthread_mutex_destroy(&sem->mutex);
637 return 0;
638#endif
639}
640
646{
647#if OPENMRN_FEATURE_MUTEX_FREERTOS
648 xSemaphoreGive(*sem);
649 return 0;
650#elif OPENMRN_FEATURE_MUTEX_FAKE
651 sem->counter++;
652 return 0;
653#elif OPENMRN_FEATURE_MUTEX_PTHREAD
654 pthread_mutex_lock(&sem->mutex);
655 sem->counter++;
656 pthread_cond_signal(&sem->cond);
657 pthread_mutex_unlock(&sem->mutex);
658 return 0;
659#endif
660}
661
662#if OPENMRN_FEATURE_RTOS_FROM_ISR
668OS_INLINE int os_sem_post_from_isr(os_sem_t *sem, int *woken)
669{
670 portBASE_TYPE local_woken = 0;
671 xSemaphoreGiveFromISR(*sem, &local_woken);
672 *woken |= local_woken;
673 return 0;
674}
675#endif // OPENMRN_FEATURE_RTOS_FROM_ISR
676
682{
683#if OPENMRN_FEATURE_MUTEX_FREERTOS
684 xSemaphoreTake(*sem, portMAX_DELAY);
685 return 0;
686#elif defined(__EMSCRIPTEN__)
687 while (!sem->counter)
688 {
689 os_emscripten_yield();
690 }
691 --sem->counter;
692 return 0;
693#elif OPENMRN_FEATURE_MUTEX_FAKE
694 if (!sem->counter) {
695 DIE("Semaphore deadlock.");
696 }
697 --sem->counter;
698 return 0;
699#elif OPENMRN_FEATURE_MUTEX_PTHREAD
700 pthread_mutex_lock(&sem->mutex);
701 while (sem->counter == 0)
702 {
703 pthread_cond_wait(&sem->cond, &sem->mutex);
704 }
705 sem->counter--;
706 pthread_mutex_unlock(&sem->mutex);
707 return 0;
708#endif
709}
710
711#if OPENMRN_FEATURE_SEM_TIMEDWAIT
717OS_INLINE int os_sem_timedwait(os_sem_t *sem, long long timeout)
718{
719 if (timeout == OPENMRN_OS_WAIT_FOREVER)
720 {
721 return os_sem_wait(sem);
722 }
723#if OPENMRN_FEATURE_MUTEX_FREERTOS
724 if (xSemaphoreTake(*sem, NSEC_TO_TICK(timeout)) == pdTRUE)
725 {
726 return 0;
727 }
728 else
729 {
730 errno = ETIMEDOUT;
731 return -1;
732 }
733#elif defined(__EMSCRIPTEN__)
734 long long end_time = 0;
735 do
736 {
737 if (sem->counter)
738 {
739 --sem->counter;
740 return 0;
741 }
742 else if (end_time)
743 {
744 errno = ETIMEDOUT;
745 return -1;
746 }
747 end_time = os_get_time_monotonic() + timeout;
748 while (!sem->counter && os_get_time_monotonic() < end_time)
749 {
750 os_emscripten_yield();
751 }
752 } while(1);
753#elif OPENMRN_FEATURE_MUTEX_PTHREAD
754 struct timeval tv;
755 struct timespec ts;
756 gettimeofday(&tv, NULL);
757 timeout += ((long long)tv.tv_sec * 1000000000LL) + ((long long) tv.tv_usec * 1000LL);
758 ts.tv_sec = timeout / 1000000000LL;
759 ts.tv_nsec = timeout % 1000000000LL;
760 pthread_mutex_lock(&sem->mutex);
761 while (sem->counter == 0)
762 {
763 if (pthread_cond_timedwait(&sem->cond, &sem->mutex, &ts) == ETIMEDOUT)
764 {
765 pthread_mutex_unlock(&sem->mutex);
766 errno = ETIMEDOUT;
767 return -1;
768 }
769 }
770 sem->counter--;
771 pthread_mutex_unlock(&sem->mutex);
772 return 0;
773#endif
774}
775
776#endif // OPENMRN_FEATURE_SEM_TIMEDWAIT
777
778
779#if !defined (OPENMRN_FEATURE_MUTEX_FREERTOS)
782typedef struct queue_priv
783{
784 os_sem_t semSend;
785 os_sem_t semReceive;
786 char *buffer;
787 size_t itemSize;
788 size_t bytes;
789 unsigned int indexSend;
790 unsigned int indexReceive;
791 os_mutex_t mutex;
792} QueuePriv;
793#endif
794
800OS_INLINE os_mq_t os_mq_create(size_t length, size_t item_size)
801{
802#if OPENMRN_FEATURE_MUTEX_FREERTOS
803 return xQueueCreate(length, item_size);
804#else
805 QueuePriv *q = (QueuePriv*)malloc(sizeof(QueuePriv));
806 if (!q)
807 {
808 errno = ENOMEM;
809 return NULL;
810 }
811 os_sem_init(&q->semSend, length);
812 os_sem_init(&q->semReceive, 0);
813 q->buffer = (char*)malloc(length * item_size);
814 q->itemSize = item_size;
815 q->bytes = length * item_size;
816 q->indexSend = 0;
817 q->indexReceive = 0;
818 os_mutex_init(&q->mutex);
819
820 return q;
821#endif
822}
823
828OS_INLINE void os_mq_send(os_mq_t queue, const void *data)
829{
830#if OPENMRN_FEATURE_MUTEX_FREERTOS
831 xQueueSend(queue, data, portMAX_DELAY);
832#else
833 QueuePriv *q = (QueuePriv*)queue;
834
835 os_sem_wait(&q->semSend);
836
837 os_mutex_lock(&q->mutex);
838 memcpy(q->buffer + q->indexSend, data, q->itemSize);
839 q->indexSend += q->itemSize;
840 if (q->indexSend >= q->bytes)
841 {
842 q->indexSend = 0;
843 }
844 os_mutex_unlock(&q->mutex);
845 os_sem_post(&q->semReceive);
846#endif
847}
848
855OS_INLINE int os_mq_timedsend(os_mq_t queue, const void *data, long long timeout)
856{
857#if OPENMRN_FEATURE_MUTEX_FREERTOS
858 portTickType ticks = NSEC_TO_TICK(timeout);
859
860 if (xQueueSend(queue, data, ticks) != pdTRUE)
861 {
862 return OS_MQ_TIMEDOUT;
863 }
864#else
865 DIE("unimplemented.");
866#endif
867 return OS_MQ_NONE;
868}
869
870
875OS_INLINE void os_mq_receive(os_mq_t queue, void *data)
876{
877#if OPENMRN_FEATURE_MUTEX_FREERTOS
878 xQueueReceive(queue, data, portMAX_DELAY);
879#else
880 QueuePriv *q = (QueuePriv*)queue;
881
882 os_sem_wait(&q->semReceive);
883
884 os_mutex_lock(&q->mutex);
885 memcpy(q->buffer + q->indexReceive, data, q->itemSize);
886 q->indexReceive += q->itemSize;
887 if (q->indexReceive >= q->bytes)
888 {
889 q->indexReceive = 0;
890 }
891 os_mutex_unlock(&q->mutex);
892 os_sem_post(&q->semSend);
893#endif
894}
895
902OS_INLINE int os_mq_timedreceive(os_mq_t queue, void *data, long long timeout)
903{
904#if OPENMRN_FEATURE_MUTEX_FREERTOS
905 portTickType ticks = NSEC_TO_TICK(timeout);
906
907 if (xQueueReceive(queue, data, ticks) != pdTRUE)
908 {
909 return OS_MQ_TIMEDOUT;
910 }
911#else
912 DIE("unimplemented.");
913#endif
914 return OS_MQ_NONE;
915}
916
923OS_INLINE int os_mq_send_from_isr(os_mq_t queue, const void *data, int *woken)
924{
925#if OPENMRN_FEATURE_MUTEX_FREERTOS
926 portBASE_TYPE local_woken;
927 if (xQueueSendFromISR(queue, data, &local_woken) != pdTRUE)
928 {
929 return OS_MQ_FULL;
930 }
931 *woken |= local_woken;
932#else
933 DIE("unimplemented.");
934#endif
935 return OS_MQ_NONE;
936}
937
943{
944#if OPENMRN_FEATURE_MUTEX_FREERTOS
945 return xQueueIsQueueFullFromISR(queue);
946#else
947 DIE("unimplemented.");
948#endif
949 return 1;
950}
951
952
959OS_INLINE int os_mq_receive_from_isr(os_mq_t queue, void *data, int *woken)
960{
961#if OPENMRN_FEATURE_MUTEX_FREERTOS
962 portBASE_TYPE local_woken;
963 if (xQueueReceiveFromISR(queue, data, &local_woken) != pdTRUE)
964 {
965 return OS_MQ_EMPTY;
966 }
967 *woken |= local_woken;
968#else
969 DIE("unimplemented.");
970#endif
971 return OS_MQ_NONE;
972}
973
978OS_INLINE int os_mq_num_pending(os_mq_t queue)
979{
980#if OPENMRN_FEATURE_MUTEX_FREERTOS
981 return uxQueueMessagesWaiting(queue);
982#else
983 DIE("unimplemented.");
984 return 0;
985#endif
986}
987
993{
994#if OPENMRN_FEATURE_MUTEX_FREERTOS
995 return uxQueueMessagesWaitingFromISR(queue);
996#else
997 DIE("unimplemented.");
998 return 0;
999#endif
1000}
1001
1006OS_INLINE int os_mq_num_spaces(os_mq_t queue)
1007{
1008#if OPENMRN_FEATURE_MUTEX_FREERTOS
1009 return uxQueueSpacesAvailable(queue);
1010#else
1011 DIE("unimplemented.");
1012 return 0;
1013#endif
1014}
1015
1016#if defined (__FreeRTOS__)
1019#if !defined (portEND_SWITCHING_ISR)
1020#define portEND_SWITCHING_ISR(_woken) \
1021 if( _woken ) \
1022 { \
1023 portYIELD_FROM_ISR(); \
1024 }
1025#endif
1026
1027#ifdef TARGET_PIC32MX
1028
1029void __attribute__((nomips16)) os_isr_exit_yield_test(int woken);
1030
1031#else
1035#define os_isr_exit_yield_test(_woken) \
1036do \
1037{ \
1038 portEND_SWITCHING_ISR(_woken); \
1039} while(0);
1040
1041#endif // PIC32 or general
1042#endif
1043
1047extern long long os_get_time_monotonic(void);
1048
1049#if defined (__WIN32__)
1053OS_INLINE unsigned sleep(unsigned seconds)
1054{
1055 usleep(seconds * 1000);
1056 return 0;
1057}
1058#endif
1059
1060
1061#ifdef __cplusplus
1062}
1063#endif
1064
1065#endif /* _OS_OS_H_ */
OSSem sem[1]
One semaphore required per instance pointer.
Definition CC32xxSPI.cxx:55
#define DIE(MSG)
Unconditionally terminates the current process with a message.
Definition macros.h:143
OS_INLINE void os_mq_receive(os_mq_t queue, void *data)
Blocking receive a message from a queue.
Definition os.h:875
#define OS_MQ_FULL
error code for queue being full
Definition os.h:214
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
ssize_t os_get_free_heap(void)
Definition os.c:914
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
void os_thread_cancel(os_thread_t thread)
Destroy a thread.
#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
int appl_main(int argc, char *argv[])
Entry point to application.
Definition test_main.hxx:66
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
long long os_get_fake_time(void)
Get the fake time for a unit test.
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
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
#define OS_MQ_TIMEDOUT
error code for timedout for message queues
Definition os.h:212
OS_INLINE int os_mutex_init(os_mutex_t *mutex)
Initialize mutex.
Definition os.h:460
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)
Creates a thread.
Definition os.c:450
#define OS_INLINE
Forces one definition of each inline function to be compiled.
Definition os.h:77
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
#define OS_MQ_NONE
error code for no error for message queues
Definition os.h:211
#define OS_MQ_EMPTY
error code for the queue being empty
Definition os.h:213