mutex.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include "mutex.h"
  2. #include "check.h"
  3. #include "common_defines.h"
  4. #include <semphr.h>
  5. osMutexId_t osMutexNew(const osMutexAttr_t* attr) {
  6. SemaphoreHandle_t hMutex;
  7. uint32_t type;
  8. uint32_t rmtx;
  9. int32_t mem;
  10. hMutex = NULL;
  11. if(FURI_IS_IRQ_MODE() == 0U) {
  12. if(attr != NULL) {
  13. type = attr->attr_bits;
  14. } else {
  15. type = 0U;
  16. }
  17. if((type & osMutexRecursive) == osMutexRecursive) {
  18. rmtx = 1U;
  19. } else {
  20. rmtx = 0U;
  21. }
  22. if((type & osMutexRobust) != osMutexRobust) {
  23. mem = -1;
  24. if(attr != NULL) {
  25. if((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
  26. /* The memory for control block is provided, use static object */
  27. mem = 1;
  28. } else {
  29. if((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
  30. /* Control block will be allocated from the dynamic pool */
  31. mem = 0;
  32. }
  33. }
  34. } else {
  35. mem = 0;
  36. }
  37. if(mem == 1) {
  38. #if(configSUPPORT_STATIC_ALLOCATION == 1)
  39. if(rmtx != 0U) {
  40. #if(configUSE_RECURSIVE_MUTEXES == 1)
  41. hMutex = xSemaphoreCreateRecursiveMutexStatic(attr->cb_mem);
  42. #endif
  43. } else {
  44. hMutex = xSemaphoreCreateMutexStatic(attr->cb_mem);
  45. }
  46. #endif
  47. } else {
  48. if(mem == 0) {
  49. #if(configSUPPORT_DYNAMIC_ALLOCATION == 1)
  50. if(rmtx != 0U) {
  51. #if(configUSE_RECURSIVE_MUTEXES == 1)
  52. hMutex = xSemaphoreCreateRecursiveMutex();
  53. #endif
  54. } else {
  55. hMutex = xSemaphoreCreateMutex();
  56. }
  57. #endif
  58. }
  59. }
  60. #if(configQUEUE_REGISTRY_SIZE > 0)
  61. if(hMutex != NULL) {
  62. if((attr != NULL) && (attr->name != NULL)) {
  63. /* Only non-NULL name objects are added to the Queue Registry */
  64. vQueueAddToRegistry(hMutex, attr->name);
  65. }
  66. }
  67. #endif
  68. if((hMutex != NULL) && (rmtx != 0U)) {
  69. /* Set LSB as 'recursive mutex flag' */
  70. hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
  71. }
  72. }
  73. }
  74. /* Return mutex ID */
  75. return ((osMutexId_t)hMutex);
  76. }
  77. /*
  78. Acquire a Mutex or timeout if it is locked.
  79. */
  80. osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout) {
  81. SemaphoreHandle_t hMutex;
  82. osStatus_t stat;
  83. uint32_t rmtx;
  84. hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
  85. /* Extract recursive mutex flag */
  86. rmtx = (uint32_t)mutex_id & 1U;
  87. stat = osOK;
  88. if(FURI_IS_IRQ_MODE() != 0U) {
  89. stat = osErrorISR;
  90. } else if(hMutex == NULL) {
  91. stat = osErrorParameter;
  92. } else {
  93. if(rmtx != 0U) {
  94. #if(configUSE_RECURSIVE_MUTEXES == 1)
  95. if(xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) {
  96. if(timeout != 0U) {
  97. stat = osErrorTimeout;
  98. } else {
  99. stat = osErrorResource;
  100. }
  101. }
  102. #endif
  103. } else {
  104. if(xSemaphoreTake(hMutex, timeout) != pdPASS) {
  105. if(timeout != 0U) {
  106. stat = osErrorTimeout;
  107. } else {
  108. stat = osErrorResource;
  109. }
  110. }
  111. }
  112. }
  113. /* Return execution status */
  114. return (stat);
  115. }
  116. /*
  117. Release a Mutex that was acquired by osMutexAcquire.
  118. */
  119. osStatus_t osMutexRelease(osMutexId_t mutex_id) {
  120. SemaphoreHandle_t hMutex;
  121. osStatus_t stat;
  122. uint32_t rmtx;
  123. hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
  124. /* Extract recursive mutex flag */
  125. rmtx = (uint32_t)mutex_id & 1U;
  126. stat = osOK;
  127. if(FURI_IS_IRQ_MODE() != 0U) {
  128. stat = osErrorISR;
  129. } else if(hMutex == NULL) {
  130. stat = osErrorParameter;
  131. } else {
  132. if(rmtx != 0U) {
  133. #if(configUSE_RECURSIVE_MUTEXES == 1)
  134. if(xSemaphoreGiveRecursive(hMutex) != pdPASS) {
  135. stat = osErrorResource;
  136. }
  137. #endif
  138. } else {
  139. if(xSemaphoreGive(hMutex) != pdPASS) {
  140. stat = osErrorResource;
  141. }
  142. }
  143. }
  144. /* Return execution status */
  145. return (stat);
  146. }
  147. /*
  148. Get Thread which owns a Mutex object.
  149. */
  150. FuriThreadId osMutexGetOwner(osMutexId_t mutex_id) {
  151. SemaphoreHandle_t hMutex;
  152. FuriThreadId owner;
  153. hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
  154. if((FURI_IS_IRQ_MODE() != 0U) || (hMutex == NULL)) {
  155. owner = 0;
  156. } else {
  157. owner = (FuriThreadId)xSemaphoreGetMutexHolder(hMutex);
  158. }
  159. /* Return owner thread ID */
  160. return (owner);
  161. }
  162. /*
  163. Delete a Mutex object.
  164. */
  165. osStatus_t osMutexDelete(osMutexId_t mutex_id) {
  166. osStatus_t stat;
  167. #ifndef USE_FreeRTOS_HEAP_1
  168. SemaphoreHandle_t hMutex;
  169. hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
  170. if(FURI_IS_IRQ_MODE() != 0U) {
  171. stat = osErrorISR;
  172. } else if(hMutex == NULL) {
  173. stat = osErrorParameter;
  174. } else {
  175. #if(configQUEUE_REGISTRY_SIZE > 0)
  176. vQueueUnregisterQueue(hMutex);
  177. #endif
  178. stat = osOK;
  179. vSemaphoreDelete(hMutex);
  180. }
  181. #else
  182. stat = osError;
  183. #endif
  184. /* Return execution status */
  185. return (stat);
  186. }