event_flags.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "event_flags.h"
  2. #include "common_defines.h"
  3. #include <event_groups.h>
  4. #define MAX_BITS_EVENT_GROUPS 24U
  5. #define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
  6. osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t* attr) {
  7. EventGroupHandle_t hEventGroup;
  8. int32_t mem;
  9. hEventGroup = NULL;
  10. if(FURI_IS_IRQ_MODE() == 0U) {
  11. mem = -1;
  12. if(attr != NULL) {
  13. if((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_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(configSUPPORT_STATIC_ALLOCATION == 1)
  27. hEventGroup = xEventGroupCreateStatic(attr->cb_mem);
  28. #endif
  29. } else {
  30. if(mem == 0) {
  31. #if(configSUPPORT_DYNAMIC_ALLOCATION == 1)
  32. hEventGroup = xEventGroupCreate();
  33. #endif
  34. }
  35. }
  36. }
  37. /* Return event flags ID */
  38. return ((osEventFlagsId_t)hEventGroup);
  39. }
  40. /*
  41. Set the specified Event Flags.
  42. Limitations:
  43. - Event flags are limited to 24 bits.
  44. */
  45. uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags) {
  46. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  47. uint32_t rflags;
  48. BaseType_t yield;
  49. if((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
  50. rflags = (uint32_t)osErrorParameter;
  51. } else if(FURI_IS_IRQ_MODE() != 0U) {
  52. #if(configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
  53. (void)yield;
  54. /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
  55. rflags = (uint32_t)osErrorResource;
  56. #else
  57. yield = pdFALSE;
  58. if(xEventGroupSetBitsFromISR(hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) {
  59. rflags = (uint32_t)osErrorResource;
  60. } else {
  61. rflags = flags;
  62. portYIELD_FROM_ISR(yield);
  63. }
  64. #endif
  65. } else {
  66. rflags = xEventGroupSetBits(hEventGroup, (EventBits_t)flags);
  67. }
  68. /* Return event flags after setting */
  69. return (rflags);
  70. }
  71. /*
  72. Clear the specified Event Flags.
  73. Limitations:
  74. - Event flags are limited to 24 bits.
  75. */
  76. uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags) {
  77. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  78. uint32_t rflags;
  79. if((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
  80. rflags = (uint32_t)osErrorParameter;
  81. } else if(FURI_IS_IRQ_MODE() != 0U) {
  82. #if(configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
  83. /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
  84. rflags = (uint32_t)osErrorResource;
  85. #else
  86. rflags = xEventGroupGetBitsFromISR(hEventGroup);
  87. if(xEventGroupClearBitsFromISR(hEventGroup, (EventBits_t)flags) == pdFAIL) {
  88. rflags = (uint32_t)osErrorResource;
  89. } else {
  90. /* xEventGroupClearBitsFromISR only registers clear operation in the timer command queue. */
  91. /* Yield is required here otherwise clear operation might not execute in the right order. */
  92. /* See https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/93 for more info. */
  93. portYIELD_FROM_ISR(pdTRUE);
  94. }
  95. #endif
  96. } else {
  97. rflags = xEventGroupClearBits(hEventGroup, (EventBits_t)flags);
  98. }
  99. /* Return event flags before clearing */
  100. return (rflags);
  101. }
  102. /*
  103. Get the current Event Flags.
  104. Limitations:
  105. - Event flags are limited to 24 bits.
  106. */
  107. uint32_t osEventFlagsGet(osEventFlagsId_t ef_id) {
  108. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  109. uint32_t rflags;
  110. if(ef_id == NULL) {
  111. rflags = 0U;
  112. } else if(FURI_IS_IRQ_MODE() != 0U) {
  113. rflags = xEventGroupGetBitsFromISR(hEventGroup);
  114. } else {
  115. rflags = xEventGroupGetBits(hEventGroup);
  116. }
  117. /* Return current event flags */
  118. return (rflags);
  119. }
  120. /*
  121. Wait for one or more Event Flags to become signaled.
  122. Limitations:
  123. - Event flags are limited to 24 bits.
  124. - osEventFlagsWait cannot be called from an ISR.
  125. */
  126. uint32_t
  127. osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
  128. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  129. BaseType_t wait_all;
  130. BaseType_t exit_clr;
  131. uint32_t rflags;
  132. if((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
  133. rflags = (uint32_t)osErrorParameter;
  134. } else if(FURI_IS_IRQ_MODE() != 0U) {
  135. rflags = (uint32_t)osErrorISR;
  136. } else {
  137. if(options & osFlagsWaitAll) {
  138. wait_all = pdTRUE;
  139. } else {
  140. wait_all = pdFAIL;
  141. }
  142. if(options & osFlagsNoClear) {
  143. exit_clr = pdFAIL;
  144. } else {
  145. exit_clr = pdTRUE;
  146. }
  147. rflags = xEventGroupWaitBits(
  148. hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout);
  149. if(options & osFlagsWaitAll) {
  150. if((flags & rflags) != flags) {
  151. if(timeout > 0U) {
  152. rflags = (uint32_t)osErrorTimeout;
  153. } else {
  154. rflags = (uint32_t)osErrorResource;
  155. }
  156. }
  157. } else {
  158. if((flags & rflags) == 0U) {
  159. if(timeout > 0U) {
  160. rflags = (uint32_t)osErrorTimeout;
  161. } else {
  162. rflags = (uint32_t)osErrorResource;
  163. }
  164. }
  165. }
  166. }
  167. /* Return event flags before clearing */
  168. return (rflags);
  169. }
  170. /*
  171. Delete an Event Flags object.
  172. */
  173. osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id) {
  174. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  175. osStatus_t stat;
  176. #ifndef USE_FreeRTOS_HEAP_1
  177. if(FURI_IS_IRQ_MODE() != 0U) {
  178. stat = osErrorISR;
  179. } else if(hEventGroup == NULL) {
  180. stat = osErrorParameter;
  181. } else {
  182. stat = osOK;
  183. vEventGroupDelete(hEventGroup);
  184. }
  185. #else
  186. stat = osError;
  187. #endif
  188. /* Return execution status */
  189. return (stat);
  190. }