valuemutex.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #pragma once
  2. #include "flipper.h"
  3. /*
  4. == ValueMutex ==
  5. The most simple concept is ValueMutex.
  6. It is wrapper around mutex and value pointer.
  7. You can take and give mutex to work with value and read and write value.
  8. */
  9. typedef struct {
  10. void* value;
  11. size_t size;
  12. osMutexId_t mutex;
  13. } ValueMutex;
  14. /*
  15. Creates ValueMutex.
  16. */
  17. bool init_mutex(ValueMutex* valuemutex, void* value, size_t size);
  18. /*
  19. Free resources allocated by `init_mutex`.
  20. This function doesn't free the memory occupied by `ValueMutex` itself.
  21. */
  22. bool delete_mutex(ValueMutex* valuemutex);
  23. /*
  24. Call for work with data stored in mutex.
  25. Returns pointer to data if success, NULL otherwise.
  26. */
  27. void* acquire_mutex(ValueMutex* valuemutex, uint32_t timeout);
  28. /*
  29. Helper: infinitly wait for mutex
  30. */
  31. static inline void* acquire_mutex_block(ValueMutex* valuemutex) {
  32. return acquire_mutex(valuemutex, osWaitForever);
  33. }
  34. /*
  35. Release mutex after end of work with data.
  36. Call `release_mutex` and pass ValueData instance and pointer to data.
  37. */
  38. bool release_mutex(ValueMutex* valuemutex, void* value);
  39. /*
  40. Instead of take-access-give sequence you can use `read_mutex` and `write_mutex` functions.
  41. Both functions return true in case of success, false otherwise.
  42. */
  43. bool read_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout);
  44. bool write_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout);
  45. inline static bool write_mutex_block(ValueMutex* valuemutex, void* data, size_t len) {
  46. return write_mutex(valuemutex, data, len, osWaitForever);
  47. }
  48. inline static bool read_mutex_block(ValueMutex* valuemutex, void* data, size_t len) {
  49. return read_mutex(valuemutex, data, len, osWaitForever);
  50. }
  51. /*
  52. Usage example
  53. ```C
  54. // MANIFEST
  55. // name="example-provider-app"
  56. // stack=128
  57. void provider_app(void* _p) {
  58. // create record with mutex
  59. uint32_t example_value = 0;
  60. ValueMutex example_mutex;
  61. // call `init_mutex`.
  62. if(!init_mutex(&example_mutex, (void*)&example_value, sizeof(uint32_t))) {
  63. printf("critical error\n");
  64. flapp_exit(NULL);
  65. }
  66. if(furi_create("provider/example", (void*)&example_mutex)) {
  67. printf("critical error\n");
  68. flapp_exit(NULL);
  69. }
  70. // we are ready to provide record to other apps
  71. flapp_ready();
  72. // get value and increment it
  73. while(1) {
  74. uint32_t* value = acquire_mutex(&example_mutex, OsWaitForever);
  75. if(value != NULL) {
  76. value++;
  77. }
  78. release_mutex(&example_mutex, value);
  79. osDelay(100);
  80. }
  81. }
  82. // MANIFEST
  83. // name="example-consumer-app"
  84. // stack=128
  85. // require="example-provider-app"
  86. void consumer_app(void* _p) {
  87. // this app run after flapp_ready call in all requirements app
  88. // open mutex value
  89. ValueMutex* counter_mutex = furi_open("provider/example");
  90. if(counter_mutex == NULL) {
  91. printf("critical error\n");
  92. flapp_exit(NULL);
  93. }
  94. // continously read value every 1s
  95. uint32_t counter;
  96. while(1) {
  97. if(read_mutex(counter_mutex, &counter, sizeof(counter), OsWaitForever)) {
  98. printf("counter value: %d\n", counter);
  99. }
  100. osDelay(1000);
  101. }
  102. }
  103. ```
  104. */