message_queue.c 4.9 KB

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