Skip to content

Commit

Permalink
Merge branch 'feature/ringbuf_add_create_with_caps' into 'master'
Browse files Browse the repository at this point in the history
esp_ringbuf: Add xRingbufferCreateWithCaps()

See merge request espressif/esp-idf!24377
  • Loading branch information
Dazza0 committed Jun 27, 2023
2 parents f2f5b41 + 7d983fe commit 9f52710
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
34 changes: 34 additions & 0 deletions components/esp_ringbuf/include/freertos/ringbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,40 @@ void vRingbufferGetInfo(RingbufHandle_t xRingbuffer,
*/
void xRingbufferPrintInfo(RingbufHandle_t xRingbuffer);

/**
* @brief Retrieve the pointers to a statically created ring buffer
*
* @param[in] xRingbuffer Ring buffer
* @param[out] ppucRingbufferStorage Used to return a pointer to the queue's storage area buffer
* @param[out] ppxStaticRingbuffer Used to return a pointer to the queue's data structure buffer
* @return pdTRUE if buffers were retrieved, pdFALSE otherwise.
*/
BaseType_t xRingbufferGetStaticBuffer(RingbufHandle_t xRingbuffer, uint8_t **ppucRingbufferStorage, StaticRingbuffer_t **ppxStaticRingbuffer);

/**
* @brief Creates a ring buffer with specific memory capabilities
*
* This function is similar to xRingbufferCreate(), except that it allows the
* memory allocated for the ring buffer to have specific capabilities (e.g.,
* MALLOC_CAP_INTERNAL).
*
* @note A queue created using this function must only be deleted using
* vRingbufferDeleteWithCaps()
* @param[in] xBufferSize Size of the buffer in bytes
* @param[in] xBufferType Type of ring buffer, see documentation.
* @param[in] uxMemoryCaps Memory capabilities of the queue's memory (see
* esp_heap_caps.h)
* @return Handle to the created ring buffer or NULL on failure.
*/
RingbufHandle_t xRingbufferCreateWithCaps(size_t xBufferSize, RingbufferType_t xBufferType, UBaseType_t uxMemoryCaps);

/**
* @brief Deletes a ring buffer previously created using xRingbufferCreateWithCaps()
*
* @param xRingbuffer Ring buffer
*/
void vRingbufferDeleteWithCaps(RingbufHandle_t xRingbuffer);

#ifdef __cplusplus
}
#endif
64 changes: 64 additions & 0 deletions components/esp_ringbuf/ringbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/ringbuf.h"
#include "esp_heap_caps.h"

// ------------------------------------------------- Macros and Types --------------------------------------------------

Expand Down Expand Up @@ -1360,3 +1361,66 @@ void xRingbufferPrintInfo(RingbufHandle_t xRingbuffer)
pxRingbuffer->pucWrite - pxRingbuffer->pucHead,
pxRingbuffer->pucAcquire - pxRingbuffer->pucHead);
}

BaseType_t xRingbufferGetStaticBuffer(RingbufHandle_t xRingbuffer, uint8_t **ppucRingbufferStorage, StaticRingbuffer_t **ppxStaticRingbuffer)
{
Ringbuffer_t *pxRingbuffer = (Ringbuffer_t *)xRingbuffer;
BaseType_t xReturn;

configASSERT(pxRingbuffer && ppucRingbufferStorage && ppxStaticRingbuffer);

if (pxRingbuffer->uxRingbufferFlags & rbBUFFER_STATIC_FLAG) {
*ppucRingbufferStorage = pxRingbuffer->pucHead;
*ppxStaticRingbuffer = (StaticRingbuffer_t *)pxRingbuffer;
xReturn = pdTRUE;
} else {
xReturn = pdFALSE;
}

return xReturn;
}

RingbufHandle_t xRingbufferCreateWithCaps(size_t xBufferSize, RingbufferType_t xBufferType, UBaseType_t uxMemoryCaps)
{
RingbufHandle_t xRingbuffer;
StaticRingbuffer_t *pxStaticRingbuffer;
uint8_t *pucRingbufferStorage;

pxStaticRingbuffer = heap_caps_malloc(sizeof(StaticRingbuffer_t), (uint32_t)uxMemoryCaps);
pucRingbufferStorage = heap_caps_malloc(xBufferSize, (uint32_t)uxMemoryCaps);

if (pxStaticRingbuffer == NULL || pucRingbufferStorage == NULL) {
goto err;
}

// Create the ring buffer using static creation API
xRingbuffer = xRingbufferCreateStatic(xBufferSize, xBufferType, pucRingbufferStorage, pxStaticRingbuffer);
if (xRingbuffer == NULL) {
goto err;
}

return xRingbuffer;

err:
heap_caps_free(pxStaticRingbuffer);
heap_caps_free(pucRingbufferStorage);
return NULL;
}

void vRingbufferDeleteWithCaps(RingbufHandle_t xRingbuffer)
{
BaseType_t xResult;
StaticRingbuffer_t *pxStaticRingbuffer = NULL;
uint8_t *pucRingbufferStorage = NULL;

// Retrieve the buffers used to create the ring buffer before deleting it
xResult = xRingbufferGetStaticBuffer(xRingbuffer, &pucRingbufferStorage, &pxStaticRingbuffer);
configASSERT(xResult == pdTRUE);

// Delete the ring buffer
vRingbufferDelete(xRingbuffer);

// Free the memory buffers
heap_caps_free(pxStaticRingbuffer);
heap_caps_free(pucRingbufferStorage);
}
31 changes: 30 additions & 1 deletion components/esp_ringbuf/test_apps/main/test_ringbuf.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -13,6 +13,7 @@
#include "freertos/ringbuf.h"
#include "driver/gptimer.h"
#include "esp_private/spi_flash_os.h"
#include "esp_memory_utils.h"
#include "esp_heap_caps.h"
#include "spi_flash_mmap.h"
#include "unity.h"
Expand Down Expand Up @@ -1093,3 +1094,31 @@ TEST_CASE("Test ringbuffer 0 item size", "[esp_ringbuf]")
vRingbufferDelete(allow_split_rb);
vRingbufferDelete(byte_rb);
}

/* --------------------- Test ring buffer create with caps ---------------------
* The following test case tests ring buffer creation with caps. Specifically
* the following APIs:
*
* - xRingbufferCreateWithCaps()
* - vRingbufferDeleteWithCaps()
* - xRingbufferGetStaticBuffer()
*/

TEST_CASE("Test ringbuffer with caps", "[esp_ringbuf]")
{
RingbufHandle_t rb_handle;
uint8_t *rb_storage;
StaticRingbuffer_t *rb_obj;

// Create ring buffer with caps
rb_handle = xRingbufferCreateWithCaps(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT, (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT));
TEST_ASSERT_NOT_EQUAL(NULL, rb_handle);

// Get the ring buffer's memory
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferGetStaticBuffer(rb_handle, &rb_storage, &rb_obj));
TEST_ASSERT(esp_ptr_in_dram(rb_storage));
TEST_ASSERT(esp_ptr_in_dram(rb_obj));

// Free the ring buffer
vRingbufferDeleteWithCaps(rb_handle);
}

0 comments on commit 9f52710

Please sign in to comment.