Procházet zdrojové kódy

Merge branch 'feature/ringbuf_add_create_with_caps' into 'master'

esp_ringbuf: Add xRingbufferCreateWithCaps()

See merge request espressif/esp-idf!24377
Darian před 2 roky
rodič
revize
9f5271031d

+ 34 - 0
components/esp_ringbuf/include/freertos/ringbuf.h

@@ -513,6 +513,40 @@ void vRingbufferGetInfo(RingbufHandle_t xRingbuffer,
  */
  */
 void xRingbufferPrintInfo(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
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 64 - 0
components/esp_ringbuf/ringbuf.c

@@ -11,6 +11,7 @@
 #include "freertos/task.h"
 #include "freertos/task.h"
 #include "freertos/queue.h"
 #include "freertos/queue.h"
 #include "freertos/ringbuf.h"
 #include "freertos/ringbuf.h"
+#include "esp_heap_caps.h"
 
 
 // ------------------------------------------------- Macros and Types --------------------------------------------------
 // ------------------------------------------------- Macros and Types --------------------------------------------------
 
 
@@ -1360,3 +1361,66 @@ void xRingbufferPrintInfo(RingbufHandle_t xRingbuffer)
            pxRingbuffer->pucWrite - pxRingbuffer->pucHead,
            pxRingbuffer->pucWrite - pxRingbuffer->pucHead,
            pxRingbuffer->pucAcquire - 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);
+}

+ 30 - 1
components/esp_ringbuf/test_apps/main/test_ringbuf.c

@@ -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
  * SPDX-License-Identifier: Apache-2.0
  */
  */
@@ -13,6 +13,7 @@
 #include "freertos/ringbuf.h"
 #include "freertos/ringbuf.h"
 #include "driver/gptimer.h"
 #include "driver/gptimer.h"
 #include "esp_private/spi_flash_os.h"
 #include "esp_private/spi_flash_os.h"
+#include "esp_memory_utils.h"
 #include "esp_heap_caps.h"
 #include "esp_heap_caps.h"
 #include "spi_flash_mmap.h"
 #include "spi_flash_mmap.h"
 #include "unity.h"
 #include "unity.h"
@@ -1093,3 +1094,31 @@ TEST_CASE("Test ringbuffer 0 item size", "[esp_ringbuf]")
     vRingbufferDelete(allow_split_rb);
     vRingbufferDelete(allow_split_rb);
     vRingbufferDelete(byte_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);
+}