furi.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #pragma once
  2. #include "cmsis_os.h"
  3. #include <stdbool.h>
  4. #include <stdint.h>
  5. #define MAX_TASK_RECORDS 8
  6. #define MAX_RECORD_SUBSCRIBERS 8
  7. /// application is just a function
  8. typedef void(*FlipperApplication)(void*);
  9. /// pointer to value callback function
  10. typedef void(*FlipperRecordCallback)(const void*, size_t);
  11. typedef enum {
  12. FlipperRecordStateMute, ///< record open and mute this handler
  13. FlipperRecordStateUnmute, ///< record unmuted
  14. FlipperRecordStateDeleted ///< record owner halt
  15. } FlipperRecordState;
  16. /// pointer to state callback function
  17. typedef void(*FlipperRecordStateCallback)(FlipperRecordState);
  18. typedef struct {
  19. bool allocated;
  20. FlipperRecordCallback cb; ///< value cb
  21. FlipperRecordStateCallback state_cb; ///< state cb
  22. uint8_t mute_counter; ///< see "wiki/FURI#mute-algorithm"
  23. bool no_mute;
  24. } FuriRecordSubscriber;
  25. /// FURI record handler
  26. typedef struct {
  27. const char* name;
  28. void* value;
  29. size_t size;
  30. StaticSemaphore_t mutex_buffer;
  31. SemaphoreHandle_t mutex;
  32. uint8_t mute_counter;
  33. FuriRecordSubscriber subscribers[MAX_RECORD_SUBSCRIBERS];
  34. } FuriRecord;
  35. /// FURI record handler for use after open
  36. typedef struct {
  37. FuriRecord* record; ///< full record (for read/write/take/give value)
  38. FuriRecordSubscriber* subscriber; ///< current handler info
  39. } FuriRecordHandler;
  40. /// store info about active task
  41. typedef struct {
  42. const char* name;
  43. FlipperApplication application;
  44. const char* prev_name;
  45. FlipperApplication prev;
  46. TaskHandle_t handler;
  47. uint8_t records_count; ///< count of records which task open
  48. FuriRecord* records[MAX_TASK_RECORDS]; ///< list of records which task open
  49. } FuriApp;
  50. /*!
  51. Simply starts application.
  52. It call app entrypoint with param passed as argument.
  53. Useful for daemon applications and pop-up.
  54. */
  55. FuriApp* furiac_start(FlipperApplication app, const char* name, void* param);
  56. /*!
  57. Swtich to other application.
  58. FURI stop current app, call app entrypoint with param passed as
  59. argument and save current application entrypoint to prev field
  60. in current application registry.
  61. Useful for UI or "active" application.
  62. */
  63. void furiac_switch(FlipperApplication app, char* name, void* param);
  64. /*!
  65. Stop current application
  66. (stop thread and clear application's stack), start application
  67. from prev entry in current application registry, cleanup current
  68. application registry.
  69. */
  70. void furiac_exit(void* param);
  71. /*!
  72. Stop specified app without returning to prev application.
  73. */
  74. bool furiac_kill(FuriApp* app);
  75. // find task pointer by handle
  76. FuriApp* find_task(TaskHandle_t handler);
  77. /*!
  78. Creates named FURI record.
  79. \param[in] name you can open this record anywhere
  80. \param[in] value pointer to data.
  81. \param[in] size size of data.
  82. If NULL, create FURI Pipe (only callbacks management, no data/mutex)
  83. Returns false if registry have not enough memory for creating.
  84. */
  85. bool furi_create(const char* name, void* value, size_t size);
  86. /*!
  87. Opens existing FURI record by name.
  88. Returns NULL if record does not exist.
  89. \param[in] solo if true another applications handlers set into "muted" state.
  90. When appication has exited or record has closed, all handlers is unmuted.
  91. It may be useful for concurrently acces to resources like framebuffer or beeper.
  92. \param[in] no_mute if true, another applications cannot mute this handler.
  93. */
  94. FuriRecordHandler furi_open(
  95. const char* name,
  96. bool solo,
  97. bool no_mute,
  98. FlipperRecordCallback value_callback,
  99. FlipperRecordStateCallback state_callback
  100. );
  101. /*!
  102. */
  103. void furi_close(FuriRecordHandler* handler);
  104. /*!
  105. read message from record.
  106. Returns true if success, false otherwise (closed/non-existent record)
  107. Also return false if you try to read from FURI pipe
  108. TODO: enum return value with execution status
  109. */
  110. bool furi_read(FuriRecordHandler* record, void* data, size_t size);
  111. /*!
  112. write message to record.
  113. Returns true if success, false otherwise (closed/non-existent record or muted).
  114. TODO: enum return value with execution status
  115. */
  116. bool furi_write(FuriRecordHandler* record, const void* data, size_t size);
  117. /*!
  118. lock value mutex.
  119. It can be useful if records contain pointer to buffer which you want to change.
  120. You must call furi_give after operation on data and
  121. you shouldn't block executing between take and give calls
  122. Returns pointer to data, NULL if closed/non-existent record or muted
  123. TODO: enum return value with execution status
  124. */
  125. void* furi_take(FuriRecordHandler* record);
  126. /*!
  127. unlock value mutex.
  128. */
  129. void furi_give(FuriRecordHandler* record);