lo_os.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "cmsis_os.h"
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <pthread.h>
  5. #include <errno.h>
  6. #include <signal.h>
  7. #include <sys/types.h>
  8. #include <sys/ipc.h>
  9. #include <sys/msg.h>
  10. void osDelay(uint32_t ms) {
  11. // printf("[DELAY] %d ms\n", ms);
  12. usleep(ms * 1000);
  13. }
  14. // temporary struct to pass function ptr and param to wrapper
  15. typedef struct {
  16. TaskFunction_t func;
  17. void * param;
  18. } PthreadTask;
  19. void* pthread_wrapper(void* p) {
  20. pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0x00);
  21. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0x00);
  22. PthreadTask* task = (PthreadTask*)p;
  23. task->func(task->param);
  24. return NULL;
  25. }
  26. TaskHandle_t xTaskCreateStatic(
  27. TaskFunction_t pxTaskCode,
  28. const char * const pcName,
  29. const uint32_t ulStackDepth,
  30. void * const pvParameters,
  31. UBaseType_t uxPriority,
  32. StackType_t * const puxStackBuffer,
  33. StaticTask_t * const pxTaskBuffer
  34. ) {
  35. TaskHandle_t thread = malloc(sizeof(TaskHandle_t));
  36. PthreadTask* task = malloc(sizeof(PthreadTask));
  37. task->func = pxTaskCode;
  38. task->param = pvParameters;
  39. pthread_create(thread, NULL, pthread_wrapper, (void*)task);
  40. return thread;
  41. }
  42. void vTaskDelete(TaskHandle_t xTask) {
  43. if(xTask == NULL) {
  44. // kill itself
  45. pthread_exit(NULL);
  46. }
  47. // maybe thread already join
  48. if (pthread_kill(*xTask, 0) == ESRCH) return;
  49. // send thread_child signal to stop it сигнал, который ее завершает
  50. pthread_cancel(*xTask);
  51. // wait for join and close descriptor
  52. pthread_join(*xTask, 0x00);
  53. // cleanup thread handler
  54. *xTask = 0;
  55. }
  56. TaskHandle_t xTaskGetCurrentTaskHandle(void) {
  57. TaskHandle_t thread = malloc(sizeof(TaskHandle_t));
  58. *thread = pthread_self();
  59. return thread;
  60. }
  61. bool task_equal(TaskHandle_t a, TaskHandle_t b) {
  62. if(a == NULL || b == NULL) return false;
  63. return pthread_equal(*a, *b) != 0;
  64. }
  65. SemaphoreHandle_t xSemaphoreCreateMutexStatic(StaticSemaphore_t* pxMutexBuffer) {
  66. // TODO add posix mutex init
  67. return NULL;
  68. }
  69. BaseType_t xQueueSend(
  70. QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait
  71. ) {
  72. // TODO: add implementation
  73. return pdTRUE;
  74. }
  75. BaseType_t xQueueReceive(
  76. QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait
  77. ) {
  78. // TODO: add implementation
  79. osDelay(100);
  80. return pdFALSE;
  81. }
  82. static uint32_t queue_global_id = 0;
  83. QueueHandle_t xQueueCreateStatic(
  84. UBaseType_t uxQueueLength,
  85. UBaseType_t uxItemSize,
  86. uint8_t* pucQueueStorageBuffer,
  87. StaticQueue_t *pxQueueBuffer
  88. ) {
  89. // TODO: check this implementation
  90. int* msgid = malloc(sizeof(int));
  91. key_t key = queue_global_id;
  92. queue_global_id++;
  93. *msgid = msgget(key, IPC_CREAT);
  94. return (QueueHandle_t)msgid;
  95. }
  96. SemaphoreHandle_t xSemaphoreCreateCountingStatic(
  97. UBaseType_t uxMaxCount,
  98. UBaseType_t uxInitialCount,
  99. StaticSemaphore_t* pxSemaphoreBuffer
  100. ) {
  101. pxSemaphoreBuffer->take_counter = 0;
  102. pxSemaphoreBuffer->give_counter = 0;
  103. return pxSemaphoreBuffer;
  104. }
  105. BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait) {
  106. if(xSemaphore == NULL) return false;
  107. // TODO: need to add inter-process sync or use POSIX primitives
  108. xSemaphore->take_counter++;
  109. TickType_t ticks = xTicksToWait;
  110. while(
  111. xSemaphore->take_counter != xSemaphore->give_counter
  112. && (ticks > 0 || xTicksToWait == portMAX_DELAY)
  113. ) {
  114. osDelay(1);
  115. ticks--;
  116. }
  117. if(xTicksToWait != 0 && ticks == 0) return pdFALSE;
  118. return pdTRUE;
  119. }
  120. BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore) {
  121. if(xSemaphore == NULL) return false;
  122. // TODO: need to add inter-process sync or use POSIX primitives
  123. xSemaphore->give_counter++;
  124. return pdTRUE;
  125. }