semaphore.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "semaphore.h"
  2. #include "check.h"
  3. #include "common_defines.h"
  4. #include <semphr.h>
  5. FuriSemaphore* furi_semaphore_alloc(uint32_t max_count, uint32_t initial_count) {
  6. furi_assert(!FURI_IS_IRQ_MODE());
  7. furi_assert((max_count > 0U) && (initial_count <= max_count));
  8. SemaphoreHandle_t hSemaphore = NULL;
  9. if(max_count == 1U) {
  10. hSemaphore = xSemaphoreCreateBinary();
  11. if((hSemaphore != NULL) && (initial_count != 0U)) {
  12. if(xSemaphoreGive(hSemaphore) != pdPASS) {
  13. vSemaphoreDelete(hSemaphore);
  14. hSemaphore = NULL;
  15. }
  16. }
  17. } else {
  18. hSemaphore = xSemaphoreCreateCounting(max_count, initial_count);
  19. }
  20. furi_check(hSemaphore);
  21. /* Return semaphore ID */
  22. return ((FuriSemaphore*)hSemaphore);
  23. }
  24. void furi_semaphore_free(FuriSemaphore* instance) {
  25. furi_assert(instance);
  26. furi_assert(!FURI_IS_IRQ_MODE());
  27. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance;
  28. vSemaphoreDelete(hSemaphore);
  29. }
  30. FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout) {
  31. furi_assert(instance);
  32. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance;
  33. FuriStatus stat;
  34. BaseType_t yield;
  35. stat = FuriStatusOk;
  36. if(FURI_IS_IRQ_MODE()) {
  37. if(timeout != 0U) {
  38. stat = FuriStatusErrorParameter;
  39. } else {
  40. yield = pdFALSE;
  41. if(xSemaphoreTakeFromISR(hSemaphore, &yield) != pdPASS) {
  42. stat = FuriStatusErrorResource;
  43. } else {
  44. portYIELD_FROM_ISR(yield);
  45. }
  46. }
  47. } else {
  48. if(xSemaphoreTake(hSemaphore, (TickType_t)timeout) != pdPASS) {
  49. if(timeout != 0U) {
  50. stat = FuriStatusErrorTimeout;
  51. } else {
  52. stat = FuriStatusErrorResource;
  53. }
  54. }
  55. }
  56. /* Return execution status */
  57. return (stat);
  58. }
  59. FuriStatus furi_semaphore_release(FuriSemaphore* instance) {
  60. furi_assert(instance);
  61. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance;
  62. FuriStatus stat;
  63. BaseType_t yield;
  64. stat = FuriStatusOk;
  65. if(FURI_IS_IRQ_MODE()) {
  66. yield = pdFALSE;
  67. if(xSemaphoreGiveFromISR(hSemaphore, &yield) != pdTRUE) {
  68. stat = FuriStatusErrorResource;
  69. } else {
  70. portYIELD_FROM_ISR(yield);
  71. }
  72. } else {
  73. if(xSemaphoreGive(hSemaphore) != pdPASS) {
  74. stat = FuriStatusErrorResource;
  75. }
  76. }
  77. /* Return execution status */
  78. return (stat);
  79. }
  80. uint32_t furi_semaphore_get_count(FuriSemaphore* instance) {
  81. furi_assert(instance);
  82. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance;
  83. uint32_t count;
  84. if(FURI_IS_IRQ_MODE()) {
  85. count = (uint32_t)uxSemaphoreGetCountFromISR(hSemaphore);
  86. } else {
  87. count = (uint32_t)uxSemaphoreGetCount(hSemaphore);
  88. }
  89. /* Return number of tokens */
  90. return (count);
  91. }