mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 18:10:57 +02:00
feat(esp_ringbuf): Add vRingbufferReset
Function has similar behavior to xQueueReset() where... - Buffer is emptied - Blocked sender is unblocked Aslo added associated unit test cases.
This commit is contained in:
committed by
Guillaume Souchere
parent
13ec7d2d2a
commit
589d5b132d
@@ -386,6 +386,15 @@ void vRingbufferReturnItem(RingbufHandle_t xRingbuffer, void *pvItem);
|
|||||||
*/
|
*/
|
||||||
void vRingbufferReturnItemFromISR(RingbufHandle_t xRingbuffer, void *pvItem, BaseType_t *pxHigherPriorityTaskWoken);
|
void vRingbufferReturnItemFromISR(RingbufHandle_t xRingbuffer, void *pvItem, BaseType_t *pxHigherPriorityTaskWoken);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset a ring buffer back to its original empty state
|
||||||
|
*
|
||||||
|
* @param[in] xRingbuffer Ring buffer to reset
|
||||||
|
*
|
||||||
|
* @note Users must ensure that all buffers are returned before calling this function
|
||||||
|
*/
|
||||||
|
void vRingbufferReset(RingbufHandle_t xRingbuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Delete a ring buffer
|
* @brief Delete a ring buffer
|
||||||
*
|
*
|
||||||
|
@@ -1252,6 +1252,32 @@ void vRingbufferReturnItemFromISR(RingbufHandle_t xRingbuffer, void *pvItem, Bas
|
|||||||
portEXIT_CRITICAL_ISR(&pxRingbuffer->mux);
|
portEXIT_CRITICAL_ISR(&pxRingbuffer->mux);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vRingbufferReset(RingbufHandle_t xRingbuffer)
|
||||||
|
{
|
||||||
|
Ringbuffer_t *pxRingbuffer = (Ringbuffer_t *)xRingbuffer;
|
||||||
|
configASSERT(pxRingbuffer);
|
||||||
|
|
||||||
|
portENTER_CRITICAL(&pxRingbuffer->mux);
|
||||||
|
// Check for unreturned buffers
|
||||||
|
configASSERT(pxRingbuffer->pucAcquire == pxRingbuffer->pucWrite);
|
||||||
|
configASSERT(pxRingbuffer->pucRead == pxRingbuffer->pucFree);
|
||||||
|
// Reset state
|
||||||
|
pxRingbuffer->pucAcquire = pxRingbuffer->pucHead;
|
||||||
|
pxRingbuffer->pucWrite = pxRingbuffer->pucHead;
|
||||||
|
pxRingbuffer->pucRead = pxRingbuffer->pucHead;
|
||||||
|
pxRingbuffer->pucFree = pxRingbuffer->pucHead;
|
||||||
|
pxRingbuffer->xItemsWaiting = 0;
|
||||||
|
pxRingbuffer->uxRingbufferFlags &= ~rbBUFFER_FULL_FLAG;
|
||||||
|
|
||||||
|
// If there's a task waiting to transmit, unblock it
|
||||||
|
if (listLIST_IS_EMPTY(&pxRingbuffer->xTasksWaitingToSend) == pdFALSE) {
|
||||||
|
if (xTaskRemoveFromEventList(&pxRingbuffer->xTasksWaitingToSend) == pdTRUE) {
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL(&pxRingbuffer->mux);
|
||||||
|
}
|
||||||
|
|
||||||
void vRingbufferDelete(RingbufHandle_t xRingbuffer)
|
void vRingbufferDelete(RingbufHandle_t xRingbuffer)
|
||||||
{
|
{
|
||||||
Ringbuffer_t *pxRingbuffer = (Ringbuffer_t *)xRingbuffer;
|
Ringbuffer_t *pxRingbuffer = (Ringbuffer_t *)xRingbuffer;
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "freertos/ringbuf.h"
|
#include "freertos/ringbuf.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
#include "esp_task.h"
|
||||||
|
|
||||||
#include "test_functions.h"
|
#include "test_functions.h"
|
||||||
|
|
||||||
@@ -1318,3 +1319,62 @@ TEST_CASE("Test no-split full buffer becomes empty when oldest is returned last"
|
|||||||
TEST_ASSERT_NOT_NULL(slot);
|
TEST_ASSERT_NOT_NULL(slot);
|
||||||
vRingbufferDelete(buffer_handle);
|
vRingbufferDelete(buffer_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------- Test ring buffer reset --------------------------------------
|
||||||
|
* Reset Case: Test that vRingbufferReset() empties the ring buffer
|
||||||
|
* Reset unblocks sender: Test that vRingbufferReset() will unblock a previously blocked sender
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint8_t item[SMALL_ITEM_SIZE] = {0};
|
||||||
|
|
||||||
|
TEST_CASE("Test ring buffer reset", "[esp_ringbuf][linux]")
|
||||||
|
{
|
||||||
|
// Create buffer
|
||||||
|
RingbufHandle_t rb = xRingbufferCreate(SMALL_ITEM_SIZE, RINGBUF_TYPE_BYTEBUF);
|
||||||
|
TEST_ASSERT_MESSAGE(rb != NULL, "Failed to create ring buffer");
|
||||||
|
// Fill buffer
|
||||||
|
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferSend(rb, item, SMALL_ITEM_SIZE, 0));
|
||||||
|
// Confirm buffer is full
|
||||||
|
TEST_ASSERT_EQUAL(0, xRingbufferGetCurFreeSize(rb));
|
||||||
|
// Reset ring buffer
|
||||||
|
vRingbufferReset(rb);
|
||||||
|
// Confirm buffer is empty
|
||||||
|
TEST_ASSERT_EQUAL(SMALL_ITEM_SIZE, xRingbufferGetCurFreeSize(rb));
|
||||||
|
// Cleanup
|
||||||
|
vRingbufferDelete(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static volatile bool post_reset_send = false;
|
||||||
|
|
||||||
|
static void post_reset_send_task(void *arg)
|
||||||
|
{
|
||||||
|
RingbufHandle_t rb = (RingbufHandle_t)arg;
|
||||||
|
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferSend(rb, item, SMALL_ITEM_SIZE, portMAX_DELAY));
|
||||||
|
post_reset_send = true;
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test ring buffer reset unblocks sender ", "[esp_ringbuf][linux]")
|
||||||
|
{
|
||||||
|
// Create buffer
|
||||||
|
RingbufHandle_t rb = xRingbufferCreate(SMALL_ITEM_SIZE, RINGBUF_TYPE_BYTEBUF);
|
||||||
|
TEST_ASSERT_MESSAGE(rb != NULL, "Failed to create ring buffer");
|
||||||
|
// Fill buffer
|
||||||
|
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferSend(rb, item, SMALL_ITEM_SIZE, 0));
|
||||||
|
// Confirm buffer is full
|
||||||
|
TEST_ASSERT_EQUAL(0, xRingbufferGetCurFreeSize(rb));
|
||||||
|
// Launch task to block on sending to full ring buffer
|
||||||
|
post_reset_send = false;
|
||||||
|
xTaskCreatePinnedToCore(post_reset_send_task, "send tsk", 2048, (void*)rb, ESP_TASK_MAIN_PRIO + 1, NULL, 0);
|
||||||
|
vTaskDelay(10);
|
||||||
|
// Confirm blocked task has not sent
|
||||||
|
TEST_ASSERT_EQUAL(false, post_reset_send);
|
||||||
|
// Reset the ring buffer
|
||||||
|
vRingbufferReset(rb);
|
||||||
|
// Check task has unblocked and sent
|
||||||
|
vTaskDelay(1);
|
||||||
|
TEST_ASSERT_EQUAL(true, post_reset_send);
|
||||||
|
// Cleanup
|
||||||
|
vRingbufferDelete(rb);
|
||||||
|
vTaskDelay(1);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user