semaphore.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include "semaphore.h"
  2. #include "check.h"
  3. #include "common_defines.h"
  4. #include <semphr.h>
  5. osSemaphoreId_t
  6. osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t* attr) {
  7. SemaphoreHandle_t hSemaphore;
  8. int32_t mem;
  9. hSemaphore = NULL;
  10. if((FURI_IS_IRQ_MODE() == 0U) && (max_count > 0U) && (initial_count <= max_count)) {
  11. mem = -1;
  12. if(attr != NULL) {
  13. if((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
  14. /* The memory for control block is provided, use static object */
  15. mem = 1;
  16. } else {
  17. if((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
  18. /* Control block will be allocated from the dynamic pool */
  19. mem = 0;
  20. }
  21. }
  22. } else {
  23. mem = 0;
  24. }
  25. if(mem != -1) {
  26. if(max_count == 1U) {
  27. if(mem == 1) {
  28. #if(configSUPPORT_STATIC_ALLOCATION == 1)
  29. hSemaphore = xSemaphoreCreateBinaryStatic((StaticSemaphore_t*)attr->cb_mem);
  30. #endif
  31. } else {
  32. #if(configSUPPORT_DYNAMIC_ALLOCATION == 1)
  33. hSemaphore = xSemaphoreCreateBinary();
  34. #endif
  35. }
  36. if((hSemaphore != NULL) && (initial_count != 0U)) {
  37. if(xSemaphoreGive(hSemaphore) != pdPASS) {
  38. vSemaphoreDelete(hSemaphore);
  39. hSemaphore = NULL;
  40. }
  41. }
  42. } else {
  43. if(mem == 1) {
  44. #if(configSUPPORT_STATIC_ALLOCATION == 1)
  45. hSemaphore = xSemaphoreCreateCountingStatic(
  46. max_count, initial_count, (StaticSemaphore_t*)attr->cb_mem);
  47. #endif
  48. } else {
  49. #if(configSUPPORT_DYNAMIC_ALLOCATION == 1)
  50. hSemaphore = xSemaphoreCreateCounting(max_count, initial_count);
  51. #endif
  52. }
  53. }
  54. #if(configQUEUE_REGISTRY_SIZE > 0)
  55. if(hSemaphore != NULL) {
  56. if((attr != NULL) && (attr->name != NULL)) {
  57. /* Only non-NULL name objects are added to the Queue Registry */
  58. vQueueAddToRegistry(hSemaphore, attr->name);
  59. }
  60. }
  61. #endif
  62. }
  63. }
  64. /* Return semaphore ID */
  65. return ((osSemaphoreId_t)hSemaphore);
  66. }
  67. /*
  68. Acquire a Semaphore token or timeout if no tokens are available.
  69. */
  70. osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout) {
  71. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
  72. osStatus_t stat;
  73. BaseType_t yield;
  74. stat = osOK;
  75. if(hSemaphore == NULL) {
  76. stat = osErrorParameter;
  77. } else if(FURI_IS_IRQ_MODE() != 0U) {
  78. if(timeout != 0U) {
  79. stat = osErrorParameter;
  80. } else {
  81. yield = pdFALSE;
  82. if(xSemaphoreTakeFromISR(hSemaphore, &yield) != pdPASS) {
  83. stat = osErrorResource;
  84. } else {
  85. portYIELD_FROM_ISR(yield);
  86. }
  87. }
  88. } else {
  89. if(xSemaphoreTake(hSemaphore, (TickType_t)timeout) != pdPASS) {
  90. if(timeout != 0U) {
  91. stat = osErrorTimeout;
  92. } else {
  93. stat = osErrorResource;
  94. }
  95. }
  96. }
  97. /* Return execution status */
  98. return (stat);
  99. }
  100. /*
  101. Release a Semaphore token up to the initial maximum count.
  102. */
  103. osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id) {
  104. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
  105. osStatus_t stat;
  106. BaseType_t yield;
  107. stat = osOK;
  108. if(hSemaphore == NULL) {
  109. stat = osErrorParameter;
  110. } else if(FURI_IS_IRQ_MODE() != 0U) {
  111. yield = pdFALSE;
  112. if(xSemaphoreGiveFromISR(hSemaphore, &yield) != pdTRUE) {
  113. stat = osErrorResource;
  114. } else {
  115. portYIELD_FROM_ISR(yield);
  116. }
  117. } else {
  118. if(xSemaphoreGive(hSemaphore) != pdPASS) {
  119. stat = osErrorResource;
  120. }
  121. }
  122. /* Return execution status */
  123. return (stat);
  124. }
  125. /*
  126. Get current Semaphore token count.
  127. */
  128. uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id) {
  129. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
  130. uint32_t count;
  131. if(hSemaphore == NULL) {
  132. count = 0U;
  133. } else if(FURI_IS_IRQ_MODE() != 0U) {
  134. count = (uint32_t)uxSemaphoreGetCountFromISR(hSemaphore);
  135. } else {
  136. count = (uint32_t)uxSemaphoreGetCount(hSemaphore);
  137. }
  138. /* Return number of tokens */
  139. return (count);
  140. }
  141. /*
  142. Delete a Semaphore object.
  143. */
  144. osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id) {
  145. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
  146. osStatus_t stat;
  147. #ifndef USE_FreeRTOS_HEAP_1
  148. if(FURI_IS_IRQ_MODE() != 0U) {
  149. stat = osErrorISR;
  150. } else if(hSemaphore == NULL) {
  151. stat = osErrorParameter;
  152. } else {
  153. #if(configQUEUE_REGISTRY_SIZE > 0)
  154. vQueueUnregisterQueue(hSemaphore);
  155. #endif
  156. stat = osOK;
  157. vSemaphoreDelete(hSemaphore);
  158. }
  159. #else
  160. stat = osError;
  161. #endif
  162. /* Return execution status */
  163. return (stat);
  164. }