From 3f5f6ec13ef47a8a7d2ba75b9ef9b4997baa54ec Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Wed, 19 Mar 2025 12:09:08 +0100 Subject: [PATCH] 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. --- components/esp_ringbuf/include/freertos/ringbuf.h | 8 +++++--- components/esp_ringbuf/ringbuf.c | 2 ++ docs/en/api-reference/system/freertos_additions.rst | 4 ++++ docs/zh_CN/api-reference/system/freertos_additions.rst | 4 ++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/components/esp_ringbuf/include/freertos/ringbuf.h b/components/esp_ringbuf/include/freertos/ringbuf.h index dc176a233a..4fea2262f3 100644 --- a/components/esp_ringbuf/include/freertos/ringbuf.h +++ b/components/esp_ringbuf/include/freertos/ringbuf.h @@ -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. diff --git a/components/esp_ringbuf/ringbuf.c b/components/esp_ringbuf/ringbuf.c index b97672af3a..d69d96fee0 100644 --- a/components/esp_ringbuf/ringbuf.c +++ b/components/esp_ringbuf/ringbuf.c @@ -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; diff --git a/docs/en/api-reference/system/freertos_additions.rst b/docs/en/api-reference/system/freertos_additions.rst index a4e8ea8f11..c883afa038 100644 --- a/docs/en/api-reference/system/freertos_additions.rst +++ b/docs/en/api-reference/system/freertos_additions.rst @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-reference/system/freertos_additions.rst b/docs/zh_CN/api-reference/system/freertos_additions.rst index eb2f0f41b4..c0a7633068 100644 --- a/docs/zh_CN/api-reference/system/freertos_additions.rst +++ b/docs/zh_CN/api-reference/system/freertos_additions.rst @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^