esp_ringbuf: Add xRingbufferCreateWithCaps()

This commit adds APIS to create a ring buffer with specific memory caps. The
following APIs have been added:

- xRingbufferGetStaticBuffer()
- xRingbufferCreateWithCaps()
- vRingbufferDeleteWithCaps()
This commit is contained in:
Darian Leung 2023-06-24 21:30:53 +08:00
parent ddb9c1172f
commit 7d983fe5a3
3 changed files with 128 additions and 1 deletions

View File

@ -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

View File

@ -11,6 +11,7 @@
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/ringbuf.h"
#include "esp_heap_caps.h"
// ------------------------------------------------- Macros and Types --------------------------------------------------
@ -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);
}

View File

@ -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
*/
@ -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"
@ -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);
}