fix(ringbuf): xRingbufferReceive() crashes for allow-split buffers

This commit adds an assert check to xRingbufferReceive() and
xRingbufferReceiveFromISR() functions to prevent them from being used to
retrieve items from an allow-split buffer. Corresponding documentation
has also been updated.
This commit is contained in:
Sudeep Mohanty
2025-03-19 12:09:08 +01:00
parent 72a684c1f0
commit db9d88c0d4
4 changed files with 15 additions and 3 deletions

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -225,7 +225,8 @@ BaseType_t xRingbufferSendComplete(RingbufHandle_t xRingbuffer, void *pvItem);
* @param[in] xTicksToWait Ticks to wait for items in the ring buffer. * @param[in] xTicksToWait Ticks to wait for items in the ring buffer.
* *
* @note A call to vRingbufferReturnItem() is required after this to free the item retrieved. * @note A call to vRingbufferReturnItem() is required after this to free the item retrieved.
* @note It is possible to receive items with a pxItemSize of 0 on no-split/allow split buffers. * @note It is possible to receive items with a pxItemSize of 0 on no-split buffers.
* @note To retrieve an item from an allow-split buffer, use `xRingbufferReceiveSplit()` instead.
* *
* @return * @return
* - Pointer to the retrieved item on success; *pxItemSize filled with the length of the item. * - Pointer to the retrieved item on success; *pxItemSize filled with the length of the item.
@ -246,7 +247,8 @@ void *xRingbufferReceive(RingbufHandle_t xRingbuffer, size_t *pxItemSize, TickTy
* @note A call to vRingbufferReturnItemFromISR() is required after this to free the item retrieved. * @note A call to vRingbufferReturnItemFromISR() is required after this to free the item retrieved.
* @note Byte buffers do not allow multiple retrievals before returning an item * @note Byte buffers do not allow multiple retrievals before returning an item
* @note Two calls to RingbufferReceiveFromISR() are required if the bytes wrap around the end of the ring buffer. * @note Two calls to RingbufferReceiveFromISR() are required if the bytes wrap around the end of the ring buffer.
* @note It is possible to receive items with a pxItemSize of 0 on no-split/allow split buffers. * @note It is possible to receive items with a pxItemSize of 0 on no-split buffers.
* @note To retrieve an item from an allow-split buffer, use `xRingbufferReceiveSplitFromISR()` instead.
* *
* @return * @return
* - Pointer to the retrieved item on success; *pxItemSize filled with the length of the item. * - Pointer to the retrieved item on success; *pxItemSize filled with the length of the item.

View File

@ -1124,6 +1124,7 @@ void *xRingbufferReceive(RingbufHandle_t xRingbuffer, size_t *pxItemSize, TickTy
//Check arguments //Check arguments
configASSERT(pxRingbuffer && pxItemSize); configASSERT(pxRingbuffer && pxItemSize);
configASSERT((pxRingbuffer->uxRingbufferFlags & rbALLOW_SPLIT_FLAG) == 0); // This function must not be called for allow-split buffers
//Attempt to retrieve an item //Attempt to retrieve an item
void *pvTempItem; void *pvTempItem;
@ -1140,6 +1141,7 @@ void *xRingbufferReceiveFromISR(RingbufHandle_t xRingbuffer, size_t *pxItemSize)
//Check arguments //Check arguments
configASSERT(pxRingbuffer && pxItemSize); configASSERT(pxRingbuffer && pxItemSize);
configASSERT((pxRingbuffer->uxRingbufferFlags & rbALLOW_SPLIT_FLAG) == 0); // This function must not be called for allow-split buffers
//Attempt to retrieve an item //Attempt to retrieve an item
void *pvTempItem; void *pvTempItem;

View File

@ -296,6 +296,10 @@ Byte buffers **do not allow multiple retrievals before returning** (every retrie
Referring to the diagram above, the 38 bytes of continuous stored data at the tail of the buffer is retrieved, returned, and freed. The next call to :cpp:func:`xRingbufferReceive` or :cpp:func:`xRingbufferReceiveFromISR` then wraps around and does the same to the 30 bytes of continuous stored data at the head of the buffer. Referring to the diagram above, the 38 bytes of continuous stored data at the tail of the buffer is retrieved, returned, and freed. The next call to :cpp:func:`xRingbufferReceive` or :cpp:func:`xRingbufferReceiveFromISR` then wraps around and does the same to the 30 bytes of continuous stored data at the head of the buffer.
.. note::
Retrieving items from Allow-Split buffers must be done via :cpp:func:`xRingbufferReceiveSplit` or :cpp:func:`xRingbufferReceiveSplitFromISR` instead of :cpp:func:`xRingbufferReceive` or :cpp:func:`xRingbufferReceiveFromISR`.
Ring Buffers with Queue Sets Ring Buffers with Queue Sets
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -296,6 +296,10 @@ ESP-IDF 环形 buffer 是一个典型的 FIFO buffer支持任意大小的数
参考上图, buffer 尾部 38 字节连续存储的数据被检索、返回和释放。然后,下一次调用 :cpp:func:`xRingbufferReceive`:cpp:func:`xRingbufferReceiveFromISR`buffer 将绕回并对头部的 30 字节连续存储数据进行同样的处理。 参考上图, buffer 尾部 38 字节连续存储的数据被检索、返回和释放。然后,下一次调用 :cpp:func:`xRingbufferReceive`:cpp:func:`xRingbufferReceiveFromISR`buffer 将绕回并对头部的 30 字节连续存储数据进行同样的处理。
.. note::
从可分割 buffer 中检索数据项必须使用 :cpp:func:`xRingbufferReceiveSplit`:cpp:func:`xRingbufferReceiveSplitFromISR`,而不是 :cpp:func:`xRingbufferReceive`:cpp:func:`xRingbufferReceiveFromISR`
使用队列集的环形 buffer 使用队列集的环形 buffer
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^