Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
os.c
Go to the documentation of this file.
1
35#ifndef _DEFAULT_SOURCE
36#define _DEFAULT_SOURCE
37#endif
38
40#define OS_INLINE extern
41
42#include <stdint.h>
43#include <stdio.h>
44#include <fcntl.h>
45#if !defined (GCC_MEGA_AVR)
46#include <unistd.h>
47#endif // !GCC_MEGA_AVR
48
49#if defined (__FreeRTOS__)
50#include "devtab.h"
51#include "FreeRTOS.h"
52#include "task.h"
53
54#elif defined(__WIN32__)
55
56#include <winsock2.h>
57#include <ws2tcpip.h> /* socklen_t */
58#include <time.h>
59#include <signal.h>
60
61#elif defined(ESP_NONOS)
62
63#include <sys/select.h>
64#include <sched.h>
65#include <signal.h>
66#include <user_interface.h>
67
68#else
69
70#include <sys/select.h>
71#include <sched.h>
72#include <time.h>
73#include <signal.h>
74
75#endif // switch by OS
76
77#include "nmranet_config.h"
78
79#include "utils/macros.h"
80#include "os/os.h"
81#include "os/os_private.h"
82
84extern const char *STDIN_DEVICE;
85
87extern const char *STDOUT_DEVICE;
88
90extern const char *STDERR_DEVICE;
91
95const char* g_death_file;
96
98long long rtcOffset = 0;
99
102#define DELETED_TASK_MAGIC 0xb5c5d5e5
103
104/* This section of code is required because CodeSourcery's mips-gcc
105 * distribution contains a strangely compiled NewLib (in the unhosted-libc.a
106 * version) that does not forward these function calls to the implementations
107 * we have. We are thus forced to override their weak definition of these
108 * functions. */
109#if defined(TARGET_PIC32MX) || defined(ESP_NONOS)
110#include "reent.h"
111
112#ifndef _READ_WRITE_RETURN_TYPE
113#define _READ_WRITE_RETURN_TYPE ssize_t
114#endif
115
116int open(const char* b, int flags, ...)
117{
118 return _open_r(_impure_ptr, b, flags, 0);
119}
120int close(int fd)
121{
122 return _close_r(_impure_ptr, fd);
123}
124_READ_WRITE_RETURN_TYPE read(int fd, void* buf, size_t count)
125{
126 return _read_r(_impure_ptr, fd, buf, count);
127}
128_READ_WRITE_RETURN_TYPE write(int fd, const void* buf, size_t count)
129{
130 return _write_r(_impure_ptr, fd, buf, count);
131}
132off_t lseek(int fd, off_t offset, int whence)
133{
134 return _lseek_r(_impure_ptr, fd, offset, whence);
135}
136int fstat(int fd, struct stat* buf)
137{
138 return _fstat_r(_impure_ptr, fd, buf);
139}
140
141#endif
142
143
144#if OPENMRN_FEATURE_THREAD_FREERTOS
146typedef struct task_list
147{
148 xTaskHandle task;
149 char * name;
150 size_t unused;
151 struct task_list *next;
152} TaskList;
153
156typedef struct
157{
158 void *(*entry)(void*);
159 void *arg;
160 TaskList *taskList;
161} OSThreadStartPriv;
162
164static TaskList *taskList = NULL;
165
167static os_mutex_t onceMutex = OS_MUTEX_INITIALIZER;
168
172void hw_init(void) __attribute__ ((weak));
173void hw_init(void)
174{
175}
176
182void hw_postinit(void) __attribute__ ((weak));
183void hw_postinit(void)
184{
185}
186
192int os_thread_once(os_thread_once_t *once, void (*routine)(void))
193{
194 if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING)
195 {
196 /* The scheduler has started so we should use locking */
197 os_mutex_lock(&onceMutex);
198 if (once->state == OS_THREAD_ONCE_NEVER)
199 {
200 once->state = OS_THREAD_ONCE_INPROGRESS;
201 os_mutex_unlock(&onceMutex);
202 routine();
203 os_mutex_lock(&onceMutex);
204 once->state = OS_THREAD_ONCE_DONE;
205 }
206
207 while (once->state == OS_THREAD_ONCE_INPROGRESS)
208 {
209 /* avoid dead lock waiting for PTHREAD_ONCE_DONE state */
210 os_mutex_unlock(&onceMutex);
211 usleep(MSEC_TO_USEC(10));
212 os_mutex_lock(&onceMutex);
213 }
214 os_mutex_unlock(&onceMutex);
215 }
216 else
217 {
218 /* this is for static constructures before the scheduler is started */
219 if (once->state == OS_THREAD_ONCE_NEVER)
220 {
221 once->state = OS_THREAD_ONCE_INPROGRESS;
222 routine();
223 once->state = OS_THREAD_ONCE_DONE;
224 }
225 }
226
227 return 0;
228}
229#endif
230
231#if defined (__WIN32__)
236int pipe(int fildes[2])
237{
238 struct sockaddr_in addr;
239 int listener, connector, acceptor;
240 socklen_t addrlen = sizeof(addr);
241
242 if ((listener = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
243 {
244 errno = EMFILE;
245 return -1;
246 }
247 if ((connector = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
248 {
249 closesocket(listener);
250 errno = EMFILE;
251 return -1;
252 }
253
254 memset(&addr, 0, sizeof(addr));
255 addr.sin_family = AF_INET;
256 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
257 addr.sin_port = 0;
258
259 int reuse = 0;
260 if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
261 (char*)&reuse, (socklen_t)sizeof(reuse)) < 0)
262 {
263 closesocket(listener);
264 closesocket(connector);
265 errno = EMFILE;
266 return -1;
267 }
268
269 if (bind(listener, (const struct sockaddr*)&addr, sizeof(addr)) < 0)
270 {
271 closesocket(listener);
272 closesocket(connector);
273 errno = EMFILE;
274 return -1;
275 }
276
277 if (getsockname(listener, (struct sockaddr*)&addr, &addrlen) < 0)
278 {
279 closesocket(listener);
280 closesocket(connector);
281 errno = EMFILE;
282 return -1;
283 }
284
285 if (listen(listener, 1) < 0)
286 {
287 closesocket(listener);
288 closesocket(connector);
289 errno = EMFILE;
290 return -1;
291 }
292
293 if (connect(connector, (const struct sockaddr*)&addr, addrlen) < 0)
294 {
295 closesocket(listener);
296 closesocket(connector);
297 errno = EMFILE;
298 return -1;
299 }
300
301 if ((acceptor = accept(listener, NULL, NULL)) < 0)
302 {
303 closesocket(listener);
304 closesocket(connector);
305 errno = EMFILE;
306 return -1;
307 }
308
309 int flag = 1;
310 setsockopt(connector, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
311 setsockopt(acceptor, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
312
313 fildes[0] = connector;
314 fildes[1] = acceptor;
315 closesocket(listener);
316 return 0;
317}
318#endif
319
320#if OPENMRN_FEATURE_THREAD_FREERTOS
321extern const void* stack_malloc(unsigned long length);
322
326void add_thread_to_task_list(TaskList *task_new)
327{
328 vTaskSuspendAll();
329 task_new->next = taskList;
330 taskList = task_new;
331 xTaskResumeAll();
332}
333
337void del_thread_from_task_list(TaskHandle_t task_handle)
338{
339 vTaskSuspendAll();
340 TaskList *tl;
341 for (tl = taskList; tl != NULL && tl->task != task_handle; tl = tl->next)
342 {
343 }
344 if (tl)
345 {
346 tl->task = NULL;
347 tl->name = NULL;
348 tl->unused = DELETED_TASK_MAGIC;
349 }
350 xTaskResumeAll();
351}
352
355void __attribute__((weak)) os_thread_start_entry_hook(void)
356{
357}
358
362void __attribute__((weak)) os_thread_start_exit_hook(void *context)
363{
364 vTaskDelete(NULL);
365}
366
370void os_thread_start(void *arg)
371{
372 os_thread_start_entry_hook();
373
374 // add ourselves to the task list
375 OSThreadStartPriv *priv = (OSThreadStartPriv*)arg;
376 priv->taskList->task = xTaskGetCurrentTaskHandle();
377 add_thread_to_task_list(priv->taskList);
378
379#if OPENMRN_FEATURE_DEVICE_SELECT
380 // init thread local storage to
381#if tskKERNEL_VERSION_MAJOR >= 9
382 // FreeRTOS 9.x+ implementation
383 vTaskSetThreadLocalStoragePointer(NULL, TLS_INDEX_SELECT_EVENT_BIT, NULL);
384#else
385 // legacy implementation uses task tag
386 vTaskSetApplicationTaskTag(NULL, NULL);
387#endif
388#endif
389
390 // execute thread entry point
391 void *result = (*priv->entry)(priv->arg);
392
393 // remove ourselves from task list
394 del_thread_from_task_list(xTaskGetCurrentTaskHandle());
395
396 // We purposesly do not free priv->taskList. Though it is technically a
397 // leak, we keep it around for diagnostic purposes.
398
399 free(arg);
400
401 os_thread_start_exit_hook(result);
402}
403#endif // OPENMRN_FEATURE_THREAD_FREERTOS
404
405#ifndef OPENMRN_FEATURE_SINGLE_THREADED
406
407#if OPENMRN_FEATURE_THREAD_FREERTOS
417int __attribute__((weak)) os_thread_create_helper(os_thread_t *thread,
418 const char *name,
419 int priority,
420 size_t stack_size,
421 void *priv)
422{
423 HASSERT(thread);
424#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
425 xTaskCreate(os_thread_start, (const char *const)name,
426 stack_size/sizeof(portSTACK_TYPE), priv, priority, thread);
427#elif (configSUPPORT_STATIC_ALLOCATION == 1)
428 *thread = xTaskCreateStatic(os_thread_start, (const char *const)name,
429 stack_size/sizeof(portSTACK_TYPE), priv,
430 priority,
431 (StackType_t *)stack_malloc(stack_size),
432 (StaticTask_t *) malloc(sizeof(StaticTask_t)));
433#else
434#error FREERTOS version v9.0.0 or later required
435#endif
436 return 0;
437}
438#endif // OPENMRN_FEATURE_THREAD_FREERTOS
439
450int os_thread_create(os_thread_t *thread, const char *name, int priority,
451 size_t stack_size, void *(*start_routine) (void *),
452 void *arg)
453{
454 static unsigned int count = 0;
455 char auto_name[10];
456
457 if (name == NULL)
458 {
459 strcpy(auto_name, "thread.");
460 auto_name[9] = '\0';
461 auto_name[8] = '0' + (count % 10);
462 auto_name[7] = '0' + (count / 10);
463 count++;
464 name = auto_name;
465 }
466
467#if OPENMRN_FEATURE_THREAD_FREERTOS
468 OSThreadStartPriv *priv =
469 (OSThreadStartPriv*)malloc(sizeof(OSThreadStartPriv));
470
471 priv->taskList = (TaskList*)malloc(sizeof(TaskList));
472 priv->taskList->name = NULL;
473 priv->entry = start_routine;
474 priv->arg = arg;
475
476 priv->taskList->unused = stack_size;
477 if (priority == 0)
478 {
479 priority = configMAX_PRIORITIES / 2;
480 }
481 else if (priority >= configMAX_PRIORITIES)
482 {
483 priority = configMAX_PRIORITIES - 1;
484 }
485
486 if (stack_size == 0)
487 {
488 stack_size = 2048;
489 }
490
491 os_thread_t local_thread;
492 int result = os_thread_create_helper(&local_thread, name, priority,
493 stack_size, priv);
494 if (result == 0)
495 {
496 priv->taskList->task = local_thread;
497 priv->taskList->name = (char*)pcTaskGetTaskName(local_thread);
498 if (thread)
499 {
500 *thread = local_thread;
501 }
502 }
503 return result;
504#endif
505#if OPENMRN_FEATURE_THREAD_PTHREAD
506 pthread_attr_t attr;
507
508 int result = pthread_attr_init(&attr);
509 if (result != 0)
510 {
511 return result;
512 }
513 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
514 if (result != 0)
515 {
516 return result;
517 }
518
519#if OPENMRN_FEATURE_PTHREAD_SETSTACK
520 struct sched_param sched_param;
521 result = pthread_attr_setstacksize(&attr, stack_size);
522 if (result != 0)
523 {
524 return result;
525 }
526
527 sched_param.sched_priority = 0; /* default priority */
528 result = pthread_attr_setschedparam(&attr, &sched_param);
529 if (result != 0)
530 {
531 return result;
532 }
533
534 result = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
535 if (result != 0)
536 {
537 return result;
538 }
539
540 result = pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
541 if (result != 0)
542 {
543 return result;
544 }
545#endif // no stack size set needed
546 pthread_t local_thread_handle;
547 if (!thread)
548 {
549 thread = &local_thread_handle;
550 }
551 result = pthread_create(thread, &attr, start_routine, arg);
552
553#if OPENMRN_HAVE_PTHREAD_SETNAME
554 if (!result)
555 {
556 pthread_setname_np(*thread, name);
557 }
558#endif
559
560 return result;
561#endif // pthread implementation
562}
563#endif // not single threaded
564
567extern long long hw_get_partial_tick_time_nsec(void);
569long long __attribute__((weak)) hw_get_partial_tick_time_nsec() { return 0; }
570
572{
573 static long long last = 0;
574 long long time;
575#if defined (__FreeRTOS__)
576 portTickType tick = xTaskGetTickCount();
577 time = ((long long)tick) << NSEC_TO_TICK_SHIFT;
579#elif defined (__MACH__)
580 /* get the timebase info */
581 mach_timebase_info_data_t info;
582 mach_timebase_info(&info);
583
584 /* get the timestamp */
585 time = (long long)mach_absolute_time();
586
587 /* convert to nanoseconds */
588 time *= info.numer;
589 time /= info.denom;
590#elif defined (__WIN32__)
591 struct timeval tv;
592 gettimeofday(&tv, NULL);
593 time = ((long long)tv.tv_sec * 1000LL * 1000LL * 1000LL) +
594 ((long long)tv.tv_usec * 1000LL);
595#elif defined(ARDUINO)
596 // redeclare micros() prototype to remove compiler warning
597 unsigned long micros();
598
599 static uint32_t last_micros = 0;
600 static uint32_t overflow_micros = 0;
601
603 uint32_t new_micros = (uint32_t) micros();
604 if (new_micros < last_micros)
605 {
606 ++overflow_micros;
607 }
608 last_micros = new_micros;
610
611 time = overflow_micros;
612 time <<= 32;
613 time += new_micros;
614 time *= 1000; // Convert micros to nanos
615#elif defined(ESP_NONOS)
616 static uint32_t clockmul = 0;
617 if (clockmul == 0) {
618 clockmul = system_rtc_clock_cali_proc();
619 clockmul *= 1000;
620 clockmul >>= 10;
621 }
622 time = system_get_rtc_time();
623 time *= clockmul;
624 time >>= 2;
625#else
626
627 struct timespec ts;
628#if defined (__nuttx__)
629 clock_gettime(CLOCK_REALTIME, &ts);
630#else
631 clock_gettime(CLOCK_MONOTONIC, &ts);
632#endif
633 time = ((long long)ts.tv_sec * 1000000000LL) + ts.tv_nsec;
634
635#ifdef GTEST
636 long long fake_time = os_get_fake_time();
637 if (fake_time >= 0)
638 {
639 return fake_time;
640 }
641#endif // not GTEST
642
643#endif
644 /* This logic ensures that every successive call is one value larger
645 * than the last. Each call returns a unique value.
646 */
648 if (time <= last)
649 {
650 last++;
651 time = last;
652 }
653 else
654 {
655 last = time;
656 }
658
659 return time;
660}
661
662#if defined(__EMSCRIPTEN__)
663int os_thread_once(os_thread_once_t *once, void (*routine)(void))
664{
665 if (once->state == OS_THREAD_ONCE_NEVER)
666 {
667 once->state = OS_THREAD_ONCE_INPROGRESS;
668 routine();
669 once->state = OS_THREAD_ONCE_DONE;
670 }
671 else if (once->state == OS_THREAD_ONCE_INPROGRESS)
672 {
673 DIE("Recursive call to os_thread_once.");
674 }
675 return 0;
676}
677#endif
678
679#if defined (__FreeRTOS__)
680/* standard C library hooks for multi-threading */
681
684void __malloc_lock(void)
685{
686 if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
687 {
688 vTaskSuspendAll();
689 }
690}
691
694void __malloc_unlock(void)
695{
696 if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
697 {
698 xTaskResumeAll();
699 }
700}
701
702#if defined (_REENT_SMALL)
703void *__real__malloc_r(size_t size);
704void __real__free_r(void *address);
705
710void *__wrap__malloc_r(size_t size)
711{
712 void *result;
713 __malloc_lock();
714 result = __real__malloc_r(size);
715 __malloc_unlock();
716 return result;
717}
718
722void __wrap__free_r(void *address)
723{
724 __malloc_lock();
725 __real__free_r(address);
726 __malloc_unlock();
727}
728#endif
729
733unsigned sleep(unsigned seconds)
734{
735 vTaskDelay(seconds * configTICK_RATE_HZ);
736 return 0;
737}
738
742int usleep(useconds_t usec)
743{
744 long long nsec = usec;
745 nsec *= 1000;
746 vTaskDelay(nsec >> NSEC_TO_TICK_SHIFT);
747 return 0;
748}
749
750void abort(void)
751{
752#if defined(TARGET_LPC2368) || defined(TARGET_LPC11Cxx) || \
753 defined(TARGET_LPC1768) || defined(GCC_ARMCM3) || defined (GCC_ARMCM0) || \
754 defined(TARGET_PIC32MX)
756#endif
757 for (;;)
758 {
759 }
760}
761
762/* magic that allows for an optional second heap region */
763char __attribute__((weak)) __heap2_start_alias;
764extern char __heap2_start __attribute__((weak, alias ("__heap2_start_alias")));
765extern char __heap2_end __attribute__((weak, alias ("__heap2_start_alias")));
766
767extern char *heap_end;
768char *heap_end = 0;
769extern char *heap2_end;
770char *heap2_end = 0;
771void* _sbrk_r(struct _reent *reent, ptrdiff_t incr)
772{
774 extern char __cs3_heap_start;
775 extern char __cs3_heap_end; /* Defined by the linker */
776 char *prev_heap_end;
777 if (heap_end == 0)
778 {
779 heap_end = &__cs3_heap_start;
780 }
781 if (heap2_end == 0)
782 {
783 heap2_end = &__heap2_start;
784 }
785 prev_heap_end = heap_end;
786 if ((heap_end + incr) > &__cs3_heap_end)
787 {
788 if (&__heap2_start != &__heap2_end)
789 {
790 /* there is a second heap */
791 char *prev_heap2_end;
792 prev_heap2_end = heap2_end;
793 if ((heap2_end + incr) <= &__heap2_end)
794 {
795 heap2_end += incr;
796 return (caddr_t) prev_heap2_end;
797 }
798 }
799 /* Heap and stack collistion */
801 return 0;
802 }
803 heap_end += incr;
804 return (caddr_t) prev_heap_end;
805}
806
807ssize_t os_get_free_heap()
808{
810 extern char __cs3_heap_end; /* Defined by the linker */
811 uint32_t fh = &__cs3_heap_end - heap_end;
812 fh += (&__heap2_end - heap2_end);
813 return fh;
814}
815
816xTaskHandle volatile overflowed_task = 0;
817signed portCHAR * volatile overflowed_task_name = 0;
818
823void vApplicationStackOverflowHook(xTaskHandle task, signed portCHAR *name)
824{
825 overflowed_task = task;
826 overflowed_task_name = name;
828}
829
833void hw_idle_hook(void) __attribute__((weak));
834
835void hw_idle_hook(void)
836{
837}
838
841void vApplicationIdleHook( void )
842{
843 hw_idle_hook();
844 vTaskSuspendAll();
845 // First we clean up all deleted tasks.
846 for (TaskList **ptl = &taskList; *ptl != NULL;)
847 {
848 if ((*ptl)->unused == DELETED_TASK_MAGIC)
849 {
850 TaskList *tl = *ptl;
851 *ptl = tl->next;
852 free(tl);
853 }
854 else
855 {
856 ptl = &((*ptl)->next);
857 }
858 }
859 // Then we scan through the tasks and update the free stack values.
860 for (TaskList *tl = taskList; tl != NULL; tl = tl->next)
861 {
862 if (tl->task)
863 {
864 tl->unused = uxTaskGetStackHighWaterMark(tl->task) *
865 sizeof(portSTACK_TYPE);
866 }
867 xTaskResumeAll();
868 vTaskSuspendAll();
869 }
870 xTaskResumeAll();
871}
872
873#ifdef TARGET_PIC32MX
874static void __attribute__((nomips16)) os_yield_trampoline(void)
875{
876 taskYIELD();
877}
878
879void __attribute__((nomips16)) os_isr_exit_yield_test(int woken)
880{
881 portEND_SWITCHING_ISR(woken);
882}
883
884#else
885static inline void __attribute__((always_inline)) os_yield_trampoline(void)
886{
887 taskYIELD();
888}
889#endif
890
895static void *main_thread(void *unused)
896{
897 char *argv[2] = {(char*)"openmrn", NULL};
898
899 /* Allow any library threads to run that must run ahead of main */
900 os_yield_trampoline();
901
902 /* Give another chance to the board file to do work, this time coordinating
903 * between application and library threads. */
904 hw_postinit();
905
906 appl_main(1, argv);
907 // If the main thread returns, FreeRTOS usually crashes the CPU in a
908 // hard-to-debug state. Let's avoid that.
909 abort();
910 return NULL;
911}
912#else // not freertos
913
914ssize_t __attribute__((weak)) os_get_free_heap()
915{
916 return -1;
917}
918
919#endif
920
923int ignore_fn(void)
924{
925 return 0;
926}
927
928#if !defined(ARDUINO) && !defined(ESP_PLATFORM)
929
930#if !defined (__MINGW32__)
931int main(int argc, char *argv[]) __attribute__ ((weak));
932#endif
933
939int main(int argc, char *argv[])
940{
941#if defined (__FreeRTOS__)
942 /* initialize the processor hardware */
943 hw_init();
944
945#ifndef TARGET_LPC11Cxx
946 /* stdin */
947 if (open(STDIN_DEVICE, O_RDWR) < 0)
948 {
949 open("/dev/null", O_RDWR);
950 }
951 /* stdout */
952 if (open(STDOUT_DEVICE, O_RDWR) < 0)
953 {
954 open("/dev/null", O_RDWR);
955 }
956 /* stderr */
957 if (open(STDERR_DEVICE, O_WRONLY) < 0)
958 {
959 open("/dev/null", O_WRONLY);
960 }
961#endif
962
963 int priority;
964 if (config_main_thread_priority() == 0xdefa01)
965 {
966 priority = configMAX_PRIORITIES / 2;
967 }
968 else
969 {
970 priority = config_main_thread_priority();
971 }
972
973 os_thread_create(NULL, "thread.main", priority,
974 config_main_thread_stack_size(), main_thread, NULL);
975
976 vTaskStartScheduler();
977#else
978#if defined (__WIN32__)
979 /* enable Windows networking */
980 WSADATA wsa_data;
981 WSAStartup(WINSOCK_VERSION, &wsa_data);
982#endif
983 return appl_main(argc, argv);
984#endif
985}
986
987#endif // ESP_PLATFORM
988
989#if defined(ARDUINO)
990unsigned critical_nesting;
991#endif
992
993#if 0 && defined(ESP_NONOS)
994struct _reent *_impure_ptr = NULL;
995static int my_errno;
996int* __errno(void) {
997 return &my_errno;
998}
999#endif
int getsockname(int socket, struct sockaddr &addr, socklen_t &namelen)
Get the socket name.
int pipe(int pipefds[2])
Create a Unix style pipe.
Definition Pipe.cxx:391
int accept(int socket, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition Socket.cxx:194
int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len)
Set the socket options.
Definition Socket.cxx:255
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
Bind a name to a socket.
Definition Socket.cxx:159
int listen(int socket, int backlog)
Mark a connection-mode socket, specified by the socket argument, as accepting connections.
Definition Socket.cxx:174
int connect(int socket, const struct sockaddr *address, socklen_t address_len)
Connect a socket.
Definition Socket.cxx:208
int socket(int domain, int type, int protocol)
Create an unbound socket in a communications domain.
Definition Socket.cxx:144
void diewith(uint32_t pattern)
Sets a blinking pattern and never returns.
#define BLINK_DIE_STACKOVERFLOW
Stack overflow.
Definition blinker.h:62
#define BLINK_DIE_ABORT
abort() was called (usually due to an assertion failure or an uncaught C++ exception).
Definition blinker.h:71
#define BLINK_DIE_OUTOFMEM
Out of memory. (sbrk failed to allocate memory).
Definition blinker.h:58
void * stack_malloc(unsigned long length)
Custom malloc function for stack spaces.
#define IPPROTO_TCP
TCP Raw Socket.
Definition in.h:70
#define htonl(x)
Converts a host endian long value to network endian.
Definition in.h:91
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
#define DIE(MSG)
Unconditionally terminates the current process with a message.
Definition macros.h:143
int main(int argc, char *argv[])
Entry point to program.
Definition os.c:939
long long rtcOffset
clock management
Definition os.c:98
const char * STDERR_DEVICE
default stderr
Definition Null.cxx:45
long long hw_get_partial_tick_time_nsec(void)
Implement this function to read timing more accurately than 1 msec in FreeRTOS.
Definition os.c:569
int g_death_lineno
Captures point of death (line).
Definition os.c:93
const char * STDIN_DEVICE
default stdin
Definition Null.cxx:39
int ignore_fn(void)
This function does nothing.
Definition os.c:923
#define DELETED_TASK_MAGIC
This magic value is written to a task's taskList entry in order to signal the idle task to pick it ou...
Definition os.c:102
const char * STDOUT_DEVICE
default stdout
Definition Null.cxx:42
const char * g_death_file
Captures point of death (file).
Definition os.c:95
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
ssize_t os_get_free_heap()
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_thread_once(os_thread_once_t *once, void(*routine)(void))
One time intialization routine.
Definition os.h:201
int appl_main(int argc, char *argv[])
Entry point to application.
Definition test_main.hxx:66
#define MSEC_TO_USEC(_msec)
Convert a millisecond value to a microsecond value.
Definition os.h:274
long long os_get_fake_time(void)
Get the fake time for a unit test.
OS_INLINE int os_mutex_unlock(os_mutex_t *mutex)
Unock a mutex.
Definition os.h:575
void os_atomic_lock(void)
Locks a single global Atomic used to guard some OS structures.
Definition OSImpl.cxx:40
void os_atomic_unlock(void)
Unlocks a single global Atomic used to guard some OS structures.
Definition OSImpl.cxx:45
#define SOCK_STREAM
TCP Socket.
Definition socket.h:45
uint32_t socklen_t
type of sockaddr lenth
Definition socket.h:89
#define SO_REUSEADDR
socket option to reuse address
Definition socket.h:67
#define SOL_SOCKET
socket option category
Definition socket.h:64
#define AF_INET
IPv4 Socket (UDP, TCP, etc...)
Definition socket.h:54
Structure describing an Internet socket address.
Definition in.h:56
IPv4 socket address.
Definition socket.h:83
#define TCP_NODELAY
don't delay send to coalesce packets
Definition tcp.h:42