mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/ringbuf_read_pointer_wrap_v4.1' into 'release/v4.1'
ringbuf: Fix bug where comparision between a signed and unsigned operand resulted in incorrect free size for no-split/allow-split buffers (v4.1) See merge request espressif/esp-idf!15884
This commit is contained in:
commit
fa9ca143c1
@ -33,7 +33,7 @@
|
||||
#define rbITEM_FREE_FLAG ( ( UBaseType_t ) 1 ) //Item has been retrieved and returned by application, free to overwrite
|
||||
#define rbITEM_DUMMY_DATA_FLAG ( ( UBaseType_t ) 2 ) //Data from here to end of the ring buffer is dummy data. Restart reading at start of head of the buffer
|
||||
#define rbITEM_SPLIT_FLAG ( ( UBaseType_t ) 4 ) //Valid for RINGBUF_TYPE_ALLOWSPLIT, indicating that rest of the data is wrapped around
|
||||
#define rbITEM_WRITTEN_FLAG ( ( UBaseType_t ) 8 ) //Item has been written to by the application, thus it is free to be read
|
||||
#define rbITEM_WRITTEN_FLAG ( ( UBaseType_t ) 8 ) //Item has been written to by the application, thus can be read
|
||||
|
||||
//Static allocation related
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
@ -142,16 +142,41 @@ static BaseType_t prvCheckItemFitsDefault( Ringbuffer_t *pxRingbuffer, size_t xI
|
||||
//Checks if an item will currently fit in a byte buffer
|
||||
static BaseType_t prvCheckItemFitsByteBuffer( Ringbuffer_t *pxRingbuffer, size_t xItemSize);
|
||||
|
||||
//Copies an item to a no-split ring buffer. Only call this function after calling prvCheckItemFitsDefault()
|
||||
/*
|
||||
Copies an item to a no-split ring buffer
|
||||
Entry:
|
||||
- Must have already guaranteed there is sufficient space for item by calling prvCheckItemFitsDefault()
|
||||
Exit:
|
||||
- New item copied into ring buffer
|
||||
- pucAcquire and pucWrite updated.
|
||||
- Dummy item added if necessary
|
||||
*/
|
||||
static void prvCopyItemNoSplit(Ringbuffer_t *pxRingbuffer, const uint8_t *pucItem, size_t xItemSize);
|
||||
|
||||
//Copies an item to a allow-split ring buffer. Only call this function after calling prvCheckItemFitsDefault()
|
||||
/*
|
||||
Copies an item to a allow-split ring buffer
|
||||
Entry:
|
||||
- Must have already guaranteed there is sufficient space for item by calling prvCheckItemFitsDefault()
|
||||
Exit:
|
||||
- New item copied into ring buffer
|
||||
- pucAcquire and pucWrite updated
|
||||
- Item may be split
|
||||
*/
|
||||
static void prvCopyItemAllowSplit(Ringbuffer_t *pxRingbuffer, const uint8_t *pucItem, size_t xItemSize);
|
||||
|
||||
//Copies an item to a byte buffer. Only call this function after calling prvCheckItemFitsByteBuffer()
|
||||
static void prvCopyItemByteBuf(Ringbuffer_t *pxRingbuffer, const uint8_t *pucItem, size_t xItemSize);
|
||||
|
||||
//Retrieve item from no-split/allow-split ring buffer. *pxIsSplit is set to pdTRUE if the retrieved item is split
|
||||
/*
|
||||
Entry:
|
||||
- Must have already guaranteed that there is an item available for retrieval by calling prvCheckItemAvail()
|
||||
- Guaranteed that pucREAD points to a valid item (i.e., not a dummy item)
|
||||
Exit:
|
||||
- Item is returned. Only first half returned if split
|
||||
- pucREAD updated to point to next valid item to read, or equals to pucWrite if there are no more valid items to read
|
||||
- pucREAD update must skip over dummy items
|
||||
*/
|
||||
static void *prvGetItemDefault(Ringbuffer_t *pxRingbuffer,
|
||||
BaseType_t *pxIsSplit,
|
||||
size_t xUnusedParam,
|
||||
@ -163,7 +188,12 @@ static void *prvGetItemByteBuf(Ringbuffer_t *pxRingbuffer,
|
||||
size_t xMaxSize,
|
||||
size_t *pxItemSize);
|
||||
|
||||
//Return an item to a split/no-split ring buffer
|
||||
/*
|
||||
Return an item to a split/no-split ring buffer
|
||||
Exit:
|
||||
- Item is marked free rbITEM_FREE_FLAG
|
||||
- pucFree is progressed as far as possible, skipping over already freed items or dummy items
|
||||
*/
|
||||
static void prvReturnItemDefault(Ringbuffer_t *pxRingbuffer, uint8_t *pucItem);
|
||||
|
||||
//Return data to a byte buffer
|
||||
@ -391,7 +421,7 @@ static void prvSendItemDoneNoSplit(Ringbuffer_t *pxRingbuffer, uint8_t* pucItem)
|
||||
//Redundancy check to ensure write pointer has not overshot buffer bounds
|
||||
configASSERT(pxRingbuffer->pucWrite <= pxRingbuffer->pucHead + pxRingbuffer->xSize);
|
||||
}
|
||||
//Check if pucAcquire requires wrap around
|
||||
//Check if pucWrite requires wrap around
|
||||
if ((pxRingbuffer->pucTail - pxRingbuffer->pucWrite) < rbHEADER_SIZE) {
|
||||
pxRingbuffer->pucWrite = pxRingbuffer->pucHead;
|
||||
}
|
||||
@ -532,7 +562,7 @@ static void *prvGetItemDefault(Ringbuffer_t *pxRingbuffer,
|
||||
//Inclusive of pucTail for special case where item of zero length just fits at the end of the buffer
|
||||
configASSERT(pcReturn >= pxRingbuffer->pucHead && pcReturn <= pxRingbuffer->pucTail);
|
||||
} else {
|
||||
//Exclusive of pucTali if length is larger than zero, pcReturn should never point to pucTail
|
||||
//Exclusive of pucTail if length is larger than zero, pcReturn should never point to pucTail
|
||||
configASSERT(pcReturn >= pxRingbuffer->pucHead && pcReturn < pxRingbuffer->pucTail);
|
||||
}
|
||||
*pxItemSize = pxHeader->xItemLen; //Get length of item
|
||||
@ -622,7 +652,7 @@ static void prvReturnItemDefault(Ringbuffer_t *pxRingbuffer, uint8_t *pucItem)
|
||||
//Redundancy check to ensure free pointer has not overshot buffer bounds
|
||||
configASSERT(pxRingbuffer->pucFree <= pxRingbuffer->pucHead + pxRingbuffer->xSize);
|
||||
}
|
||||
//Check if pucRead requires wrap around
|
||||
//Check if pucFree requires wrap around
|
||||
if ((pxRingbuffer->pucTail - pxRingbuffer->pucFree) < rbHEADER_SIZE) {
|
||||
pxRingbuffer->pucFree = pxRingbuffer->pucHead;
|
||||
}
|
||||
@ -673,12 +703,15 @@ static size_t prvGetCurMaxSizeNoSplit(Ringbuffer_t *pxRingbuffer)
|
||||
|
||||
//No-split ring buffer items need space for a header
|
||||
xFreeSize -= rbHEADER_SIZE;
|
||||
//Limit free size to be within bounds
|
||||
if (xFreeSize > pxRingbuffer->xMaxItemSize) {
|
||||
xFreeSize = pxRingbuffer->xMaxItemSize;
|
||||
} else if (xFreeSize < 0) {
|
||||
|
||||
//Check for xFreeSize < 0 before checking xFreeSize > pxRingbuffer->xMaxItemSize
|
||||
//to avoid incorrect comparison operation when xFreeSize is negative
|
||||
if (xFreeSize < 0) {
|
||||
//Occurs when free space is less than header size
|
||||
xFreeSize = 0;
|
||||
} else if (xFreeSize > pxRingbuffer->xMaxItemSize) {
|
||||
//Limit free size to be within bounds
|
||||
xFreeSize = pxRingbuffer->xMaxItemSize;
|
||||
}
|
||||
return xFreeSize;
|
||||
}
|
||||
@ -703,11 +736,13 @@ static size_t prvGetCurMaxSizeAllowSplit(Ringbuffer_t *pxRingbuffer)
|
||||
(rbHEADER_SIZE * 2);
|
||||
}
|
||||
|
||||
//Limit free size to be within bounds
|
||||
if (xFreeSize > pxRingbuffer->xMaxItemSize) {
|
||||
xFreeSize = pxRingbuffer->xMaxItemSize;
|
||||
} else if (xFreeSize < 0) {
|
||||
//Check for xFreeSize < 0 before checking xFreeSize > pxRingbuffer->xMaxItemSize
|
||||
//to avoid incorrect comparison operation when xFreeSize is negative
|
||||
if (xFreeSize < 0) {
|
||||
xFreeSize = 0;
|
||||
} else if (xFreeSize > pxRingbuffer->xMaxItemSize) {
|
||||
//Limit free size to be within bounds
|
||||
xFreeSize = pxRingbuffer->xMaxItemSize;
|
||||
}
|
||||
return xFreeSize;
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@ -16,7 +22,8 @@
|
||||
#define NO_OF_RB_TYPES 3
|
||||
#define ITEM_HDR_SIZE 8
|
||||
#define SMALL_ITEM_SIZE 8
|
||||
#define LARGE_ITEM_SIZE (2 * SMALL_ITEM_SIZE)
|
||||
#define MEDIUM_ITEM_SIZE ((3 * SMALL_ITEM_SIZE) >> 1) //12 bytes
|
||||
#define LARGE_ITEM_SIZE (2 * SMALL_ITEM_SIZE) //16 bytes
|
||||
#define BUFFER_SIZE 160 //4Byte aligned size
|
||||
|
||||
static const uint8_t small_item[SMALL_ITEM_SIZE] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
|
||||
@ -36,6 +43,17 @@ static void send_item_and_check(RingbufHandle_t handle, const uint8_t *item, si
|
||||
TEST_ASSERT_MESSAGE(ret == pdTRUE, "Failed to send item");
|
||||
}
|
||||
|
||||
static void send_item_and_check_failure(RingbufHandle_t handle, const uint8_t *item, size_t item_size, TickType_t ticks_to_wait, bool in_isr)
|
||||
{
|
||||
BaseType_t ret;
|
||||
if (in_isr) {
|
||||
ret = xRingbufferSendFromISR(handle, (void *)item, item_size, NULL);
|
||||
} else {
|
||||
ret = xRingbufferSend(handle, (void *)item, item_size, ticks_to_wait);
|
||||
}
|
||||
TEST_ASSERT_MESSAGE(ret == pdFALSE, "Sent an item to a full buffer");
|
||||
}
|
||||
|
||||
static void receive_check_and_return_item_no_split(RingbufHandle_t handle, const uint8_t *expected_data, size_t expected_size, TickType_t ticks_to_wait, bool in_isr)
|
||||
{
|
||||
//Receive item from no-split buffer
|
||||
@ -72,7 +90,6 @@ static void receive_check_and_return_item_allow_split(RingbufHandle_t handle, co
|
||||
} else {
|
||||
ret = xRingbufferReceiveSplit(handle, (void**)&item1, (void **)&item2, &item_size1, &item_size2, ticks_to_wait);
|
||||
}
|
||||
//= xRingbufferReceiveSplit(handle, (void**)&item1, (void **)&item2, &item_size1, &item_size2, ticks_to_wait);
|
||||
TEST_ASSERT_MESSAGE(ret == pdTRUE, "Failed to receive item");
|
||||
TEST_ASSERT_MESSAGE(item1 != NULL, "Failed to receive item");
|
||||
|
||||
@ -158,19 +175,37 @@ static void receive_check_and_return_item_byte_buffer(RingbufHandle_t handle, co
|
||||
}
|
||||
|
||||
/* ----------------- Basic ring buffer behavior tests cases --------------------
|
||||
* The following test cases will test basic send, receive, and wrap around
|
||||
* behavior of each type of ring buffer. Each test case will do the following
|
||||
* 1) Send multiple items (nearly fill the buffer)
|
||||
* 2) Receive and check the sent items (also prepares the buffer for a wrap around
|
||||
* 3) Send a final item that causes a wrap around
|
||||
* 4) Receive and check the wrapped item
|
||||
* The following set of test cases will test basic send, receive, wrap around and buffer full
|
||||
* behavior of each type of ring buffer.
|
||||
* Test Case 1:
|
||||
* 1) Send multiple items (nearly fill the buffer)
|
||||
* 2) Receive and check the sent items (also prepares the buffer for a wrap around)
|
||||
* 3) Send a final item that causes a wrap around
|
||||
* 4) Receive and check the wrapped item
|
||||
*
|
||||
* Test Case 2:
|
||||
* 1) Send multiple items (completely fill the buffer)
|
||||
* 2) Send another item and verify that send failure occurs
|
||||
* 3) Receive one item and verify that space is freed up in the buffer
|
||||
* 4) Receive and check the remaining sent items
|
||||
*
|
||||
* Test Case 3:
|
||||
* 1) Send multiple items (nearly fill the buffer)
|
||||
* 2) Send another small sized item to fill the buffer without causing a wrap around (not needed in case of byte buffer)
|
||||
* 2) Send another item and verify that send failure occurs
|
||||
* 4) Receive and check the sent items
|
||||
*/
|
||||
|
||||
TEST_CASE("Test ring buffer No-Split", "[esp_ringbuf]")
|
||||
TEST_CASE("TC#1: No-Split", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE/2 - ITEM_HDR_SIZE.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect max item size received");
|
||||
|
||||
//Calculate number of items to send. Aim to almost fill buffer to setup for wrap around
|
||||
int no_of_items = (BUFFER_SIZE - (ITEM_HDR_SIZE + SMALL_ITEM_SIZE)) / (ITEM_HDR_SIZE + SMALL_ITEM_SIZE);
|
||||
|
||||
@ -178,11 +213,21 @@ TEST_CASE("Test ring buffer No-Split", "[esp_ringbuf]")
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_items, "Incorrect items waiting");
|
||||
|
||||
//Test receiving items
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
receive_check_and_return_item_no_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
|
||||
|
||||
//Write pointer should be near the end, test wrap around
|
||||
uint32_t write_pos_before, write_pos_after;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, &write_pos_before, NULL, NULL);
|
||||
@ -197,11 +242,112 @@ TEST_CASE("Test ring buffer No-Split", "[esp_ringbuf]")
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("Test ring buffer Allow-Split", "[esp_ringbuf]")
|
||||
TEST_CASE("TC#2: No-Split", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE/2 - ITEM_HDR_SIZE.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect max item size received");
|
||||
|
||||
//Calculate number of items to send. Aim to fill the buffer
|
||||
int no_of_items = (BUFFER_SIZE) / (ITEM_HDR_SIZE + SMALL_ITEM_SIZE);
|
||||
|
||||
//Test sending items
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_items, "Incorrect items waiting");
|
||||
|
||||
//At this point, the buffer should be full.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved");
|
||||
|
||||
//Send an item. The item should not be sent to a full buffer.
|
||||
send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//Receive one item
|
||||
receive_check_and_return_item_no_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//At this point, the buffer should not be full any more
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) > 0, "Buffer should have free space");
|
||||
|
||||
//Test receiving remaining items
|
||||
for (int i = 0; i < no_of_items - 1; i++) {
|
||||
receive_check_and_return_item_no_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
|
||||
|
||||
//Cleanup
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("TC#3: No-Split", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE/2 - ITEM_HDR_SIZE.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect max item size received");
|
||||
|
||||
//Calculate number of medium items to send. Aim to almost fill the buffer
|
||||
int no_of_medium_items = (BUFFER_SIZE - (ITEM_HDR_SIZE + MEDIUM_ITEM_SIZE)) / (ITEM_HDR_SIZE + MEDIUM_ITEM_SIZE);
|
||||
|
||||
//Test sending items
|
||||
for (int i = 0; i < no_of_medium_items; i++) {
|
||||
send_item_and_check(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of medium items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_medium_items, "Incorrect items waiting");
|
||||
|
||||
//Send one small sized item. This will ensure that the item fits at the end of the buffer without causing the write pointer to wrap around.
|
||||
send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//The buffer should not have any free space as the number of bytes remaining should be < ITEM_HDR_SIZE.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved");
|
||||
|
||||
//Send an item. The item should not be sent to a full buffer.
|
||||
send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//Test receiving medium items
|
||||
for (int i = 0; i < no_of_medium_items; i++) {
|
||||
receive_check_and_return_item_no_split(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Test receiving small item
|
||||
receive_check_and_return_item_no_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
|
||||
|
||||
//Cleanup
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("TC#1: Allow-Split", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_ALLOWSPLIT);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE - (ITEM_HDR_SIZE * 2).
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect max item size received");
|
||||
|
||||
//Calculate number of items to send. Aim to almost fill buffer to setup for wrap around
|
||||
int no_of_items = (BUFFER_SIZE - (ITEM_HDR_SIZE + SMALL_ITEM_SIZE)) / (ITEM_HDR_SIZE + SMALL_ITEM_SIZE);
|
||||
|
||||
@ -209,11 +355,21 @@ TEST_CASE("Test ring buffer Allow-Split", "[esp_ringbuf]")
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_items, "Incorrect items waiting");
|
||||
|
||||
//Test receiving items
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
receive_check_and_return_item_allow_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
|
||||
|
||||
//Write pointer should be near the end, test wrap around
|
||||
uint32_t write_pos_before, write_pos_after;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, &write_pos_before, NULL, NULL);
|
||||
@ -228,11 +384,112 @@ TEST_CASE("Test ring buffer Allow-Split", "[esp_ringbuf]")
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("Test ring buffer Byte Buffer", "[esp_ringbuf]")
|
||||
TEST_CASE("TC#2: Allow-Split", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_ALLOWSPLIT);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE - (ITEM_HDR_SIZE * 2).
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect max item size received");
|
||||
|
||||
//Calculate number of items to send. Aim to fill the buffer
|
||||
int no_of_items = (BUFFER_SIZE) / (ITEM_HDR_SIZE + SMALL_ITEM_SIZE);
|
||||
|
||||
//Test sending items
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_items, "Incorrect items waiting");
|
||||
|
||||
//At this point, the buffer should be full.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved");
|
||||
|
||||
//Send an item. The item should not be sent to a full buffer.
|
||||
send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//Receive one item
|
||||
receive_check_and_return_item_allow_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//At this point, the buffer should not be full any more
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) > 0, "Buffer should have free space");
|
||||
|
||||
//Test receiving remaining items
|
||||
for (int i = 0; i < no_of_items - 1; i++) {
|
||||
receive_check_and_return_item_allow_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
|
||||
|
||||
//Cleanup
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("TC#3: Allow-Split", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_ALLOWSPLIT);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE - (ITEM_HDR_SIZE * 2).
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect max item size received");
|
||||
|
||||
//Calculate number of medium items to send. Aim to almost fill the buffer
|
||||
int no_of_medium_items = (BUFFER_SIZE - (ITEM_HDR_SIZE + MEDIUM_ITEM_SIZE)) / (ITEM_HDR_SIZE + MEDIUM_ITEM_SIZE);
|
||||
|
||||
//Test sending items
|
||||
for (int i = 0; i < no_of_medium_items; i++) {
|
||||
send_item_and_check(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of medium items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_medium_items, "Incorrect items waiting");
|
||||
|
||||
//Send one small sized item. This will ensure that the item fits at the end of the buffer without causing the write pointer to wrap around.
|
||||
send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//The buffer should not have any free space as the number of bytes remaining should be < ITEM_HDR_SIZE.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved");
|
||||
|
||||
//Send an item. The item should not be sent to a full buffer.
|
||||
send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//Test receiving medium items
|
||||
for (int i = 0; i < no_of_medium_items; i++) {
|
||||
receive_check_and_return_item_allow_split(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Test receiving small item
|
||||
receive_check_and_return_item_allow_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
|
||||
|
||||
//Cleanup
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("TC#1: Byte buffer", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_BYTEBUF);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == BUFFER_SIZE, "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == BUFFER_SIZE, "Incorrect max item size received");
|
||||
|
||||
//Calculate number of items to send. Aim to almost fill buffer to setup for wrap around
|
||||
int no_of_items = (BUFFER_SIZE - SMALL_ITEM_SIZE) / SMALL_ITEM_SIZE;
|
||||
|
||||
@ -240,11 +497,21 @@ TEST_CASE("Test ring buffer Byte Buffer", "[esp_ringbuf]")
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_items * SMALL_ITEM_SIZE, "Incorrect number of bytes waiting");
|
||||
|
||||
//Test receiving items
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
receive_check_and_return_item_byte_buffer(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect number of bytes waiting");
|
||||
|
||||
//Write pointer should be near the end, test wrap around
|
||||
uint32_t write_pos_before, write_pos_after;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, &write_pos_before, NULL, NULL);
|
||||
@ -259,6 +526,96 @@ TEST_CASE("Test ring buffer Byte Buffer", "[esp_ringbuf]")
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("TC#2: Byte buffer", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_BYTEBUF);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == BUFFER_SIZE, "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == BUFFER_SIZE, "Incorrect max item size received");
|
||||
|
||||
//Calculate number of items to send. Aim to fill the buffer
|
||||
int no_of_items = BUFFER_SIZE / SMALL_ITEM_SIZE;
|
||||
|
||||
//Test sending items
|
||||
for (int i = 0; i < no_of_items; i++) {
|
||||
send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_items * SMALL_ITEM_SIZE, "Incorrect number of bytes waiting");
|
||||
|
||||
//At this point, the buffer should be full.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved");
|
||||
|
||||
//Send an item. The item should not be sent to a full buffer.
|
||||
send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//Receive one item
|
||||
receive_check_and_return_item_byte_buffer(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//At this point, the buffer should not be full any more
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) > 0, "Buffer should have free space");
|
||||
|
||||
//Test receiving remaining items
|
||||
for (int i = 0; i < no_of_items - 1; i++) {
|
||||
receive_check_and_return_item_byte_buffer(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
|
||||
|
||||
//Cleanup
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("TC#3: Byte buffer", "[esp_ringbuf]")
|
||||
{
|
||||
//Create buffer
|
||||
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_BYTEBUF);
|
||||
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
|
||||
|
||||
//Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == BUFFER_SIZE, "Incorrect buffer free size received");
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == BUFFER_SIZE, "Incorrect max item size received");
|
||||
|
||||
//Calculate number of medium items to send. Aim to almost fill the buffer
|
||||
int no_of_medium_items = BUFFER_SIZE / MEDIUM_ITEM_SIZE;
|
||||
|
||||
//Test sending items
|
||||
for (int i = 0; i < no_of_medium_items; i++) {
|
||||
send_item_and_check(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify items waiting matches with the number of medium items sent
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == no_of_medium_items * MEDIUM_ITEM_SIZE, "Incorrect number of bytes waiting");
|
||||
|
||||
//The buffer should not have any free space for one small item.
|
||||
TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) < SMALL_ITEM_SIZE, "Buffer full not achieved");
|
||||
|
||||
//Send an item. The item should not be sent to a full buffer.
|
||||
send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
|
||||
//Test receiving medium items
|
||||
for (int i = 0; i < no_of_medium_items; i++) {
|
||||
receive_check_and_return_item_byte_buffer(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false);
|
||||
}
|
||||
|
||||
//Verify that no items are waiting
|
||||
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
|
||||
|
||||
//Cleanup
|
||||
vRingbufferDelete(buffer_handle);
|
||||
}
|
||||
|
||||
/* ----------------------- Ring buffer queue sets test ------------------------
|
||||
* The following test case will test receiving from ring buffers that have been
|
||||
* added to a queue set. The test case will do the following...
|
||||
|
Loading…
Reference in New Issue
Block a user