sys_ringbuffer.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /**
  2. * Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
  3. *
  4. * All Rights Reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. *
  10. * 1. Redistributions of source code must retain the above copyright notice, this
  11. * list of conditions and the following disclaimer.
  12. *
  13. * 2. Redistributions in binary form, except as embedded into a Nordic
  14. * Semiconductor ASA integrated circuit in a product or a software update for
  15. * such product, must reproduce the above copyright notice, this list of
  16. * conditions and the following disclaimer in the documentation and/or other
  17. * materials provided with the distribution.
  18. *
  19. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  20. * contributors may be used to endorse or promote products derived from this
  21. * software without specific prior written permission.
  22. *
  23. * 4. This software, with or without modification, must only be used with a
  24. * Nordic Semiconductor ASA integrated circuit.
  25. *
  26. * 5. Any software provided in binary form under this license must not be reverse
  27. * engineered, decompiled, modified and/or disassembled.
  28. *
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  31. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  33. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  34. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  35. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  36. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  38. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  39. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. *
  41. */
  42. #ifndef SYS_RINGBUFFER_H_INCLUDED
  43. #define SYS_RINGBUFFER_H_INCLUDED
  44. #include <stdint.h>
  45. #include <stdlib.h>
  46. #include <stdbool.h>
  47. /** @file
  48. * This file contains declarations of the Ring buffer routines and necessary types. Please note that
  49. * each ring buffer element should have size of 1 byte.
  50. *
  51. * @defgroup sys_ringbuffer System Ring buffer API
  52. * @ingroup sys_15_4
  53. * @{
  54. * @brief Module for declaring System Ring buffer API.
  55. * @details The Ring Buffer module implements routines to deal with the ring buffer. The following routines are supported:
  56. * sys_ringbuffer_insert(), sys_ringbuffer_remove() to operate with single element. The
  57. * sys_ringbuffer_remove_multiple() can be used to remove (read) several elements at once. The
  58. * sys_ringbuffer_clear(), sys_ringbuffer_init(), and sys_ringbuffer_init_over() functions are used to clean up and
  59. * initialize the ring buffer. Some information about the initialized ring buffer is available via the
  60. * following routines: sys_ringbuffer_size_get() to get the number of used elements, sys_ringbuffer_chunk_get()
  61. * to return the biggest, available to read, continuous chunk of elements, sys_ringbuffer_is_empty() and
  62. * sys_ringbuffer_is_full() to check if the ring buffer is empty/full, and sys_ringbuffer_max_size_get() to get
  63. * the ring buffer capacity. One of the samples for ring buffer usage is the UART implementation.
  64. */
  65. /** This structure holds all necessary information about a ring buffer. It is intentionally left undocumented
  66. * by Doxygen.
  67. *
  68. * All these fields are private and must NOT be changed by the user.
  69. */
  70. typedef struct
  71. {
  72. size_t write_index;
  73. size_t read_index;
  74. uint8_t * array;
  75. size_t size;
  76. bool is_full;
  77. } sys_ringbuffer_t;
  78. /** @brief Function for initializing an empty ring buffer over passed memory.
  79. *
  80. * @param[inout] buffer Instance of sys_ringbuffer_t that will be initialized.
  81. * @param[in] memory Start address of the memory region used as a ring buffer.
  82. * @param[in] length Size in bytes of the memory region used as a ring buffer.
  83. */
  84. void sys_ringbuffer_init(sys_ringbuffer_t * buffer,
  85. const void * memory,
  86. const size_t length);
  87. /** @brief Function for initializing a ring buffer over passed memory and marking all
  88. * pre_init_length elements as inserted.
  89. *
  90. * @details This function may be used to initialize a buffer with some
  91. * pre-initialized data in it. Passed memory region is interpreted by this function
  92. * as an already filled (partly or fully) ring buffer so that \a pre_init_length
  93. * elements are marked as inserted.
  94. *
  95. * @param[inout] buffer Instance of sys_ringbuffer_t that will be initialized.
  96. * @param[in] memory Start address of the memory region used as a ring buffer.
  97. * @param[in] pre_init_length Number of elements (bytes) that had already been in \a memory.
  98. * They would be inserted into the newly-initialized ring buffer in a FIFO manner.
  99. * @param[in] length Size of the memory region used as a ring buffer.
  100. */
  101. void sys_ringbuffer_init_over(sys_ringbuffer_t * buffer,
  102. const void * memory,
  103. const size_t pre_init_length,
  104. const size_t length);
  105. /** @brief Function for removing an element from a ring buffer and returning it.
  106. *
  107. * @param[inout] buf Instance of @c sys_ringbuffer_t.
  108. *
  109. * @return Value of the removed element.
  110. *
  111. * @warning This buffer has no underflow control except assert.
  112. */
  113. uint8_t sys_ringbuffer_remove(sys_ringbuffer_t * buf);
  114. /** @brief Function for quickly removing up to chunk_size elements from a ring buffer
  115. * and marking those elements as available in the ring buffer.
  116. *
  117. * @param[inout] buffer Instance of @c sys_ringbuffer_t.
  118. * @param[in] chunk_size Number of elements to release.
  119. */
  120. void sys_ringbuffer_remove_multiple(sys_ringbuffer_t * buffer,
  121. const size_t chunk_size);
  122. /** @brief Function for inserting a new element into a ring buffer.
  123. *
  124. * @param[inout] buffer Instance of @c sys_ringbuffer_t.
  125. * @param[in] data Element value to insert.
  126. *
  127. * @warning In case of overflow, this buffer will overwrite the oldest
  128. * element and the number of available elements will remain unchanged.
  129. */
  130. void sys_ringbuffer_insert(sys_ringbuffer_t * buffer, const uint8_t data);
  131. /** @brief Function for clearing an instance of \a sys_ringbuffer_t, making it empty.
  132. *
  133. * @param[inout] buffer Instance of @c sys_ringbuffer_t.
  134. */
  135. void sys_ringbuffer_clear(sys_ringbuffer_t * buffer);
  136. /** @brief Function for returning the number of used elements in a ring buffer instance.
  137. *
  138. * @param[inout] buf Instance of sys_ringbuffer_t.
  139. *
  140. * @return Number of elements.
  141. */
  142. size_t sys_ringbuffer_size_get(const sys_ringbuffer_t * buf);
  143. /** @brief Function for returning the biggest, available to read, continuous chunk from a ring buffer array.
  144. *
  145. * @param[inout] buffer Instance of @c sys_ringbuffer_t.
  146. * @param[out] chunk Pointer to a memory chunk removed from the ring buffer.
  147. * @param[out] chunk_size Size of the removed chunk.
  148. *
  149. * @warning The returned chunk is still part of the ring buffer. To make the chunk elements available
  150. * for write, call @c sys_ringbuffer_remove_multiple() after the chunk is processed.
  151. */
  152. void sys_ringbuffer_chunk_get(sys_ringbuffer_t * buffer,
  153. void ** chunk,
  154. size_t * chunk_size);
  155. /** @brief Function for checking whether a ring buffer is empty.
  156. *
  157. * @param[inout] buf Instance of @c sys_ringbuffer_t.
  158. *
  159. * @return True if the ring buffer is empty.
  160. */
  161. static inline bool sys_ringbuffer_is_empty(const sys_ringbuffer_t * buf)
  162. {
  163. return ((buf->write_index == buf->read_index) && (!buf->is_full));
  164. }
  165. /** @brief Function for checking whether a ring buffer is full.
  166. *
  167. * @param[inout] buf Instance of @c sys_ringbuffer_t.
  168. *
  169. * @return True if number of items in the buffer equals to (length - 1).
  170. */
  171. static inline bool sys_ringbuffer_is_full(const sys_ringbuffer_t * buf)
  172. {
  173. return buf->is_full;
  174. }
  175. /** @brief Function for returning number of elements that can be potentially put into the buffer.
  176. *
  177. * @param[inout] buf Instance of @c sys_ringbuffer_t.
  178. *
  179. * @return Number of elements.
  180. */
  181. static inline size_t sys_ringbuffer_max_size_get(const sys_ringbuffer_t * buf)
  182. {
  183. return buf->size;
  184. }
  185. /** @} */
  186. #endif /* SYS_RINGBUFFER_H_INCLUDED */