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 95f8eb12d3
commit 8b40eabce8
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
*/
@ -225,7 +225,8 @@ BaseType_t xRingbufferSendComplete(RingbufHandle_t xRingbuffer, void *pvItem);
* @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 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
* - 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 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 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
* - Pointer to the retrieved item on success; *pxItemSize filled with the length of the item.

View File

@ -1104,6 +1104,7 @@ void *xRingbufferReceive(RingbufHandle_t xRingbuffer, size_t *pxItemSize, TickTy
//Check arguments
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
void *pvTempItem;
@ -1120,6 +1121,7 @@ void *xRingbufferReceiveFromISR(RingbufHandle_t xRingbuffer, size_t *pxItemSize)
//Check arguments
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
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.
.. 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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -296,6 +296,10 @@ ESP-IDF 环形 buffer 是一个典型的 FIFO buffer支持任意大小的数
参考上图, 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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^