ringbuf.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. // Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #ifndef FREERTOS_RINGBUF_H
  14. #define FREERTOS_RINGBUF_H
  15. #ifndef INC_FREERTOS_H
  16. #error "include FreeRTOS.h" must appear in source files before "include ringbuf.h"
  17. #endif
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. #include <freertos/queue.h>
  22. /**
  23. * Type by which ring buffers are referenced. For example, a call to xRingbufferCreate()
  24. * returns a RingbufHandle_t variable that can then be used as a parameter to
  25. * xRingbufferSend(), xRingbufferReceive(), etc.
  26. */
  27. typedef void * RingbufHandle_t;
  28. typedef enum {
  29. /**
  30. * No-split buffers will only store an item in contiguous memory and will
  31. * never split an item. Each item requires an 8 byte overhead for a header
  32. * and will always internally occupy a 32-bit aligned size of space.
  33. */
  34. RINGBUF_TYPE_NOSPLIT = 0,
  35. /**
  36. * Allow-split buffers will split an item into two parts if necessary in
  37. * order to store it. Each item requires an 8 byte overhead for a header,
  38. * splitting incurs an extra header. Each item will always internally occupy
  39. * a 32-bit aligned size of space.
  40. */
  41. RINGBUF_TYPE_ALLOWSPLIT,
  42. /**
  43. * Byte buffers store data as a sequence of bytes and do not maintain separate
  44. * items, therefore byte buffers have no overhead. All data is stored as a
  45. * sequence of byte and any number of bytes can be sent or retrieved each
  46. * time.
  47. */
  48. RINGBUF_TYPE_BYTEBUF
  49. } ringbuf_type_t;
  50. /**
  51. * @brief Create a ring buffer
  52. *
  53. * @param[in] xBufferSize Size of the buffer in bytes. Note that items require
  54. * space for overhead in no-split/allow-split buffers
  55. * @param[in] xBufferType Type of ring buffer, see documentation.
  56. *
  57. * @note xBufferSize of no-split/allow-split buffers will be rounded up to the nearest 32-bit aligned size.
  58. *
  59. * @return A handle to the created ring buffer, or NULL in case of error.
  60. */
  61. RingbufHandle_t xRingbufferCreate(size_t xBufferSize, ringbuf_type_t xBufferType);
  62. /**
  63. * @brief Create a ring buffer of type RINGBUF_TYPE_NOSPLIT for a fixed item_size
  64. *
  65. * This API is similar to xRingbufferCreate(), but it will internally allocate
  66. * additional space for the headers.
  67. *
  68. * @param[in] xItemSize Size of each item to be put into the ring buffer
  69. * @param[in] xItemNum Maximum number of items the buffer needs to hold simultaneously
  70. *
  71. * @return A RingbufHandle_t handle to the created ring buffer, or NULL in case of error.
  72. */
  73. RingbufHandle_t xRingbufferCreateNoSplit(size_t xItemSize, size_t xItemNum);
  74. /**
  75. * @brief Insert an item into the ring buffer
  76. *
  77. * Attempt to insert an item into the ring buffer. This function will block until
  78. * enough free space is available or until it timesout.
  79. *
  80. * @param[in] xRingbuffer Ring buffer to insert the item into
  81. * @param[in] pvItem Pointer to data to insert. NULL is allowed if xItemSize is 0.
  82. * @param[in] xItemSize Size of data to insert.
  83. * @param[in] xTicksToWait Ticks to wait for room in the ring buffer.
  84. *
  85. * @note For no-split/allow-split ring buffers, the actual size of memory that
  86. * the item will occupy will be rounded up to the nearest 32-bit aligned
  87. * size. This is done to ensure all items are always stored in 32-bit
  88. * aligned fashion.
  89. *
  90. * @return
  91. * - pdTRUE if succeeded
  92. * - pdFALSE on time-out or when the data is larger than the maximum permissible size of the buffer
  93. */
  94. BaseType_t xRingbufferSend(RingbufHandle_t xRingbuffer, const void *pvItem, size_t xItemSize, TickType_t xTicksToWait);
  95. /**
  96. * @brief Insert an item into the ring buffer in an ISR
  97. *
  98. * Attempt to insert an item into the ring buffer from an ISR. This function
  99. * will return immediately if there is insufficient free space in the buffer.
  100. *
  101. * @param[in] xRingbuffer Ring buffer to insert the item into
  102. * @param[in] pvItem Pointer to data to insert. NULL is allowed if xItemSize is 0.
  103. * @param[in] xItemSize Size of data to insert.
  104. * @param[out] pxHigherPriorityTaskWoken Value pointed to will be set to pdTRUE if the function woke up a higher priority task.
  105. *
  106. * @note For no-split/allow-split ring buffers, the actual size of memory that
  107. * the item will occupy will be rounded up to the nearest 32-bit aligned
  108. * size. This is done to ensure all items are always stored in 32-bit
  109. * aligned fashion.
  110. *
  111. * @return
  112. * - pdTRUE if succeeded
  113. * - pdFALSE when the ring buffer does not have space.
  114. */
  115. BaseType_t xRingbufferSendFromISR(RingbufHandle_t xRingbuffer, const void *pvItem, size_t xItemSize, BaseType_t *pxHigherPriorityTaskWoken);
  116. /**
  117. * @brief Retrieve an item from the ring buffer
  118. *
  119. * Attempt to retrieve an item from the ring buffer. This function will block
  120. * until an item is available or until it timesout.
  121. *
  122. * @param[in] xRingbuffer Ring buffer to retrieve the item from
  123. * @param[out] pxItemSize Pointer to a variable to which the size of the retrieved item will be written.
  124. * @param[in] xTicksToWait Ticks to wait for items in the ring buffer.
  125. *
  126. * @note A call to vRingbufferReturnItem() is required after this to free the item retrieved.
  127. *
  128. * @return
  129. * - Pointer to the retrieved item on success; *pxItemSize filled with the length of the item.
  130. * - NULL on timeout, *pxItemSize is untouched in that case.
  131. */
  132. void *xRingbufferReceive(RingbufHandle_t xRingbuffer, size_t *pxItemSize, TickType_t xTicksToWait);
  133. /**
  134. * @brief Retrieve an item from the ring buffer in an ISR
  135. *
  136. * Attempt to retrieve an item from the ring buffer. This function returns immediately
  137. * if there are no items available for retrieval
  138. *
  139. * @param[in] xRingbuffer Ring buffer to retrieve the item from
  140. * @param[out] pxItemSize Pointer to a variable to which the size of the
  141. * retrieved item will be written.
  142. *
  143. * @note A call to vRingbufferReturnItemFromISR() is required after this to free the item retrieved.
  144. * @note Byte buffers do not allow multiple retrievals before returning an item
  145. *
  146. * @return
  147. * - Pointer to the retrieved item on success; *pxItemSize filled with the length of the item.
  148. * - NULL when the ring buffer is empty, *pxItemSize is untouched in that case.
  149. */
  150. void *xRingbufferReceiveFromISR(RingbufHandle_t xRingbuffer, size_t *pxItemSize);
  151. /**
  152. * @brief Retrieve a split item from an allow-split ring buffer
  153. *
  154. * Attempt to retrieve a split item from an allow-split ring buffer. If the item
  155. * is not split, only a single item is retried. If the item is split, both parts
  156. * will be retrieved. This function will block until an item is available or
  157. * until it timesout.
  158. *
  159. * @param[in] xRingbuffer Ring buffer to retrieve the item from
  160. * @param[out] ppvHeadItem Double pointer to first part (set to NULL if no items were retrieved)
  161. * @param[out] ppvTailItem Double pointer to second part (set to NULL if item is not split)
  162. * @param[out] pxHeadItemSize Pointer to size of first part (unmodified if no items were retrieved)
  163. * @param[out] pxTailItemSize Pointer to size of second part (unmodified if item is not split)
  164. * @param[in] xTicksToWait Ticks to wait for items in the ring buffer.
  165. *
  166. * @note Call(s) to vRingbufferReturnItem() is required after this to free up the item(s) retrieved.
  167. * @note This function should only be called on allow-split buffers
  168. *
  169. * @return
  170. * - pdTRUE if an item (split or unsplit) was retrieved
  171. * - pdFALSE when no item was retrieved
  172. */
  173. BaseType_t xRingbufferReceiveSplit(RingbufHandle_t xRingbuffer, void **ppvHeadItem, void **ppvTailItem, size_t *pxHeadItemSize, size_t *pxTailItemSize, TickType_t xTicksToWait);
  174. /**
  175. * @brief Retrieve a split item from an allow-split ring buffer in an ISR
  176. *
  177. * Attempt to retrieve a split item from an allow-split ring buffer. If the item
  178. * is not split, only a single item is retried. If the item is split, both parts
  179. * will be retrieved. This function returns immediately if there are no items
  180. * available for retrieval
  181. *
  182. * @param[in] xRingbuffer Ring buffer to retrieve the item from
  183. * @param[out] ppvHeadItem Double pointer to first part (set to NULL if no items were retrieved)
  184. * @param[out] ppvTailItem Double pointer to second part (set to NULL if item is not split)
  185. * @param[out] pxHeadItemSize Pointer to size of first part (unmodified if no items were retrieved)
  186. * @param[out] pxTailItemSize Pointer to size of second part (unmodified if item is not split)
  187. *
  188. * @note Calls to vRingbufferReturnItemFromISR() is required after this to free up the item(s) retrieved.
  189. * @note This function should only be called on allow-split buffers
  190. *
  191. * @return
  192. * - pdTRUE if an item (split or unsplit) was retrieved
  193. * - pdFALSE when no item was retrieved
  194. */
  195. BaseType_t xRingbufferReceiveSplitFromISR(RingbufHandle_t xRingbuffer, void **ppvHeadItem, void **ppvTailItem, size_t *pxHeadItemSize, size_t *pxTailItemSize);
  196. /**
  197. * @brief Retrieve bytes from a byte buffer, specifying the maximum amount of bytes to retrieve
  198. *
  199. * Attempt to retrieve data from a byte buffer whilst specifying a maximum number
  200. * of bytes to retrieve. This function will block until there is data available
  201. * for retrieval or until it timesout.
  202. *
  203. * @param[in] xRingbuffer Ring buffer to retrieve the item from
  204. * @param[out] pxItemSize Pointer to a variable to which the size of the retrieved item will be written.
  205. * @param[in] xTicksToWait Ticks to wait for items in the ring buffer.
  206. * @param[in] xMaxSize Maximum number of bytes to return.
  207. *
  208. * @note A call to vRingbufferReturnItem() is required after this to free up the data retrieved.
  209. * @note This function should only be called on byte buffers
  210. * @note Byte buffers do not allow multiple retrievals before returning an item
  211. *
  212. * @return
  213. * - Pointer to the retrieved item on success; *pxItemSize filled with
  214. * the length of the item.
  215. * - NULL on timeout, *pxItemSize is untouched in that case.
  216. */
  217. void *xRingbufferReceiveUpTo(RingbufHandle_t xRingbuffer, size_t *pxItemSize, TickType_t xTicksToWait, size_t xMaxSize);
  218. /**
  219. * @brief Retrieve bytes from a byte buffer, specifying the maximum amount of
  220. * bytes to retrieve. Call this from an ISR.
  221. *
  222. * Attempt to retrieve bytes from a byte buffer whilst specifying a maximum number
  223. * of bytes to retrieve. This function will return immediately if there is no data
  224. * available for retrieval.
  225. *
  226. * @param[in] xRingbuffer Ring buffer to retrieve the item from
  227. * @param[out] pxItemSize Pointer to a variable to which the size of the retrieved item will be written.
  228. * @param[in] xMaxSize Maximum number of bytes to return.
  229. *
  230. * @note A call to vRingbufferReturnItemFromISR() is required after this to free up the data received.
  231. * @note This function should only be called on byte buffers
  232. * @note Byte buffers do not allow multiple retrievals before returning an item
  233. *
  234. * @return
  235. * - Pointer to the retrieved item on success; *pxItemSize filled with
  236. * the length of the item.
  237. * - NULL when the ring buffer is empty, *pxItemSize is untouched in that case.
  238. */
  239. void *xRingbufferReceiveUpToFromISR(RingbufHandle_t xRingbuffer, size_t *pxItemSize, size_t xMaxSize);
  240. /**
  241. * @brief Return a previously-retrieved item to the ring buffer
  242. *
  243. * @param[in] xRingbuffer Ring buffer the item was retrieved from
  244. * @param[in] pvItem Item that was received earlier
  245. *
  246. * @note If a split item is retrieved, both parts should be returned by calling this function twice
  247. */
  248. void vRingbufferReturnItem(RingbufHandle_t xRingbuffer, void *pvItem);
  249. /**
  250. * @brief Return a previously-retrieved item to the ring buffer from an ISR
  251. *
  252. * @param[in] xRingbuffer Ring buffer the item was retrieved from
  253. * @param[in] pvItem Item that was received earlier
  254. * @param[out] pxHigherPriorityTaskWoken Value pointed to will be set to pdTRUE
  255. * if the function woke up a higher priority task.
  256. *
  257. * @note If a split item is retrieved, both parts should be returned by calling this function twice
  258. */
  259. void vRingbufferReturnItemFromISR(RingbufHandle_t xRingbuffer, void *pvItem, BaseType_t *pxHigherPriorityTaskWoken);
  260. /**
  261. * @brief Delete a ring buffer
  262. *
  263. * @param[in] xRingbuffer Ring buffer to delete
  264. */
  265. void vRingbufferDelete(RingbufHandle_t xRingbuffer);
  266. /**
  267. * @brief Get maximum size of an item that can be placed in the ring buffer
  268. *
  269. * This function returns the maximum size an item can have if it was placed in
  270. * an empty ring buffer.
  271. *
  272. * @param[in] xRingbuffer Ring buffer to query
  273. *
  274. * @return Maximum size, in bytes, of an item that can be placed in a ring buffer.
  275. */
  276. size_t xRingbufferGetMaxItemSize(RingbufHandle_t xRingbuffer);
  277. /**
  278. * @brief Get current free size available for an item/data in the buffer
  279. *
  280. * This gives the real time free space available for an item/data in the ring
  281. * buffer. This represents the maximum size an item/data can have if it was
  282. * currently sent to the ring buffer.
  283. *
  284. * @warning This API is not thread safe. So, if multiple threads are accessing
  285. * the same ring buffer, it is the application's responsibility to
  286. * ensure atomic access to this API and the subsequent Send
  287. *
  288. * @param[in] xRingbuffer Ring buffer to query
  289. *
  290. * @return Current free size, in bytes, available for an entry
  291. */
  292. size_t xRingbufferGetCurFreeSize(RingbufHandle_t xRingbuffer);
  293. /**
  294. * @brief Add the ring buffer's read semaphore to a queue set.
  295. *
  296. * The ring buffer's read semaphore indicates that data has been written
  297. * to the ring buffer. This function adds the ring buffer's read semaphore to
  298. * a queue set.
  299. *
  300. * @param[in] xRingbuffer Ring buffer to add to the queue set
  301. * @param[in] xQueueSet Queue set to add the ring buffer's read semaphore to
  302. *
  303. * @return
  304. * - pdTRUE on success, pdFALSE otherwise
  305. */
  306. BaseType_t xRingbufferAddToQueueSetRead(RingbufHandle_t xRingbuffer, QueueSetHandle_t xQueueSet);
  307. /**
  308. * @brief Check if the selected queue set member is the ring buffer's read semaphore
  309. *
  310. * This API checks if queue set member returned from xQueueSelectFromSet()
  311. * is the read semaphore of this ring buffer. If so, this indicates the ring buffer
  312. * has items waiting to be retrieved.
  313. *
  314. * @param[in] xRingbuffer Ring buffer which should be checked
  315. * @param[in] xMember Member returned from xQueueSelectFromSet
  316. *
  317. * @return
  318. * - pdTRUE when semaphore belongs to ring buffer
  319. * - pdFALSE otherwise.
  320. */
  321. BaseType_t xRingbufferCanRead(RingbufHandle_t xRingbuffer, QueueSetMemberHandle_t xMember);
  322. /**
  323. * @brief Remove the ring buffer's read semaphore from a queue set.
  324. *
  325. * This specifically removes a ring buffer's read semaphore from a queue set. The
  326. * read semaphore is used to indicate when data has been written to the ring buffer
  327. *
  328. * @param[in] xRingbuffer Ring buffer to remove from the queue set
  329. * @param[in] xQueueSet Queue set to remove the ring buffer's read semaphore from
  330. *
  331. * @return
  332. * - pdTRUE on success
  333. * - pdFALSE otherwise
  334. */
  335. BaseType_t xRingbufferRemoveFromQueueSetRead(RingbufHandle_t xRingbuffer, QueueSetHandle_t xQueueSet);
  336. /**
  337. * @brief Get information about ring buffer status
  338. *
  339. * Get information of the a ring buffer's current status such as
  340. * free/read/write pointer positions, and number of items waiting to be retrieved.
  341. * Arguments can be set to NULL if they are not required.
  342. *
  343. * @param[in] xRingbuffer Ring buffer to remove from the queue set
  344. * @param[out] uxFree Pointer use to store free pointer position
  345. * @param[out] uxRead Pointer use to store read pointer position
  346. * @param[out] uxWrite Pointer use to store write pointer position
  347. * @param[out] uxItemsWaiting Pointer use to store number of items (bytes for byte buffer) waiting to be retrieved
  348. */
  349. void vRingbufferGetInfo(RingbufHandle_t xRingbuffer, UBaseType_t *uxFree, UBaseType_t *uxRead, UBaseType_t *uxWrite, UBaseType_t *uxItemsWaiting);
  350. /**
  351. * @brief Debugging function to print the internal pointers in the ring buffer
  352. *
  353. * @param xRingbuffer Ring buffer to show
  354. */
  355. void xRingbufferPrintInfo(RingbufHandle_t xRingbuffer);
  356. /* -------------------------------- Deprecated Functions --------------------------- */
  357. /** @cond */ //Doxygen command to hide deprecated function from API Reference
  358. /*
  359. * Deprecated as function is not thread safe and does not check if an item is
  360. * actually available for retrieval. Use xRingbufferReceiveSplit() instead for
  361. * thread safe method of retrieve a split item.
  362. */
  363. bool xRingbufferIsNextItemWrapped(RingbufHandle_t xRingbuffer) __attribute__((deprecated));
  364. /*
  365. * Deprecated as queue sets are not meant to be used for writing to buffers. Adding
  366. * the ring buffer write semaphore to a queue set will break queue set usage rules,
  367. * as every read of a semaphore must be preceded by a call to xQueueSelectFromSet().
  368. * QueueSetWrite no longer supported.
  369. */
  370. BaseType_t xRingbufferAddToQueueSetWrite(RingbufHandle_t xRingbuffer, QueueSetHandle_t xQueueSet) __attribute__((deprecated));
  371. /*
  372. * Deprecated as queue sets are not meant to be used for writing to buffers.
  373. * QueueSetWrite no longer supported.
  374. */
  375. BaseType_t xRingbufferRemoveFromQueueSetWrite(RingbufHandle_t xRingbuffer, QueueSetHandle_t xQueueSet) __attribute__((deprecated));
  376. /** @endcond */
  377. #ifdef __cplusplus
  378. }
  379. #endif
  380. #endif /* FREERTOS_RINGBUF_H */