stream_buffer.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * @file stream_buffer.h
  3. * Furi stream buffer primitive.
  4. *
  5. * Stream buffers are used to send a continuous stream of data from one task or
  6. * interrupt to another. Their implementation is light weight, making them
  7. * particularly suited for interrupt to task and core to core communication
  8. * scenarios.
  9. *
  10. * ***NOTE***: Stream buffer implementation assumes there is only one task or
  11. * interrupt that will write to the buffer (the writer), and only one task or
  12. * interrupt that will read from the buffer (the reader).
  13. */
  14. #pragma once
  15. #include <stdint.h>
  16. #include <stddef.h>
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. typedef void FuriStreamBuffer;
  21. /**
  22. * @brief Allocate stream buffer instance.
  23. * Stream buffer implementation assumes there is only one task or
  24. * interrupt that will write to the buffer (the writer), and only one task or
  25. * interrupt that will read from the buffer (the reader).
  26. *
  27. * @param size The total number of bytes the stream buffer will be able to hold at any one time.
  28. * @param trigger_level The number of bytes that must be in the stream buffer
  29. * before a task that is blocked on the stream buffer to wait for data is moved out of the blocked state.
  30. * @return The stream buffer instance.
  31. */
  32. FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level);
  33. /**
  34. * @brief Free stream buffer instance
  35. *
  36. * @param stream_buffer The stream buffer instance.
  37. */
  38. void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer);
  39. /**
  40. * @brief Set trigger level for stream buffer.
  41. * A stream buffer's trigger level is the number of bytes that must be in the
  42. * stream buffer before a task that is blocked on the stream buffer to
  43. * wait for data is moved out of the blocked state.
  44. *
  45. * @param stream_buffer The stream buffer instance
  46. * @param trigger_level The new trigger level for the stream buffer.
  47. * @return true if trigger level can be be updated (new trigger level was less than or equal to the stream buffer's length).
  48. * @return false if trigger level can't be be updated (new trigger level was greater than the stream buffer's length).
  49. */
  50. bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level);
  51. /**
  52. * @brief Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
  53. * Wakes up task waiting for data to become available if called from ISR.
  54. *
  55. * @param stream_buffer The stream buffer instance.
  56. * @param data A pointer to the data that is to be copied into the stream buffer.
  57. * @param length The maximum number of bytes to copy from data into the stream buffer.
  58. * @param timeout The maximum amount of time the task should remain in the
  59. * Blocked state to wait for space to become available if the stream buffer is full.
  60. * Will return immediately if timeout is zero.
  61. * Setting timeout to FuriWaitForever will cause the task to wait indefinitely.
  62. * Ignored if called from ISR.
  63. * @return The number of bytes actually written to the stream buffer.
  64. */
  65. size_t furi_stream_buffer_send(
  66. FuriStreamBuffer* stream_buffer,
  67. const void* data,
  68. size_t length,
  69. uint32_t timeout);
  70. /**
  71. * @brief Receives bytes from a stream buffer.
  72. * Wakes up task waiting for space to become available if called from ISR.
  73. *
  74. * @param stream_buffer The stream buffer instance.
  75. * @param data A pointer to the buffer into which the received bytes will be
  76. * copied.
  77. * @param length The length of the buffer pointed to by the data parameter.
  78. * @param timeout The maximum amount of time the task should remain in the
  79. * Blocked state to wait for data to become available if the stream buffer is empty.
  80. * Will return immediately if timeout is zero.
  81. * Setting timeout to FuriWaitForever will cause the task to wait indefinitely.
  82. * Ignored if called from ISR.
  83. * @return The number of bytes read from the stream buffer, if any.
  84. */
  85. size_t furi_stream_buffer_receive(
  86. FuriStreamBuffer* stream_buffer,
  87. void* data,
  88. size_t length,
  89. uint32_t timeout);
  90. /**
  91. * @brief Queries a stream buffer to see how much data it contains, which is equal to
  92. * the number of bytes that can be read from the stream buffer before the stream
  93. * buffer would be empty.
  94. *
  95. * @param stream_buffer The stream buffer instance.
  96. * @return The number of bytes that can be read from the stream buffer before
  97. * the stream buffer would be empty.
  98. */
  99. size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer);
  100. /**
  101. * @brief Queries a stream buffer to see how much free space it contains, which is
  102. * equal to the amount of data that can be sent to the stream buffer before it
  103. * is full.
  104. *
  105. * @param stream_buffer The stream buffer instance.
  106. * @return The number of bytes that can be written to the stream buffer before
  107. * the stream buffer would be full.
  108. */
  109. size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer);
  110. /**
  111. * @brief Queries a stream buffer to see if it is full.
  112. *
  113. * @param stream_buffer stream buffer instance.
  114. * @return true if the stream buffer is full.
  115. * @return false if the stream buffer is not full.
  116. */
  117. bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer);
  118. /**
  119. * @brief Queries a stream buffer to see if it is empty.
  120. *
  121. * @param stream_buffer The stream buffer instance.
  122. * @return true if the stream buffer is empty.
  123. * @return false if the stream buffer is not empty.
  124. */
  125. bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer);
  126. /**
  127. * @brief Resets a stream buffer to its initial, empty, state. Any data that was
  128. * in the stream buffer is discarded. A stream buffer can only be reset if there
  129. * are no tasks blocked waiting to either send to or receive from the stream buffer.
  130. *
  131. * @param stream_buffer The stream buffer instance.
  132. * @return FuriStatusOk if the stream buffer is reset.
  133. * @return FuriStatusError if there was a task blocked waiting to send to or read
  134. * from the stream buffer then the stream buffer is not reset.
  135. */
  136. FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer);
  137. #ifdef __cplusplus
  138. }
  139. #endif