message_queue.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "message_queue.h"
  2. #include "core/common_defines.h"
  3. #include <FreeRTOS.h>
  4. #include <queue.h>
  5. #include "check.h"
  6. FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size) {
  7. furi_assert((furi_is_irq_context() == 0U) && (msg_count > 0U) && (msg_size > 0U));
  8. return ((FuriMessageQueue*)xQueueCreate(msg_count, msg_size));
  9. }
  10. void furi_message_queue_free(FuriMessageQueue* instance) {
  11. furi_assert(furi_is_irq_context() == 0U);
  12. furi_assert(instance);
  13. vQueueDelete((QueueHandle_t)instance);
  14. }
  15. FuriStatus
  16. furi_message_queue_put(FuriMessageQueue* instance, const void* msg_ptr, uint32_t timeout) {
  17. QueueHandle_t hQueue = (QueueHandle_t)instance;
  18. FuriStatus stat;
  19. BaseType_t yield;
  20. stat = FuriStatusOk;
  21. if(furi_is_irq_context() != 0U) {
  22. if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
  23. stat = FuriStatusErrorParameter;
  24. } else {
  25. yield = pdFALSE;
  26. if(xQueueSendToBackFromISR(hQueue, msg_ptr, &yield) != pdTRUE) {
  27. stat = FuriStatusErrorResource;
  28. } else {
  29. portYIELD_FROM_ISR(yield);
  30. }
  31. }
  32. } else {
  33. if((hQueue == NULL) || (msg_ptr == NULL)) {
  34. stat = FuriStatusErrorParameter;
  35. } else {
  36. if(xQueueSendToBack(hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
  37. if(timeout != 0U) {
  38. stat = FuriStatusErrorTimeout;
  39. } else {
  40. stat = FuriStatusErrorResource;
  41. }
  42. }
  43. }
  44. }
  45. /* Return execution status */
  46. return (stat);
  47. }
  48. FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uint32_t timeout) {
  49. QueueHandle_t hQueue = (QueueHandle_t)instance;
  50. FuriStatus stat;
  51. BaseType_t yield;
  52. stat = FuriStatusOk;
  53. if(furi_is_irq_context() != 0U) {
  54. if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
  55. stat = FuriStatusErrorParameter;
  56. } else {
  57. yield = pdFALSE;
  58. if(xQueueReceiveFromISR(hQueue, msg_ptr, &yield) != pdPASS) {
  59. stat = FuriStatusErrorResource;
  60. } else {
  61. portYIELD_FROM_ISR(yield);
  62. }
  63. }
  64. } else {
  65. if((hQueue == NULL) || (msg_ptr == NULL)) {
  66. stat = FuriStatusErrorParameter;
  67. } else {
  68. if(xQueueReceive(hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
  69. if(timeout != 0U) {
  70. stat = FuriStatusErrorTimeout;
  71. } else {
  72. stat = FuriStatusErrorResource;
  73. }
  74. }
  75. }
  76. }
  77. /* Return execution status */
  78. return (stat);
  79. }
  80. uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance) {
  81. StaticQueue_t* mq = (StaticQueue_t*)instance;
  82. uint32_t capacity;
  83. if(mq == NULL) {
  84. capacity = 0U;
  85. } else {
  86. /* capacity = pxQueue->uxLength */
  87. capacity = mq->uxDummy4[1];
  88. }
  89. /* Return maximum number of messages */
  90. return (capacity);
  91. }
  92. uint32_t furi_message_queue_get_message_size(FuriMessageQueue* instance) {
  93. StaticQueue_t* mq = (StaticQueue_t*)instance;
  94. uint32_t size;
  95. if(mq == NULL) {
  96. size = 0U;
  97. } else {
  98. /* size = pxQueue->uxItemSize */
  99. size = mq->uxDummy4[2];
  100. }
  101. /* Return maximum message size */
  102. return (size);
  103. }
  104. uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) {
  105. QueueHandle_t hQueue = (QueueHandle_t)instance;
  106. UBaseType_t count;
  107. if(hQueue == NULL) {
  108. count = 0U;
  109. } else if(furi_is_irq_context() != 0U) {
  110. count = uxQueueMessagesWaitingFromISR(hQueue);
  111. } else {
  112. count = uxQueueMessagesWaiting(hQueue);
  113. }
  114. /* Return number of queued messages */
  115. return ((uint32_t)count);
  116. }
  117. uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) {
  118. StaticQueue_t* mq = (StaticQueue_t*)instance;
  119. uint32_t space;
  120. uint32_t isrm;
  121. if(mq == NULL) {
  122. space = 0U;
  123. } else if(furi_is_irq_context() != 0U) {
  124. isrm = taskENTER_CRITICAL_FROM_ISR();
  125. /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
  126. space = mq->uxDummy4[1] - mq->uxDummy4[0];
  127. taskEXIT_CRITICAL_FROM_ISR(isrm);
  128. } else {
  129. space = (uint32_t)uxQueueSpacesAvailable((QueueHandle_t)mq);
  130. }
  131. /* Return number of available slots */
  132. return (space);
  133. }
  134. FuriStatus furi_message_queue_reset(FuriMessageQueue* instance) {
  135. QueueHandle_t hQueue = (QueueHandle_t)instance;
  136. FuriStatus stat;
  137. if(furi_is_irq_context() != 0U) {
  138. stat = FuriStatusErrorISR;
  139. } else if(hQueue == NULL) {
  140. stat = FuriStatusErrorParameter;
  141. } else {
  142. stat = FuriStatusOk;
  143. (void)xQueueReset(hQueue);
  144. }
  145. /* Return execution status */
  146. return (stat);
  147. }