1382 lines
56 KiB
C
1382 lines
56 KiB
C
/*
|
|
* FreeRTOS V202111.00
|
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* https://www.FreeRTOS.org
|
|
* https://github.com/FreeRTOS
|
|
*
|
|
*/
|
|
/*! @file stream_buffer_utest.c */
|
|
|
|
/* C runtime includes. */
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
|
|
/* Stream Buffer includes */
|
|
#include "FreeRTOS.h"
|
|
#include "FreeRTOSConfig.h"
|
|
#include "stream_buffer.h"
|
|
|
|
/* Test includes. */
|
|
#include "unity.h"
|
|
#include "unity_memory.h"
|
|
#include "CException.h"
|
|
|
|
/* Mock includes. */
|
|
#include "mock_task.h"
|
|
#include "mock_fake_assert.h"
|
|
#include "mock_fake_port.h"
|
|
|
|
/**
|
|
* @brief Sample size in bytes of the stream buffer used for test.
|
|
* The size is kept short enough so that the buffer can be allocated on stack.
|
|
*/
|
|
#define TEST_STREAM_BUFFER_SIZE ( 64U )
|
|
|
|
/**
|
|
* @brief Sample trigger level in bytes used for stream buffer tests.
|
|
* When a receiver task is blocked waiting for data, trigger level determines how much bytes should
|
|
* be available before which receiver task can be unblocked.
|
|
*/
|
|
#define TEST_STREAM_BUFFER_TRIGGER_LEVEL ( 32U )
|
|
|
|
/**
|
|
* @brief Maximum unsigned long value that can be passed as a stream buffer size so as to
|
|
* trigger an integer overflow.
|
|
*/
|
|
#define TEST_STREAM_BUFFER_MAX_UINT_SIZE ( ~( size_t ) ( 0UL ) )
|
|
|
|
/**
|
|
* @brief A value used to test setting and getting stream buffer number.
|
|
*/
|
|
#define TEST_STREAM_BUFFER_NUMBER ( 0xFFU )
|
|
|
|
/**
|
|
* @brief Wait ticks passed into from tests if the stream buffer is full while sending data or
|
|
* empty while receiving data.
|
|
*/
|
|
#define TEST_STREAM_BUFFER_WAIT_TICKS ( 1000U )
|
|
|
|
/**
|
|
* @brief CException code for when a configASSERT should be intercepted.
|
|
*/
|
|
#define configASSERT_E 0xAA101
|
|
|
|
/**
|
|
* @brief Expect a configASSERT from the function called.
|
|
* Break out of the called function when this occurs.
|
|
* @details Use this macro when the call passed in as a parameter is expected
|
|
* to cause invalid memory access.
|
|
*/
|
|
#define EXPECT_ASSERT_BREAK( call ) \
|
|
do \
|
|
{ \
|
|
shouldAbortOnAssertion = true; \
|
|
CEXCEPTION_T e = CEXCEPTION_NONE; \
|
|
Try \
|
|
{ \
|
|
call; \
|
|
TEST_FAIL(); \
|
|
} \
|
|
Catch( e ) \
|
|
{ \
|
|
TEST_ASSERT_EQUAL( configASSERT_E, e ); \
|
|
} \
|
|
} while( 0 )
|
|
|
|
|
|
/* ============================ GLOBAL VARIABLES =========================== */
|
|
|
|
/**
|
|
* @brief Global counter for the number of assertions in code.
|
|
*/
|
|
static int assertionFailed = 0;
|
|
|
|
/**
|
|
* @brief Global counter to keep track of how many times a sender task was woken up by a task receiving from the stream buffer.
|
|
*/
|
|
static int senderTaskWoken = 0;
|
|
|
|
/**
|
|
* @brief Global counter to keep track of how many times a receiver task was woken up by a task sending to the buffer.
|
|
*/
|
|
static int receiverTaskWoken = 0;
|
|
|
|
/**
|
|
* @brief Dummy sender task handle to which the stream buffer receive APIs will send notification.
|
|
*/
|
|
static TaskHandle_t senderTask = ( TaskHandle_t ) ( 0xAABBCCDD );
|
|
|
|
/**
|
|
* @brief Dummy receiver task handle to which the stream buffer send APIs will send notifications.
|
|
*/
|
|
static TaskHandle_t receiverTask = ( TaskHandle_t ) ( 0xABCDEEFF );
|
|
|
|
/**
|
|
* @brief Global Stream buffer handle used for tests.
|
|
*/
|
|
static StreamBufferHandle_t xStreamBuffer;
|
|
|
|
/**
|
|
* @brief Flag which denotes if test need to abort on assertion.
|
|
*/
|
|
static BaseType_t shouldAbortOnAssertion;
|
|
|
|
/**
|
|
* @brief Variable used to record the total dynamic size allocated in a test.
|
|
*/
|
|
static size_t dynamicMemoryAllocated = 0;
|
|
|
|
/* ========================== CALLBACK FUNCTIONS =========================== */
|
|
|
|
void * pvPortMalloc( size_t xSize )
|
|
{
|
|
dynamicMemoryAllocated += xSize;
|
|
return unity_malloc( xSize );
|
|
}
|
|
void vPortFree( void * pv )
|
|
{
|
|
return unity_free( pv );
|
|
}
|
|
|
|
static void vFakeAssertStub( bool x,
|
|
char * file,
|
|
int line,
|
|
int cmock_num_calls )
|
|
{
|
|
if( !x )
|
|
{
|
|
assertionFailed++;
|
|
|
|
if( shouldAbortOnAssertion == pdTRUE )
|
|
{
|
|
Throw( configASSERT_E );
|
|
}
|
|
}
|
|
}
|
|
|
|
static BaseType_t streamBufferReceiveCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
|
|
size_t dataReceived = 0;
|
|
|
|
/* Receive enough bytes (full size) from stream buffer to wake up sender task. */
|
|
dataReceived = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, 0 );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, dataReceived );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t streamBufferReceiveFromISRCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
|
|
size_t dataReceived = 0;
|
|
BaseType_t senderTaskWokenFromISR = pdFALSE;
|
|
|
|
/* Receive enough bytes (full size) from stream buffer to wake up sender task. */
|
|
dataReceived = xStreamBufferReceiveFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, &senderTaskWokenFromISR );
|
|
TEST_ASSERT_EQUAL( pdTRUE, senderTaskWokenFromISR );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, dataReceived );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t resetWhenBlockedCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
BaseType_t status;
|
|
|
|
/* Reset when the task is blocked on stream buffer, should fail and return pdFAIL. */
|
|
status = xStreamBufferReset( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( pdFAIL, status );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t sendCompletedFromISRCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
BaseType_t status = pdFALSE, highPriorityTaskWoken = pdFALSE;
|
|
|
|
/* Executing the send completed API from ISR should unblock a high priority task waiting to receive from stream buffer. */
|
|
status = xStreamBufferSendCompletedFromISR( xStreamBuffer, &highPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( pdTRUE, status );
|
|
TEST_ASSERT_EQUAL( pdTRUE, highPriorityTaskWoken );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t receiveCompletedFromISRCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
BaseType_t status = pdFALSE, highPriorityTaskWoken = pdFALSE;
|
|
|
|
/* Executing the receive completed API from ISR should unblock a high priority task waiting to send to stream buffer. */
|
|
status = xStreamBufferReceiveCompletedFromISR( xStreamBuffer, &highPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( pdTRUE, status );
|
|
TEST_ASSERT_EQUAL( pdTRUE, highPriorityTaskWoken );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t senderTaskNotificationCallback( TaskHandle_t xTaskToNotify,
|
|
UBaseType_t uxIndexToNotify,
|
|
uint32_t ulValue,
|
|
eNotifyAction eAction,
|
|
uint32_t * pulPreviousNotificationValue,
|
|
int cmock_num_calls )
|
|
{
|
|
TEST_ASSERT_EQUAL( senderTask, xTaskToNotify );
|
|
senderTaskWoken++;
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t senderTaskNotificationFromISRCallback( TaskHandle_t xTaskToNotify,
|
|
UBaseType_t uxIndexToNotify,
|
|
uint32_t ulValue,
|
|
eNotifyAction eAction,
|
|
uint32_t * pulPreviousNotificationValue,
|
|
BaseType_t * pxHigherPriorityTaskWoken,
|
|
int cmock_num_calls )
|
|
{
|
|
TEST_ASSERT_EQUAL( senderTask, xTaskToNotify );
|
|
senderTaskWoken++;
|
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
|
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t streamBufferSendCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_TRIGGER_LEVEL ] = { 0 };
|
|
size_t dataSent = 0;
|
|
|
|
/* Send enough (trigger level) bytes to stream buffer to wake up the receiver Task. */
|
|
dataSent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_TRIGGER_LEVEL, 0 );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL, dataSent );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t streamBufferSendFromISRCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_TRIGGER_LEVEL ] = { 0 };
|
|
size_t dataSent = 0;
|
|
BaseType_t receiverTaskWokenFromISR = pdFALSE;
|
|
|
|
/* Send enough (trigger level) bytes to stream buffer to wake up the receiver Task. */
|
|
dataSent = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_TRIGGER_LEVEL, &receiverTaskWokenFromISR );
|
|
TEST_ASSERT_EQUAL( pdTRUE, receiverTaskWokenFromISR );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL, dataSent );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t sendLessThanTriggerLevelBytesCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_TRIGGER_LEVEL ] = { 0 };
|
|
size_t dataSent = 0;
|
|
|
|
/* Sending less than trigger level bytes should not wake up the receiver Task. */
|
|
dataSent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_TRIGGER_LEVEL - 1, 0 );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL - 1, dataSent );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t sendLessThanTriggerLevelBytesFromISRCallback( UBaseType_t uxIndexToWaitOn,
|
|
uint32_t ulBitsToClearOnEntry,
|
|
uint32_t ulBitsToClearOnExit,
|
|
uint32_t * pulNotificationValue,
|
|
TickType_t xTicksToWait,
|
|
int cmock_num_calls )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_TRIGGER_LEVEL ] = { 0 };
|
|
size_t dataSent = 0;
|
|
BaseType_t receiverTaskWokenFromISR = pdFALSE;
|
|
|
|
/* Sending less than trigger level bytes should not wake up the receiver Task. */
|
|
dataSent = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_TRIGGER_LEVEL - 1, &receiverTaskWokenFromISR );
|
|
TEST_ASSERT_EQUAL( pdFALSE, receiverTaskWokenFromISR );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL - 1, dataSent );
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t receiverTaskNotificationFromISRCallback( TaskHandle_t xTaskToNotify,
|
|
UBaseType_t uxIndexToNotify,
|
|
uint32_t ulValue,
|
|
eNotifyAction eAction,
|
|
uint32_t * pulPreviousNotificationValue,
|
|
BaseType_t * pxHigherPriorityTaskWoken,
|
|
int cmock_num_calls )
|
|
{
|
|
TEST_ASSERT_EQUAL( receiverTask, xTaskToNotify );
|
|
receiverTaskWoken++;
|
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
|
|
|
return pdTRUE;
|
|
}
|
|
|
|
static BaseType_t receiverTaskNotificationCallback( TaskHandle_t xTaskToNotify,
|
|
UBaseType_t uxIndexToNotify,
|
|
uint32_t ulValue,
|
|
eNotifyAction eAction,
|
|
uint32_t * pulPreviousNotificationValue,
|
|
int cmock_num_calls )
|
|
{
|
|
TEST_ASSERT_EQUAL( receiverTask, xTaskToNotify );
|
|
receiverTaskWoken++;
|
|
return pdTRUE;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Unity fixtures
|
|
******************************************************************************/
|
|
void setUp( void )
|
|
{
|
|
assertionFailed = 0;
|
|
xStreamBuffer = NULL;
|
|
senderTaskWoken = 0;
|
|
receiverTaskWoken = 0;
|
|
shouldAbortOnAssertion = pdTRUE;
|
|
dynamicMemoryAllocated = 0;
|
|
|
|
|
|
mock_task_Init();
|
|
mock_fake_assert_Init();
|
|
mock_fake_port_Init();
|
|
|
|
vFakePortEnterCriticalSection_Ignore();
|
|
vFakePortExitCriticalSection_Ignore();
|
|
ulFakePortSetInterruptMaskFromISR_IgnoreAndReturn( 0U );
|
|
vFakePortClearInterruptMaskFromISR_Ignore();
|
|
vFakeAssert_StubWithCallback( vFakeAssertStub );
|
|
/* Track calls to malloc / free */
|
|
UnityMalloc_StartTest();
|
|
}
|
|
|
|
/*! called before each test case */
|
|
void tearDown( void )
|
|
{
|
|
TEST_ASSERT_EQUAL_MESSAGE( 0, assertionFailed, "Assertion check failed in code." );
|
|
UnityMalloc_EndTest();
|
|
mock_task_Verify();
|
|
mock_task_Destroy();
|
|
mock_fake_assert_Verify();
|
|
mock_fake_assert_Destroy();
|
|
mock_fake_port_Verify();
|
|
mock_fake_port_Destroy();
|
|
}
|
|
|
|
/*! called at the beginning of the whole suite */
|
|
void suiteSetUp()
|
|
{
|
|
}
|
|
|
|
/*! called at the end of the whole suite */
|
|
int suiteTearDown( int numFailures )
|
|
{
|
|
return numFailures;
|
|
}
|
|
|
|
static void validate_stream_buffer_init_state( StreamBufferHandle_t xStreamBuffer,
|
|
size_t bufferSize )
|
|
{
|
|
TEST_ASSERT_TRUE( xStreamBufferIsEmpty( xStreamBuffer ) );
|
|
TEST_ASSERT_FALSE( xStreamBufferIsFull( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( bufferSize, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( 0U, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( 0U, xStreamBufferNextMessageLengthBytes( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( 0, ucStreamBufferGetStreamBufferType( xStreamBuffer ) );
|
|
}
|
|
|
|
static void validate_and_clear_assertions( void )
|
|
{
|
|
TEST_ASSERT_EQUAL( 1, assertionFailed );
|
|
assertionFailed = 0;
|
|
}
|
|
|
|
/* ============================== Test Cases ============================== */
|
|
|
|
/**
|
|
* @brief Validates that stream buffer of sample size is created successfully.
|
|
*/
|
|
void test_xStreamBufferCreate_success( void )
|
|
{
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_EQUAL( NULL, xStreamBuffer );
|
|
validate_stream_buffer_init_state( xStreamBuffer, TEST_STREAM_BUFFER_SIZE );
|
|
|
|
/* Verify internal memory allocated is equal to size of the struct + buffer size + 1. */
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE + 1U + sizeof( StaticStreamBuffer_t ), dynamicMemoryAllocated );
|
|
|
|
/* Set a stream buffer number and get it. */
|
|
vStreamBufferSetStreamBufferNumber( xStreamBuffer, TEST_STREAM_BUFFER_NUMBER );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_NUMBER, uxStreamBufferGetStreamBufferNumber( xStreamBuffer ) );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* Returns NULL if there is an integer overflow in the buffer size.
|
|
*/
|
|
void test_xStreamBufferCreate_integer_overflow( void )
|
|
{
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_MAX_UINT_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_EQUAL( NULL, xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Returns NULL if internal memory allocation of the stream buffer fails.
|
|
*/
|
|
void test_xStreamBufferCreate_malloc_fail( void )
|
|
{
|
|
UnityMalloc_MakeMallocFailAfterCount( 0 );
|
|
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_EQUAL( NULL, xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Assertion fails if a zero buffer size is passed as the parameter.
|
|
*/
|
|
void test_xStreamBufferCreate_zero_buffer_size( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferCreate( 0, TEST_STREAM_BUFFER_TRIGGER_LEVEL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Assertion fails if trigger level is greater than the stream buffer size.
|
|
*/
|
|
void test_xStreamBufferCreate_invalid_trigger_level( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, ( TEST_STREAM_BUFFER_SIZE + 1 ) ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Assertion fails while trying to delete a null stream buffer.
|
|
*/
|
|
void test_xStreamBufferDelete_null_stream_buffer( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( vStreamBufferDelete( NULL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Validates stream buffer create using a static buffer is successful.
|
|
*/
|
|
void test_xStreamBufferCreateStatic_success( void )
|
|
{
|
|
StaticStreamBuffer_t streamBufferStruct;
|
|
|
|
/* The size of stream buffer array should be one greater than the required size of stream buffer. */
|
|
uint8_t streamBufferArray[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
|
|
|
|
xStreamBuffer = xStreamBufferCreateStatic( sizeof( streamBufferArray ), TEST_STREAM_BUFFER_TRIGGER_LEVEL, streamBufferArray, &streamBufferStruct );
|
|
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
validate_stream_buffer_init_state( xStreamBuffer, TEST_STREAM_BUFFER_SIZE );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates stream buffer static create fails if NULL array is passed.
|
|
*/
|
|
void test_xStreamBufferCreateStatic_null_array( void )
|
|
{
|
|
StaticStreamBuffer_t streamBufferStruct;
|
|
|
|
/* The size of stream buffer array should be one greater than the required size of stream buffer. */
|
|
uint8_t streamBufferArray[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
|
|
|
|
/* Tests should abort if assertion is enabled or return NULL. */
|
|
shouldAbortOnAssertion = pdFALSE;
|
|
|
|
/* Returns NULL if a NULL pointer is passed as the stream buffer storage area. */
|
|
xStreamBuffer = xStreamBufferCreateStatic( sizeof( streamBufferArray ), TEST_STREAM_BUFFER_TRIGGER_LEVEL, NULL, &streamBufferStruct );
|
|
TEST_ASSERT_NULL( xStreamBuffer );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Validates stream buffer static create fails if NULL struct is passed.
|
|
*/
|
|
void test_xStreamBufferCreateStatic_invalid_null_struct( void )
|
|
{
|
|
/* The size of stream buffer array should be one greater than the required size of stream buffer. */
|
|
uint8_t streamBufferArray[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
|
|
|
|
/* Tests should abort if assertion is enabled or return NULL. */
|
|
shouldAbortOnAssertion = pdFALSE;
|
|
|
|
/* Returns NULL if a NULL struct is passed as a parameter. */
|
|
xStreamBuffer = xStreamBufferCreateStatic( sizeof( streamBufferArray ), TEST_STREAM_BUFFER_TRIGGER_LEVEL, streamBufferArray, NULL );
|
|
TEST_ASSERT_NULL( xStreamBuffer );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Validates stream buffer static create fails on passing invalid trigger level
|
|
*/
|
|
void test_xStreamBufferCreateStatic_invalid_trigger_level( void )
|
|
{
|
|
StaticStreamBuffer_t streamBufferStruct;
|
|
/* The size of stream buffer array should be one greater than the required size of stream buffer. */
|
|
uint8_t streamBufferArray[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
|
|
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferCreateStatic( sizeof( streamBufferArray ), TEST_STREAM_BUFFER_SIZE + 2, streamBufferArray, &streamBufferStruct ) );
|
|
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Validates a task is able to send upto buffer space available without blocking.
|
|
*/
|
|
void test_xStreamBufferSend_success( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
|
|
size_t sent = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of the default test sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Sending bytes of size upto to available size should succeed without blocking. */
|
|
sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( pdFALSE, xStreamBufferIsEmpty( xStreamBuffer ) );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates that sending data more than stream buffer size will cap it to the size of stream buffer without blocking.
|
|
*/
|
|
void test_xStreamBufferSend_more_than_buffer_size( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
|
|
size_t sent = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of the default test sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Sending bytes more than stream buffer size caps its to the size of stream buffer. */
|
|
sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE + 1, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Sending zero bytes to stream buffer should return write nothing to the
|
|
* buffer and return 0.
|
|
*/
|
|
void test_xStreamBufferSend_zero_bytes( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of the default test sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
TEST_ASSERT_EQUAL( pdFALSE, xStreamBufferSend( xStreamBuffer, data, 0U, TEST_STREAM_BUFFER_WAIT_TICKS ) );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates cases where stream buffer has insufficient space to send the data and sender has to block.
|
|
*/
|
|
void test_xStreamBufferSend_blocking( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
|
|
size_t sent = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
|
|
xTaskGetCurrentTaskHandle_IgnoreAndReturn( senderTask );
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of test sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Sending upto size of stream buffer should not block. */
|
|
sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE - 1, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, sent );
|
|
TEST_ASSERT_EQUAL( 1, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/*
|
|
* Sending beyond the stream buffer size should make task wait for upto TEST_STREAM_BUFFER_WAIT_TICKS. After the timeout
|
|
* elapses, task should return with partial bytes sent.
|
|
*/
|
|
xTaskGenericNotifyWait_ExpectAndReturn( 0, 0, 0, NULL, TEST_STREAM_BUFFER_WAIT_TICKS, pdTRUE );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
|
|
sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 1, sent );
|
|
TEST_ASSERT_EQUAL( pdTRUE, xStreamBufferIsFull( xStreamBuffer ) );
|
|
|
|
/*
|
|
* A task trying to send to a stream buffer without any space available should block for upto TEST_STREAM_BUFFER_WAIT_TICKS.
|
|
* Sender task should be notified and woken up when bytes are consumed by a receiver task during the wait period.
|
|
*/
|
|
xTaskGenericNotifyWait_StubWithCallback( streamBufferReceiveCallback );
|
|
xTaskGenericNotify_StubWithCallback( senderTaskNotificationCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
|
|
sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( 1, senderTaskWoken );
|
|
|
|
/*
|
|
* A task trying to send to a stream buffer without any space available should block for upto TEST_STREAM_BUFFER_WAIT_TICKS.
|
|
* Sender task should be notified and woken up when bytes are consumed by an ISR during the wait period.
|
|
*/
|
|
xTaskGenericNotifyWait_StubWithCallback( streamBufferReceiveFromISRCallback );
|
|
xTaskGenericNotifyFromISR_StubWithCallback( senderTaskNotificationFromISRCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
|
|
sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( 2, senderTaskWoken );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates that stream buffer does not block if zero wait time is passed.
|
|
*/
|
|
void test_xStreamBufferSend_zero_wait_ticks( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
|
|
size_t dataSent = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Sending data of upto stream buffer size should not block. */
|
|
dataSent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, dataSent );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Sending data beyond stream buffer size but with zero wait ticks should not block and return zero bytes sent. */
|
|
dataSent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, 0 );
|
|
TEST_ASSERT_EQUAL( 0, dataSent );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates that a task is able to receive from a non empty stream buffer without blocking.
|
|
*/
|
|
void test_xStreamBufferReceive_success( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
uint8_t dataReceived[ TEST_STREAM_BUFFER_SIZE ] = { 0x00 };
|
|
size_t sentBytes = 0, receivedBytes = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Send TEST_STREAM_BUFFER_SIZE data to the stream buffer. */
|
|
sentBytes = xStreamBufferSend( xStreamBuffer, &data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sentBytes );
|
|
|
|
/* Receive the partial data from stream Buffer without blocking. */
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, &dataReceived, TEST_STREAM_BUFFER_SIZE - 1, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, receivedBytes );
|
|
TEST_ASSERT_EQUAL_HEX8_ARRAY( data, dataReceived, receivedBytes );
|
|
TEST_ASSERT_EQUAL( 1, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
/* Request for full TEST_STREAM_BUFFER_SIZE bytes, but only receive what's available without blocking. */
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, &dataReceived, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 1, receivedBytes );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates receiving from an empty stream buffer will block until at least trigger level bytes are
|
|
* sent to the buffer.
|
|
*/
|
|
void test_xStreamBufferReceive_blocking( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
size_t receivedBytes = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
|
|
xTaskGetCurrentTaskHandle_IgnoreAndReturn( receiverTask );
|
|
xTaskGenericNotify_StubWithCallback( receiverTaskNotificationCallback );
|
|
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
/*
|
|
* Receiving from an empty buffer causes the task to wait for TEST_STREAM_BUFFER_WAIT_TICKS period.
|
|
* After the timeout elapses, task returns with zero bytes received.
|
|
*/
|
|
xTaskGenericNotifyWait_ExpectAndReturn( 0, 0, 0, NULL, TEST_STREAM_BUFFER_WAIT_TICKS, pdTRUE );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 0, receivedBytes );
|
|
|
|
/*
|
|
* Sending at least trigger level bytes, should notify and wake up the receiver task.
|
|
*/
|
|
xTaskGenericNotifyWait_StubWithCallback( streamBufferSendCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL, receivedBytes );
|
|
TEST_ASSERT_EQUAL( 1, receiverTaskWoken );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
/*
|
|
* Sending at least trigger level bytes from ISR, should notify and wake up the receiver task.
|
|
*/
|
|
xTaskGenericNotifyWait_StubWithCallback( streamBufferSendFromISRCallback );
|
|
xTaskGenericNotifyFromISR_StubWithCallback( receiverTaskNotificationFromISRCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL, receivedBytes );
|
|
TEST_ASSERT_EQUAL( 2, receiverTaskWoken );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
|
|
/* Sending less than trigger level bytes should not wake up the task. */
|
|
xTaskGenericNotifyWait_StubWithCallback( sendLessThanTriggerLevelBytesCallback );
|
|
xTaskGenericNotifyFromISR_StubWithCallback( receiverTaskNotificationFromISRCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 2, receiverTaskWoken );
|
|
|
|
/* Sending less than trigger level bytes from ISR should not wake up the task. */
|
|
xTaskGenericNotifyWait_StubWithCallback( sendLessThanTriggerLevelBytesFromISRCallback );
|
|
xTaskGenericNotifyFromISR_StubWithCallback( receiverTaskNotificationFromISRCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 2, receiverTaskWoken );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates that receiver task does not block if zero wait ticks are passed.
|
|
*/
|
|
void test_xStreamBufferReceive_zero_wait_ticks( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
size_t receivedBytes = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Task does not block on an empty stream buffer if zero wait ticks are passed. */
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, 0 );
|
|
TEST_ASSERT_EQUAL( 0, receivedBytes );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates that an interrupt service routine is able to read data from stream
|
|
* buffer without blocking.
|
|
*/
|
|
void test_xStreamBufferReceiveFromISR_success( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
uint8_t dataReceived[ TEST_STREAM_BUFFER_SIZE ] = { 0x00 };
|
|
size_t receivedBytes = 0, sentBytes = 0;
|
|
BaseType_t xHighPriorityTaskWoken = pdFALSE;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Send data to fill the stream buffer to maximum capacity. */
|
|
sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sentBytes );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
/* Receive partial data from stream buffer without blocking. */
|
|
receivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, &dataReceived, ( TEST_STREAM_BUFFER_SIZE - 1U ), &xHighPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( ( TEST_STREAM_BUFFER_SIZE - 1U ), receivedBytes );
|
|
TEST_ASSERT_EQUAL_HEX8_ARRAY( data, dataReceived, receivedBytes );
|
|
TEST_ASSERT_EQUAL( pdFALSE, xHighPriorityTaskWoken );
|
|
|
|
/* Try to receive full capacity from stream buffer but only remaining data is received. */
|
|
receivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, &dataReceived, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( 1U, receivedBytes );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Assertion fails if a null stream buffer is passed.
|
|
*/
|
|
void test_xStreamBufferReceiveFromISR_null_stream_buffer( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
BaseType_t xHighPriorityTaskWoken = pdFALSE;
|
|
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferReceiveFromISR( NULL, data, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken ) );
|
|
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Assertion fails if a null message is passed.
|
|
*/
|
|
void test_xStreamBufferReceiveFromISR_null_buffer( void )
|
|
{
|
|
BaseType_t xHighPriorityTaskWoken = pdFALSE;
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferReceiveFromISR( xStreamBuffer, NULL, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken ) );
|
|
|
|
validate_and_clear_assertions();
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates that an interrupt service routine is able to send data upto the size of stream buffer without blocking.
|
|
*/
|
|
void test_xStreamBufferSendFromISR_success( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
size_t sentBytes = 0;
|
|
BaseType_t xHighPriorityTaskWoken = pdFALSE;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Send data to an empty buffer should succeed without blocking. */
|
|
sentBytes = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE - 1U, &xHighPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1U, sentBytes );
|
|
TEST_ASSERT_EQUAL( 1U, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( pdFALSE, xHighPriorityTaskWoken );
|
|
|
|
/* Send full capacity from ISR again should send partial bytes without blocking. */
|
|
sentBytes = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( 1U, sentBytes );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( pdFALSE, xHighPriorityTaskWoken );
|
|
|
|
/* Send to full stream buffer should return 0 bytes sent without blocking. */
|
|
sentBytes = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( 0U, sentBytes );
|
|
TEST_ASSERT_EQUAL( pdFALSE, xHighPriorityTaskWoken );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Assertion fails if a null stream buffer is passed.
|
|
*/
|
|
void test_xStreamBufferSendFromISR_null_stream_buffer( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
BaseType_t xHighPriorityTaskWoken = pdFALSE;
|
|
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSendFromISR( NULL, data, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken ) );
|
|
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Assertion fails if a null message is passed.
|
|
*/
|
|
void test_xStreamBufferSendFromISR_null_message( void )
|
|
{
|
|
BaseType_t xHighPriorityTaskWoken = pdFALSE;
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSendFromISR( xStreamBuffer, NULL, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken ) );
|
|
|
|
validate_and_clear_assertions();
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates user is able to reset the stream buffer back to empty state.
|
|
*/
|
|
void test_xStreamBufferReset_success( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
|
|
size_t dataSent = 0;
|
|
BaseType_t status = pdFALSE;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of the default test sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
|
|
/* Validate stream buffer is empty initially. */
|
|
validate_stream_buffer_init_state( xStreamBuffer, TEST_STREAM_BUFFER_SIZE );
|
|
|
|
/* Send full capacity to stream buffer. */
|
|
dataSent = xStreamBufferSend( xStreamBuffer, data, sizeof( data ), TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, dataSent );
|
|
|
|
/* Verify that all bytes are available. */
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
/* Reset the stream buffer back to empty state. */
|
|
status = xStreamBufferReset( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( pdTRUE, status );
|
|
|
|
/* Validate that stream buffer is empty. */
|
|
validate_stream_buffer_init_state( xStreamBuffer, TEST_STREAM_BUFFER_SIZE );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Resetting a null stream buffer should fail assertion.
|
|
*/
|
|
void test_xStreamBufferReset_null_stream_buffer( void )
|
|
{
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferReset( NULL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Validates that stream buffer reset fails if a sender or receiver task is blocked on it.
|
|
*/
|
|
void test_xStreamBufferReset_while_blocked( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
size_t sentBytes = 0, receivedBytes = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
|
|
xTaskGetCurrentTaskHandle_IgnoreAndReturn( senderTask );
|
|
xTaskGenericNotifyWait_StubWithCallback( resetWhenBlockedCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/*
|
|
* Perform a blocking operation to receive from an empty stream buffer. Reset stream buffer within receiver task notify
|
|
* wait callback should fail.
|
|
*/
|
|
receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 0, receivedBytes );
|
|
|
|
/*
|
|
* Send full size data to stream buffer.
|
|
*/
|
|
sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sentBytes );
|
|
TEST_ASSERT_EQUAL( pdTRUE, xStreamBufferIsFull( xStreamBuffer ) );
|
|
|
|
/*
|
|
* Sending data to full stream buffer causes task to be blocked. Reset stream buffer within sender task notify
|
|
* wait callback should fail.
|
|
*/
|
|
sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 0, sentBytes );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates that a receiver task is able to receive data after lowering the stream buffer trigger level.
|
|
*/
|
|
void test_xStreamBufferSetTrigerLevel_success( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
BaseType_t status;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
|
|
xTaskGetCurrentTaskHandle_IgnoreAndReturn( receiverTask );
|
|
xTaskGenericNotify_StubWithCallback( receiverTaskNotificationCallback );
|
|
xTaskGenericNotifyWait_StubWithCallback( streamBufferSendCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create stream buffer with trigger level equal to maximum stream buffer size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_SIZE );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
|
|
/* Set the trigger level to TEST_STREAM_BUFFER_TRIGGER_LEVEL. */
|
|
status = xStreamBufferSetTriggerLevel( xStreamBuffer, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_EQUAL( pdTRUE, status );
|
|
|
|
/*
|
|
* Receive data from empty stream buffer, with trigger level bytes send from the callback. This should unblock
|
|
* the task.
|
|
*/
|
|
( void ) xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 1, receiverTaskWoken );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validate setting trigger level with invalid parameters fails.
|
|
*/
|
|
void test_xStreamBufferSetTrigerLevel_larger_than_buffer_size( void )
|
|
{
|
|
BaseType_t status;
|
|
|
|
/* Create stream buffer. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
|
|
/* Set the trigger level to ( TEST_STREAM_BUFFER_SIZE + 1) should fail. */
|
|
status = xStreamBufferSetTriggerLevel( xStreamBuffer, ( TEST_STREAM_BUFFER_SIZE + 1 ) );
|
|
TEST_ASSERT_EQUAL( pdFALSE, status );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Set the trigger level to 0 should pass but internally set trigger level to 1.
|
|
*/
|
|
void test_xStreamBufferSetTrigerLevel_zero( void )
|
|
{
|
|
BaseType_t status;
|
|
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
|
|
status = xStreamBufferSetTriggerLevel( xStreamBuffer, 0 );
|
|
TEST_ASSERT_EQUAL( pdTRUE, status );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Setting trigger level for a null stream buffer should fail assertion.
|
|
*/
|
|
void test_xStreamBufferSetTriggerLevel_null_stream_buffer( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSetTriggerLevel( NULL, TEST_STREAM_BUFFER_TRIGGER_LEVEL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Checking bytes available for a null stream buffer should fail assertion.
|
|
*/
|
|
void test_xStreamBufferBytesAvailable_null_stream_buffer( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferBytesAvailable( NULL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Checking if stream buffer is full for a null stream buffer should fail assertion.
|
|
*/
|
|
void test_xStreamBufferIsFull_null_stream_buffer( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferIsFull( NULL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Checking if stream buffer is empty for a null stream buffer should fail assertion.
|
|
*/
|
|
void test_xStreamBufferIsEmpty_null_stream_buffer( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferIsEmpty( NULL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Checking buffer size for a null stream buffer should fail assertion.
|
|
*/
|
|
void test_xStreamBufferSpacesAvailable_null_stream_buffer( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSpacesAvailable( NULL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Checking Next message length available for a null stream buffer fails
|
|
* assertion.
|
|
*/
|
|
void test_xStreamBufferNextMessageLengthBytes_null_stream_buffer( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferNextMessageLengthBytes( NULL ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Validates xStreamBufferSendCompletedFromISR function unblocks a receive task.
|
|
*/
|
|
void test_xStreamBufferSendCompletedFromISR_success( void )
|
|
{
|
|
BaseType_t status = pdFALSE;
|
|
BaseType_t highPriorityTaskWoken = pdFALSE;
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ];
|
|
size_t receiveBytes = 0;
|
|
|
|
/* Create a stream buffer of the default test sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
|
|
/* Send completed from ISR without receiver task waiting. */
|
|
status = xStreamBufferSendCompletedFromISR( xStreamBuffer, &highPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( pdFALSE, status );
|
|
TEST_ASSERT_EQUAL( pdFALSE, highPriorityTaskWoken );
|
|
|
|
/* Send completed from ISR with receiver task waiting. */
|
|
vTaskSetTimeOutState_Ignore();
|
|
xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
|
|
xTaskGetCurrentTaskHandle_IgnoreAndReturn( receiverTask );
|
|
xTaskGenericNotifyWait_StubWithCallback( sendCompletedFromISRCallback );
|
|
xTaskGenericNotifyFromISR_StubWithCallback( receiverTaskNotificationFromISRCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
receiveBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 0, receiveBytes );
|
|
TEST_ASSERT_EQUAL( 1, receiverTaskWoken );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates xStreamBufferSendCompletedFromISR fails assertion if a null stream buffer is passed.
|
|
*/
|
|
void test_xStreamBufferSendCompletedFromISR_null_stream_buffer( void )
|
|
{
|
|
BaseType_t highPriorityTaskWoken = pdFALSE;
|
|
|
|
/* Send completed from ISR without receiver task waiting. */
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSendCompletedFromISR( NULL, &highPriorityTaskWoken ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Validates xStreamBufferReceiveCompletedFromISR unblocks a sender task.
|
|
*/
|
|
void test_xStreamBufferReceiveCompletedFromISR_success( void )
|
|
{
|
|
BaseType_t status = pdFALSE;
|
|
BaseType_t highPriorityTaskWoken = pdFALSE;
|
|
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
size_t sentBytes = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of the default test sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
|
|
/* Receive completed from ISR without a sender task waiting. */
|
|
status = xStreamBufferReceiveCompletedFromISR( xStreamBuffer, &highPriorityTaskWoken );
|
|
TEST_ASSERT_EQUAL( pdFALSE, status );
|
|
TEST_ASSERT_EQUAL( pdFALSE, highPriorityTaskWoken );
|
|
|
|
|
|
/* Send full capacity to a stream buffer so that sender task blocks. */
|
|
sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sentBytes );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
|
|
/* Receive completed from ISR when a sender task is waiting. */
|
|
xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
|
|
xTaskGetCurrentTaskHandle_IgnoreAndReturn( senderTask );
|
|
xTaskGenericNotifyWait_StubWithCallback( receiveCompletedFromISRCallback );
|
|
xTaskGenericNotifyFromISR_StubWithCallback( senderTaskNotificationFromISRCallback );
|
|
xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
|
|
sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( 0, sentBytes );
|
|
TEST_ASSERT_EQUAL( 1, senderTaskWoken );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|
|
|
|
/**
|
|
* @brief Validates xStreamBufferReceiveCompletedFromISR fails assertion if a null stream buffer is passed.
|
|
*/
|
|
void test_xStreamBufferReceiveCompletedFromISR_null_stream_buffer( void )
|
|
{
|
|
BaseType_t highPriorityTaskWoken = pdFALSE;
|
|
|
|
/* Send completed from ISR without receiver task waiting. */
|
|
EXPECT_ASSERT_BREAK( ( void ) xStreamBufferReceiveCompletedFromISR( NULL, &highPriorityTaskWoken ) );
|
|
validate_and_clear_assertions();
|
|
}
|
|
|
|
/**
|
|
* @brief Validates scenario where stream buffer head and tail pointer wraps over.
|
|
*/
|
|
void test_xStreamBufferSend_WrapOver( void )
|
|
{
|
|
uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
|
|
size_t sent = 0, received = 0;
|
|
|
|
vTaskSetTimeOutState_Ignore();
|
|
vTaskSuspendAll_Ignore();
|
|
xTaskResumeAll_IgnoreAndReturn( pdTRUE );
|
|
|
|
/* Create a stream buffer of the default test sample size. */
|
|
xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
|
|
TEST_ASSERT_NOT_NULL( xStreamBuffer );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Sending bytes upto max stream buffer size. */
|
|
sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Read upto max buffer size - 1 */
|
|
received = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE - 1, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, received );
|
|
TEST_ASSERT_EQUAL( 1, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
/* Send upto max buffer size - 1 so that head wraps over. */
|
|
sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE - 1, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, sent );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( 0U, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
|
|
/* Read all bytes and verify that tail wraps over as well. */
|
|
received = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, received );
|
|
TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
|
|
TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
|
|
|
|
vStreamBufferDelete( xStreamBuffer );
|
|
}
|