2021-11-30 14:51:24 +01:00

589 lines
19 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 mutex_utest.c */
#include "../queue_utest_common.h"
/* Queue includes */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "semphr.h"
#include "mock_fake_port.h"
/* ============================ GLOBAL VARIABLES =========================== */
static SemaphoreHandle_t xSemaphoreHandleStatic = NULL;
/* ========================== CALLBACK FUNCTIONS =========================== */
/* ============================= Unity Fixtures ============================= */
void setUp( void )
{
commonSetUp();
}
void tearDown( void )
{
commonTearDown();
}
void suiteSetUp()
{
commonSuiteSetUp();
}
int suiteTearDown( int numFailures )
{
return commonSuiteTearDown( numFailures );
}
/* ========================== Helper functions =========================== */
/* ========================== Test Cases =========================== */
/**
* @brief Test xSemaphoreCreateMutex where the call to malloc fails
* @coverage xQueueCreateMutex
*/
void test_macro_xSemaphoreCreateMutex_malloc_fail( void )
{
UnityMalloc_MakeMallocFailAfterCount( 0 );
SemaphoreHandle_t xSemaphore = INVALID_PTR;
xSemaphore = xSemaphoreCreateMutex();
/* validate returned semaphore handle */
TEST_ASSERT_EQUAL( NULL, xSemaphore );
}
/**
* @brief Test xSemaphoreCreateMutex
* @details Create a mutex using xSemaphoreCreateMutex
* @coverage xQueueCreateMutex
*/
void test_macro_xSemaphoreCreateMutex_success( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
/* validate returned semaphore handle */
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreCreateMutexStatic with a null buffer
* @coverage xQueueCreateMutexStatic
*/
void test_macro_xSemaphoreCreateMutexStatic_nullptr( void )
{
SemaphoreHandle_t xSemaphore = INVALID_PTR;
/* Expect that xQueueCreate will assert due to the NULL buffer */
fakeAssertExpectFail();
xSemaphore = xSemaphoreCreateMutexStatic( NULL );
/* Check that configASSERT was called twice */
fakeAssertVerifyNumAssertsAndClear( 2 );
TEST_ASSERT_EQUAL( NULL, xSemaphore );
TEST_ASSERT_EQUAL( 0, getLastMallocSize() );
}
/**
* @brief Test xSemaphoreCreateMutexStatic with a valid buffer.
* @details Create a semaphore using xSemaphoreCreateMutexStatic
* @coverage xQueueCreateMutexStatic
*/
void test_macro_xSemaphoreCreateMutexStatic_success( void )
{
SemaphoreHandle_t xSemaphore = NULL;
StaticSemaphore_t xSemaphoreBuffer;
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
xSemaphore = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer );
/* Check that no call to malloc occurred */
TEST_ASSERT_EQUAL( 0, getLastMallocSize() );
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreTake with a Mutex
* @details Create a mutex using xSemaphoreCreateMutex
* and verify that an immediate call to xSemaphoreTake succeeds.
* @coverage xQueueSemaphoreTake
*/
void test_macro_xSemaphoreTake_success( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
/* validate returned semaphore handle */
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
pvTaskIncrementMutexHeldCount_IgnoreAndReturn( NULL );
/* Verify that an immediate xSemaphoreTake operation succeeds */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGive with xSemaphoreCreateMutex
* @details Create a mutex using xSemaphoreCreateMutex
* and verify that an immediate call to xSemaphoreGive fails.
* @coverage xQueueGenericSend
*/
void test_macro_xSemaphoreGive_fail( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
/* validate returned semaphore handle */
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
/* Verify that an immediate xSemaphoreGive operation fails */
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreGive( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGive and xSemaphoreTake with xSemaphoreCreateMutex
* @details Create a mutex using xSemaphoreCreateMutex
* and verify that an immediate call to xSemaphoreGive succeeds and a subsequent
* call to xSemaphoreTake succeeds.
* @coverage xQueueGenericSend xQueueSemaphoreTake
*/
void test_macro_xSemaphoreGive_xSemaphoreTake_success( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
/* validate returned semaphore handle */
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
pvTaskIncrementMutexHeldCount_ExpectAndReturn( 0 );
/* Verify that an immediate xSemaphoreTake operation succeeds */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
/* Verify that a subsequent xSemaphoreGive operation succeeds */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGive( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGive multiple times on a Mutex.
* @details Create a mutex using xSemaphoreCreateMutex
* and verify that an immediate call to xSemaphoreGive succeeds and a subsequent
* call to xSemaphoreGive fails.
* @coverage xQueueGenericSend
*/
void test_macro_xSemaphoreGive_multiple_Mutex_fail( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
/* validate returned semaphore handle */
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
pvTaskIncrementMutexHeldCount_ExpectAndReturn( 0 );
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
xSemaphoreTake( xSemaphore, 0 );
/* Verify that the first xSemaphoreGive call succeeds */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGive( xSemaphore ) );
/* Verify that a second xSemaphoreGive call fails */
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreGive( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreTake multiple times on a Mutex.
* @details Create a Mutex using xSemaphoreCreateMutex,
* verify that an immediate call to xSemaphoreTake succeeds, a subsequent
* call to xSemaphoreGive succeds, but a second call to xSemaphoreGive fails.
* @coverage xQueueSemaphoreTake
*/
void test_macro_xSemaphoreTake_multiple_Mutex_fail( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
/* validate returned semaphore handle */
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
pvTaskIncrementMutexHeldCount_ExpectAndReturn( 0 );
/* Verify that an immediate xSemaphoreTake operation succeeds */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
/* Verify that the second xSemaphoreTake operation fails */
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, 0 ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test uxSemaphoreGetCount with a Mutex
* @details Create a Mutex using xSemaphoreCreateMutex.
* validate the return value of uxSemaphoreGetCount(),
* call xSemaphoreTake() and validate the return value of uxSemaphoreGetCount()
* @coverage uxQueueMessagesWaiting
*/
void test_macro_uxSemaphoreGetCount_Mutex( void )
{
SemaphoreHandle_t xSemaphore = NULL;
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
pvTaskIncrementMutexHeldCount_ExpectAndReturn( 0 );
xSemaphore = xSemaphoreCreateMutex();
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
xSemaphoreTake( xSemaphore, 0 );
TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGetMutexHolder with an invalid (null) SemaphoreHandle_t
* @coverage xQueueGetMutexHolder
*/
void test_macro_xSemaphoreGetMutexHolder_NULL( void )
{
/* This previously caused a segfault, but I patched queue.c */
EXPECT_ASSERT_BREAK( xSemaphoreGetMutexHolder( NULL ) );
}
/**
* @brief Test xSemaphoreGetMutexHolder with a handle of a binary semaphore
* @details Verify that xSemaphoreGetMutexHolder returns NULL when given a handle to a binary semaphore rather than a mutex.
* @coverage xQueueGetMutexHolder
*/
void test_macro_xSemaphoreGetMutexHolder_binary_semaphore( void )
{
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
TEST_ASSERT_EQUAL( NULL, xSemaphoreGetMutexHolder( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGetMutexHolder with a valid SemaphoreHandle_t
* @coverage xQueueGetMutexHolder
*/
void test_macro_xSemaphoreGetMutexHolder_Mutex( void )
{
TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
TEST_ASSERT_EQUAL( xMutexHolder, xSemaphoreGetMutexHolder( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGetMutexHolderFromISR with an invalid (null) SemaphoreHandle_t
* @coverage xQueueGetMutexHolderFromISR
*/
void test_macro_xSemaphoreGetMutexHolderFromISR_Mutex_NULL( void )
{
EXPECT_ASSERT_BREAK( xSemaphoreGetMutexHolderFromISR( NULL ) );
}
/**
* @brief Test xSemaphoreGetMutexHolderFromISR with a handle of a binary semaphore
* @details Verify that xSemaphoreGetMutexHolderFromISR returns NULL when given a handle to a binary semaphore rather than a mutex.
* @coverage xQueueGetMutexHolderFromISR
*/
void test_macro_xSemaphoreGetMutexHolderFromISR_binary_semaphore( void )
{
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
TEST_ASSERT_EQUAL( NULL, xSemaphoreGetMutexHolderFromISR( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGetMutexHolderFromISR with a valid SemaphoreHandle_t
* @coverage xQueueGetMutexHolderFromISR
*/
void test_macro_xSemaphoreGetMutexHolderFromISR_Mutex( void )
{
TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
TEST_ASSERT_EQUAL( xMutexHolder, xSemaphoreGetMutexHolderFromISR( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGiveFromISR with a Mutex that has an owner.
* @details Verify that xSemaphoreGiveFromISR configASSERTs when an owned mutex is given as the xSemaphore argument.
* @coverage xQueueGiveFromISR
*/
void test_macro_xSemaphoreGiveFromISR_mutex_owned( void )
{
TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
/* Setup mocks for xSemaphoretake */
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
vFakePortAssertIfInterruptPriorityInvalid_Expect();
xSemaphoreTake( xSemaphore, 0 );
/* Expect that xSemaphoreGiveFromISR will assert due to the mutex usage */
fakeAssertExpectFail();
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGiveFromISR( xSemaphore, NULL ) );
TEST_ASSERT_EQUAL( true, fakeAssertGetFlagAndClear() );
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreGiveFromISR with a Mutex that has a NULL owner.
* @details Verify that xSemaphoreGiveFromISR does not configASSERT when a mutex with a NULL owner is given in the xSemaphore argument.
* @coverage xQueueGiveFromISR
*/
void test_macro_xSemaphoreGiveFromISR_mutex_not_owned( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
/* Setup mocks for xSemaphoretake */
pvTaskIncrementMutexHeldCount_ExpectAndReturn( NULL );
vFakePortAssertIfInterruptPriorityInvalid_Expect();
xSemaphoreTake( xSemaphore, 0 );
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGiveFromISR( xSemaphore, NULL ) );
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreTake in blocking mode on an already owned mutex.
* @details Test xSemaphoreTake on a mutex owned by another task where the owning task has lower priority.
* @coverage xQueueSemaphoreTake prvGetDisinheritPriorityAfterTimeout
*/
void test_macro_xSemaphoreTake_blocking_mutex_inherit_timeout( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
BaseType_t xFakeMutexHolder = getNextMonotonicTestValue();
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */
pvTaskIncrementMutexHeldCount_ExpectAndReturn( ( void * ) xFakeMutexHolder );
/* Take the mutex */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
for( int i = 0; i < TICKS_TO_WAIT; i++ )
{
/* Return pdTRUE to signify that priority inheritance occurred */
xTaskPriorityInherit_ExpectAndReturn( ( void * ) xFakeMutexHolder, pdTRUE );
}
vTaskPriorityDisinheritAfterTimeout_Expect( ( void * ) ( BaseType_t ) getLastMonotonicTestValue(), tskIDLE_PRIORITY );
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, TICKS_TO_WAIT ) );
TEST_ASSERT_EQUAL( TICKS_TO_WAIT, td_task_getYieldCount() );
TEST_ASSERT_EQUAL( TICKS_TO_WAIT, td_task_getCount_vPortYieldWithinAPI() );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Test xSemaphoreTake in blocking mode on an already owned mutex.
* @details Test xSemaphoreTake on a mutex owned by another task with another high priority task waiting and the current task timing out.
* @coverage xQueueSemaphoreTake prvGetDisinheritPriorityAfterTimeout
*/
void test_macro_xSemaphoreTake_blocking_mutex_inherit_timeout_high_prio_waiting( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
TaskHandle_t xFakeMutexHolder = ( TaskHandle_t ) ( ( uint64_t ) 0 + getNextMonotonicTestValue() );
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xFakeMutexHolder );
/* Take the mutex */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
/* Insert an item into the event list */
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
td_task_addFakeTaskWaitingToReceiveFromQueue( xSemaphore );
for( int i = 0; i < TICKS_TO_WAIT; i++ )
{
/* Return pdTRUE to signify that priority inheritance occurred */
xTaskPriorityInherit_ExpectAndReturn( xFakeMutexHolder, pdTRUE );
}
vTaskPriorityDisinheritAfterTimeout_Expect( xFakeMutexHolder, DEFAULT_PRIORITY + 1 );
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, TICKS_TO_WAIT ) );
TEST_ASSERT_EQUAL( TICKS_TO_WAIT + 1, td_task_getYieldCount() );
TEST_ASSERT_EQUAL( TICKS_TO_WAIT + 1, td_task_getCount_YieldFromTaskResumeAll() );
vSemaphoreDelete( xSemaphore );
}
/**
* @brief Callback for test_macro_xSemaphoreTake_blocking_mutex_inherit_disinherit
*/
static BaseType_t xSemaphoreTake_blocking_xTaskResumeAllStub( int cmock_num_calls )
{
BaseType_t xReturnValue = td_task_xTaskResumeAllStub( cmock_num_calls );
if( cmock_num_calls == NUM_CALLS_TO_INTERCEPT )
{
TEST_ASSERT_TRUE( xSemaphoreGive( xSemaphoreHandleStatic ) );
}
return xReturnValue;
}
/**
* @brief Test priority inheritance during a successful blocking call to xSemaphoreTake
* @coverage xQueueSemaphoreTake
*/
void test_macro_xSemaphoreTake_blocking_mutex_inherit_disinherit( void )
{
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
xSemaphoreHandleStatic = xSemaphore;
TaskHandle_t xFakeMutexHolder = ( TaskHandle_t ) ( ( uint64_t ) 0 + getNextMonotonicTestValue() );
xTaskResumeAll_Stub( &xSemaphoreTake_blocking_xTaskResumeAllStub );
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xFakeMutexHolder );
/* Take the mutex */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
for( int i = 0; i < NUM_CALLS_TO_INTERCEPT + 1; i++ )
{
/* Return pdTRUE to signify that priority inheritance occurred */
xTaskPriorityInherit_ExpectAndReturn( xFakeMutexHolder, pdTRUE );
}
xTaskPriorityDisinherit_ExpectAndReturn( xFakeMutexHolder, pdTRUE );
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xFakeMutexHolder );
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, TICKS_TO_WAIT ) );
TEST_ASSERT_EQUAL( NUM_CALLS_TO_INTERCEPT + 2, td_task_getYieldCount() );
TEST_ASSERT_EQUAL( NUM_CALLS_TO_INTERCEPT + 2, td_task_getCount_vPortYieldWithinAPI() );
vSemaphoreDelete( xSemaphore );
}