Add unit test for FreeRTOS SMP (#1047)

* Add unit test for FreeRTOS SMP to verify SMP scheduler logic in tasks.c which is enclosed by `configNUMBER_OF_CORES > 1`.

---------

Co-authored-by: Joshua Zarr <joshzarr@amazon.com>
Co-authored-by: Anubhav Rawal <rawalexe@amazon.com>
Co-authored-by: Alfred Gedeon <alfred2g@hotmail.com>
Co-authored-by: Adam Scislowicz <adamds@amazon.com>
Co-authored-by: jannusi <121577776+jannusi@users.noreply.github.com>
Co-authored-by: Krishna Vamsi Tallapaneni <124737189+vamsitas@users.noreply.github.com>
Co-authored-by: Kody Stribrny <kstribrn@amazon.com>
Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com>
This commit is contained in:
chinglee-iot 2023-10-31 08:34:59 +08:00 committed by GitHub
parent 1114e8f39b
commit e7d39763db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
64 changed files with 25145 additions and 71 deletions

View file

@ -5012,6 +5012,7 @@ VRRSTEN
VRRSTS VRRSTS
VSDB VSDB
VSYNC VSYNC
VTASKLIST
VTIR VTIR
VTOFFR VTOFFR
VTOR VTOR
@ -5340,6 +5341,7 @@ coremqtt
cortexa cortexa
coverity coverity
covfs covfs
covg
cpas cpas
cpbs cpbs
cpcdis cpcdis
@ -5402,6 +5404,7 @@ enetrg
epage epage
epdisc epdisc
eqcfg eqcfg
equalto
equidistribution equidistribution
eret eret
ethernetif ethernetif
@ -5581,6 +5584,7 @@ lpstart
lpthread lpthread
lptr lptr
lsls lsls
lteq
ltorg ltorg
ltry ltry
lums lums
@ -6049,10 +6053,14 @@ utilising
utrhf utrhf
utrhfgdghfg utrhfgdghfg
ux ux
uxdeletedtaskwaiting
uxindex uxindex
uxpriority
uxsource uxsource
uxtab uxtab
uxtasknumber
uxtb uxtb
uxtopreadypriority
vactive vactive
vblank vblank
vcmp vcmp
@ -6120,6 +6128,7 @@ xfindobjectwithlabelandclass
xfscompat xfscompat
xgetslotlist xgetslotlist
xheader xheader
xidx
xinitializepkcs xinitializepkcs
xlarge xlarge
xlength xlength

@ -1 +1 @@
Subproject commit 4ada1d7d5e853f0f9415dc99cafae72eaf571b59 Subproject commit 5281427a9942bf12d35240d388fcfe60fa7dd682

View file

@ -14,6 +14,7 @@ UNITS += queue
UNITS += stream_buffer UNITS += stream_buffer
UNITS += message_buffer UNITS += message_buffer
UNITS += event_groups UNITS += event_groups
UNITS += smp
.PHONY: makefile.in .PHONY: makefile.in

View file

@ -0,0 +1,32 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FAKE_INFINITE_LOOP_H
#define FAKE_INFINITE_LOOP_H
int vFakeInfiniteLoop( void );
#endif /* FAKE_INFINITE_LOOP_H */

View file

@ -31,7 +31,8 @@ void vFakePortYield( void );
void vFakePortYieldFromISR( void ); void vFakePortYieldFromISR( void );
void vFakePortYieldWithinAPI( void ); void vFakePortYieldWithinAPI( void );
void vFakePortDisableInterrupts( void ); void vFakePortRestoreInterrupts( UBaseType_t );
uint32_t vFakePortDisableInterrupts( void );
void vFakePortEnableInterrupts( void ); void vFakePortEnableInterrupts( void );
void vFakePortClearInterruptMaskFromISR( UBaseType_t uxNewMaskValue ); void vFakePortClearInterruptMaskFromISR( UBaseType_t uxNewMaskValue );
void vFakePortClearInterruptMask( UBaseType_t uxNewMaskValue ); void vFakePortClearInterruptMask( UBaseType_t uxNewMaskValue );
@ -44,7 +45,25 @@ void vFakePortEnterCriticalSection( void );
void vFakePortExitCriticalSection( void ); void vFakePortExitCriticalSection( void );
void vPortCurrentTaskDying( void * pxTaskToDelete, void vPortCurrentTaskDying( void * pxTaskToDelete,
volatile BaseType_t * pxPendYield ); volatile BaseType_t * pxPendYield );
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
void portSetupTCB_CB( void * tcb ); void portSetupTCB_CB( void * tcb );
void vFakePortGetISRLock( void );
void vFakePortReleaseISRLock( void );
void vFakePortGetTaskLock( void );
void vFakePortReleaseTaskLock( void );
void vFakePortAssertIfISR(); void vFakePortAssertIfISR();
BaseType_t vFakePortCheckIfInISR( void );
unsigned int vFakePortGetCoreID( void );
void vFakePortYieldCore( int );
portBASE_TYPE vFakePortEnterCriticalFromISR( void );
void vFakePortExitCriticalFromISR( portBASE_TYPE uxSavedInterruptState );
void vFakePortAllocateSecureContext( BaseType_t stackSize );
#endif /* FAKE_PORT_H */ #endif /* FAKE_PORT_H */

View file

@ -81,6 +81,7 @@ typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t; typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 ) #if ( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t; typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff #define portMAX_DELAY ( TickType_t ) 0xffff
@ -93,6 +94,7 @@ typedef unsigned long UBaseType_t;
/* Requires definition of UBaseType_t */ /* Requires definition of UBaseType_t */
#include "fake_port.h" #include "fake_port.h"
#include <FreeRTOS.h>
/* Hardware specifics. */ /* Hardware specifics. */
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
@ -123,46 +125,70 @@ typedef unsigned long UBaseType_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portSAVE_CONTEXT() #define portSAVE_CONTEXT()
#define portYIELD() vFakePortYield() #define portYIELD() vFakePortYield()
#define portYIELD_WITHIN_API() vFakePortYieldWithinAPI() #define portYIELD_WITHIN_API() vFakePortYieldWithinAPI()
#define portYIELD_FROM_ISR() vFakePortYieldFromISR() #define portYIELD_FROM_ISR() vFakePortYieldFromISR()
/* Critical section handling. */ /* Critical section handling. */
#define portDISABLE_INTERRUPTS() vFakePortDisableInterrupts() #define portDISABLE_INTERRUPTS() vFakePortDisableInterrupts()
#define portENABLE_INTERRUPTS() vFakePortEnableInterrupts() #define portENABLE_INTERRUPTS() vFakePortEnableInterrupts()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) \ #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) \
vFakePortClearInterruptMaskFromISR( x ) vFakePortClearInterruptMaskFromISR( x )
#define portSET_INTERRUPT_MASK_FROM_ISR() \ #define portSET_INTERRUPT_MASK_FROM_ISR() \
ulFakePortSetInterruptMaskFromISR() ulFakePortSetInterruptMaskFromISR()
#define portSET_INTERRUPT_MASK() ulFakePortSetInterruptMask() #define portSET_INTERRUPT_MASK() ulFakePortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK( x ) vFakePortClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK( x ) vFakePortClearInterruptMask( x )
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() \ #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() \
vFakePortAssertIfInterruptPriorityInvalid() vFakePortAssertIfInterruptPriorityInvalid()
#define portENTER_CRITICAL() vFakePortEnterCriticalSection() #define portENTER_CRITICAL() vFakePortEnterCriticalSection()
#define portEXIT_CRITICAL() vFakePortExitCriticalSection() #define portEXIT_CRITICAL() vFakePortExitCriticalSection()
#define portGET_ISR_LOCK() vFakePortGetISRLock()
#define portRELEASE_ISR_LOCK() vFakePortReleaseISRLock()
#define portGET_TASK_LOCK() vFakePortGetTaskLock()
#define portRELEASE_TASK_LOCK() vFakePortReleaseTaskLock()
#define portCHECK_IF_IN_ISR() vFakePortCheckIfInISR()
#define portRESTORE_INTERRUPTS( x ) vFakePortRestoreInterrupts( x )
#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxPendYield ) \ #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxPendYield ) \
vPortCurrentTaskDying( ( pvTaskToDelete ), ( pxPendYield ) ) vPortCurrentTaskDying( ( pvTaskToDelete ), ( pxPendYield ) )
#define portSETUP_TCB( pxTCB ) portSetupTCB_CB( pxTCB ); #define portSETUP_TCB( pxTCB ) portSetupTCB_CB( pxTCB );
#define portASSERT_IF_IN_ISR() vFakePortAssertIfISR(); #define portASSERT_IF_IN_ISR() vFakePortAssertIfISR();
#define ucPortCountLeadingZeros( ulBitmap ) ( ( uint8_t ) __builtin_clz( ulBitmap ) ) #define portGET_CORE_ID() vFakePortGetCoreID()
#define portYIELD_CORE( x ) vFakePortYieldCore( x )
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) \ #define portENTER_CRITICAL_FROM_ISR vFakePortEnterCriticalFromISR
#define portEXIT_CRITICAL_FROM_ISR vFakePortExitCriticalFromISR
#if ( configNUMBER_OF_CORES > 1 )
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
#else
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \
volatile int fool_static = 0; \
void vFunction( void * ( pvParameters ) )
#define portTASK_FUNCTION( vFunction, pvParameters ) \
volatile int fool_static2 = 0; \
void vFunction( void * ( pvParameters ) )
#endif
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
static uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
{
uint8_t ucReturn;
ucReturn = __builtin_clz( ulBitmap );
return ucReturn;
}
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) \
( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) \ #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) \
( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \ #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
#endif /* if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) */
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \
volatile int fool_static = 0; \
void vFunction( void * ( pvParameters ) )
#define portTASK_FUNCTION( vFunction, pvParameters ) \
volatile int fool_static2 = 0; \
void vFunction( void * ( pvParameters ) )
/* We need to define it here because CMock does not recognize the /* We need to define it here because CMock does not recognize the
* #if ( portUSING_MPU_WRAPPERS == 1 ) guard around xTaskGetMPUSettings * #if ( portUSING_MPU_WRAPPERS == 1 ) guard around xTaskGetMPUSettings

View file

@ -13,7 +13,7 @@ GENERATED_DIR := $(BUILD_DIR)/generated
LIB_DIR := $(BUILD_DIR)/lib LIB_DIR := $(BUILD_DIR)/lib
TOOLS_DIR := $(UT_ROOT_DIR)/tools TOOLS_DIR := $(UT_ROOT_DIR)/tools
FREERTOS_DIR := $(abspath $(UT_ROOT_DIR)../../../FreeRTOS) FREERTOS_DIR := $(abspath $(UT_ROOT_DIR)/../../../FreeRTOS)
KERNEL_DIR := $(abspath $(UT_ROOT_DIR)/../../../FreeRTOS/Source) KERNEL_DIR := $(abspath $(UT_ROOT_DIR)/../../../FreeRTOS/Source)
CMOCK_DIR := $(UT_ROOT_DIR)/CMock CMOCK_DIR := $(UT_ROOT_DIR)/CMock

View file

@ -255,6 +255,7 @@ static BaseType_t receiverTaskNotificationCallback( TaskHandle_t xTaskToNotify,
/******************************************************************************* /*******************************************************************************
* Unity fixtures * Unity fixtures
******************************************************************************/ ******************************************************************************/
/*! called before each test case */
void setUp( void ) void setUp( void )
{ {
assertionFailed = 0; assertionFailed = 0;
@ -276,7 +277,7 @@ void setUp( void )
UnityMalloc_StartTest(); UnityMalloc_StartTest();
} }
/*! called before each test case */ /*! called after each test case */
void tearDown( void ) void tearDown( void )
{ {
TEST_ASSERT_EQUAL_MESSAGE( 0, assertionFailed, "Assertion check failed in code." ); TEST_ASSERT_EQUAL_MESSAGE( 0, assertionFailed, "Assertion check failed in code." );

View file

@ -70,6 +70,18 @@ int suiteTearDown( int numFailures )
/* ========================== Helper functions =========================== */ /* ========================== Helper functions =========================== */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================= Test Cases ============================== */ /* ============================= Test Cases ============================== */
/** /**
@ -108,6 +120,7 @@ void test_xQueueReceive_blocking_success_locked_no_pending( void )
xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB ); xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB );
xTaskResumeAll_Stub( &td_task_xTaskResumeAllStub ); xTaskResumeAll_Stub( &td_task_xTaskResumeAllStub );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
@ -140,6 +153,7 @@ void test_xQueuePeek_blocking_success_locked_no_pending( void )
xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB ); xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB );
xTaskResumeAll_Stub( &td_task_xTaskResumeAllStub ); xTaskResumeAll_Stub( &td_task_xTaskResumeAllStub );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
@ -196,6 +210,7 @@ void test_xQueueReceive_blocking_timeout_locked_high_prio_pending( void )
xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB ); xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB );
xTaskResumeAll_Stub( &xQueueReceive_xTaskResumeAllCallback ); xTaskResumeAll_Stub( &xQueueReceive_xTaskResumeAllCallback );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
@ -236,6 +251,7 @@ void test_xQueuePeek_blocking_timeout_locked_high_prio_pending( void )
xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB ); xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB );
xTaskResumeAll_Stub( &xQueueReceive_xTaskResumeAllCallback ); xTaskResumeAll_Stub( &xQueueReceive_xTaskResumeAllCallback );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
@ -276,6 +292,7 @@ void test_xQueueReceive_blocking_success_locked_low_prio_pending( void )
xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB ); xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB );
xTaskResumeAll_Stub( &xQueueReceive_xTaskResumeAllCallback ); xTaskResumeAll_Stub( &xQueueReceive_xTaskResumeAllCallback );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
td_task_setFakeTaskPriority( DEFAULT_PRIORITY - 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY - 1 );
@ -312,6 +329,7 @@ void test_xQueuePeek_blocking_success_locked_low_prio_pending( void )
xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB ); xTaskCheckForTimeOut_Stub( &xQueueReceive_xTaskCheckForTimeOutCB );
xTaskResumeAll_Stub( &xQueueReceive_xTaskResumeAllCallback ); xTaskResumeAll_Stub( &xQueueReceive_xTaskResumeAllCallback );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
td_task_setFakeTaskPriority( DEFAULT_PRIORITY - 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY - 1 );
@ -345,6 +363,7 @@ void test_xQueuePeek_blocking_suspended_assert( void )
td_task_setSchedulerState( taskSCHEDULER_SUSPENDED ); td_task_setSchedulerState( taskSCHEDULER_SUSPENDED );
vTaskSuspendAll_Stub( td_task_vTaskSuspendAllStubNoCheck ); vTaskSuspendAll_Stub( td_task_vTaskSuspendAllStubNoCheck );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
@ -398,6 +417,7 @@ void test_xQueuePeek_blocking_success( void )
xQueueHandleStatic = xQueue; xQueueHandleStatic = xQueue;
xTaskCheckForTimeOut_Stub( &blocking_success_xTaskCheckForTimeOut_cb ); xTaskCheckForTimeOut_Stub( &blocking_success_xTaskCheckForTimeOut_cb );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
@ -446,6 +466,7 @@ void test_xQueuePeek_blocking_success_last_chance( void )
xQueueHandleStatic = xQueue; xQueueHandleStatic = xQueue;
xTaskCheckForTimeOut_Stub( &blocking_success_last_chance_xTaskCheckForTimeOut_cb ); xTaskCheckForTimeOut_Stub( &blocking_success_last_chance_xTaskCheckForTimeOut_cb );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
@ -472,6 +493,8 @@ void test_xQueuePeek_blocking_timeout( void )
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
TEST_ASSERT_EQUAL( pdFALSE, xQueuePeek( xQueue, &checkVal, TICKS_TO_WAIT ) ); TEST_ASSERT_EQUAL( pdFALSE, xQueuePeek( xQueue, &checkVal, TICKS_TO_WAIT ) );
TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) ); TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
@ -496,6 +519,7 @@ void test_xQueueReceive_blocking_suspended_assert( void )
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
fakeAssertExpectFail(); fakeAssertExpectFail();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
td_task_setSchedulerState( taskSCHEDULER_SUSPENDED ); td_task_setSchedulerState( taskSCHEDULER_SUSPENDED );
@ -528,6 +552,7 @@ void test_xQueueReceive_blocking_success( void )
xQueueHandleStatic = xQueue; xQueueHandleStatic = xQueue;
xTaskCheckForTimeOut_Stub( &blocking_success_xTaskCheckForTimeOut_cb ); xTaskCheckForTimeOut_Stub( &blocking_success_xTaskCheckForTimeOut_cb );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
@ -558,6 +583,7 @@ void test_xQueueReceive_blocking_success_last_chance( void )
xQueueHandleStatic = xQueue; xQueueHandleStatic = xQueue;
xTaskCheckForTimeOut_Stub( &blocking_success_last_chance_xTaskCheckForTimeOut_cb ); xTaskCheckForTimeOut_Stub( &blocking_success_last_chance_xTaskCheckForTimeOut_cb );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
@ -584,6 +610,8 @@ void test_xQueueReceive_blocking_timeout( void )
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
TEST_ASSERT_EQUAL( pdFALSE, xQueueReceive( xQueue, &checkVal, TICKS_TO_WAIT ) ); TEST_ASSERT_EQUAL( pdFALSE, xQueueReceive( xQueue, &checkVal, TICKS_TO_WAIT ) );
TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) ); TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
@ -612,6 +640,8 @@ void test_xQueueReceive_blocking_locked( void )
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Run xQueueReceive in blocking mode with the queue locked */ /* Run xQueueReceive in blocking mode with the queue locked */
TEST_ASSERT_EQUAL( pdFALSE, xQueueReceive( xQueue, &checkVal, TICKS_TO_WAIT ) ); TEST_ASSERT_EQUAL( pdFALSE, xQueueReceive( xQueue, &checkVal, TICKS_TO_WAIT ) );
@ -636,6 +666,8 @@ void test_xQueueReceive_blocking_locked( void )
*/ */
void test_xQueuePeek_blocking_locked( void ) void test_xQueuePeek_blocking_locked( void )
{ {
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Create a new binary Queue */ /* Create a new binary Queue */
QueueHandle_t xQueue = xQueueCreate( 1, sizeof( uint32_t ) ); QueueHandle_t xQueue = xQueueCreate( 1, sizeof( uint32_t ) );

View file

@ -74,6 +74,18 @@ int suiteTearDown( int numFailures )
/* ========================== Helper functions =========================== */ /* ========================== Helper functions =========================== */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================= Test Cases ============================== */ /* ============================= Test Cases ============================== */
/** /**
@ -287,6 +299,8 @@ void test_xQueuePeek_noop_waiting_higher_priority( void )
/* peek from the queue */ /* peek from the queue */
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
TEST_ASSERT_EQUAL( 1, uxQueueMessagesWaiting( xQueue ) ); TEST_ASSERT_EQUAL( 1, uxQueueMessagesWaiting( xQueue ) );
TEST_ASSERT_EQUAL( pdTRUE, xQueuePeek( xQueue, &checkVal, 0 ) ); TEST_ASSERT_EQUAL( pdTRUE, xQueuePeek( xQueue, &checkVal, 0 ) );
@ -325,6 +339,7 @@ void test_xQueuePeek_xQueuePeek_waiting_higher_priority( void )
td_task_addFakeTaskWaitingToReceiveFromQueue( xQueue ); td_task_addFakeTaskWaitingToReceiveFromQueue( xQueue );
vFakePortYieldWithinAPI_Stub( &vPortYieldWithinAPI_xQueuePeek_Stub ); vFakePortYieldWithinAPI_Stub( &vPortYieldWithinAPI_xQueuePeek_Stub );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
xStubExpectedReturnValue = pdTRUE; xStubExpectedReturnValue = pdTRUE;
@ -369,6 +384,7 @@ void test_xQueuePeek_xQueueReceive_waiting_higher_priority( void )
td_task_addFakeTaskWaitingToReceiveFromQueue( xQueue ); td_task_addFakeTaskWaitingToReceiveFromQueue( xQueue );
vFakePortYieldWithinAPI_Stub( &vPortYieldWithinAPI_xQueueReceive_Stub ); vFakePortYieldWithinAPI_Stub( &vPortYieldWithinAPI_xQueueReceive_Stub );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
xStubExpectedReturnValue = pdTRUE; xStubExpectedReturnValue = pdTRUE;
@ -805,6 +821,8 @@ void test_xQueueReceive_noop_waiting_higher_priority( void )
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
TEST_ASSERT_EQUAL( 1, uxQueueMessagesWaiting( xQueue ) ); TEST_ASSERT_EQUAL( 1, uxQueueMessagesWaiting( xQueue ) );
/* receive from the queue */ /* receive from the queue */

View file

@ -67,6 +67,18 @@ int suiteTearDown( int numFailures )
/* ========================== Helper functions =========================== */ /* ========================== Helper functions =========================== */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ========================== Test Cases =========================== */ /* ========================== Test Cases =========================== */
/** /**
@ -164,6 +176,8 @@ void test_macro_xQueueReset_tasks_waiting_higher_priority( void )
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
td_task_addFakeTaskWaitingToSendToQueue( xQueue ); td_task_addFakeTaskWaitingToSendToQueue( xQueue );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
TEST_ASSERT_EQUAL( pdTRUE, xQueueReset( xQueue ) ); TEST_ASSERT_EQUAL( pdTRUE, xQueueReset( xQueue ) );
TEST_ASSERT_EQUAL( 1, td_task_getYieldCount() ); TEST_ASSERT_EQUAL( 1, td_task_getYieldCount() );

View file

@ -45,6 +45,18 @@ static QueueHandle_t xQueueHandleStatic;
/* ========================== CALLBACK FUNCTIONS =========================== */ /* ========================== CALLBACK FUNCTIONS =========================== */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================= Unity Fixtures ============================= */ /* ============================= Unity Fixtures ============================= */
void setUp( void ) void setUp( void )
@ -82,6 +94,8 @@ static BaseType_t xQueueSend_locked_xTaskCheckForTimeOutCB( TimeOut_t * const px
{ {
BaseType_t xReturnValue = td_task_xTaskCheckForTimeOutStub( pxTimeOut, pxTicksToWait, cmock_num_calls ); BaseType_t xReturnValue = td_task_xTaskCheckForTimeOutStub( pxTimeOut, pxTicksToWait, cmock_num_calls );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
if( cmock_num_calls == NUM_CALLS_TO_INTERCEPT ) if( cmock_num_calls == NUM_CALLS_TO_INTERCEPT )
{ {
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
@ -138,6 +152,8 @@ static BaseType_t xQueueSend_xTaskResumeAllCallback( int cmock_num_calls )
{ {
BaseType_t xReturnValue = td_task_xTaskResumeAllStub( cmock_num_calls ); BaseType_t xReturnValue = td_task_xTaskResumeAllStub( cmock_num_calls );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* If td_task_xTaskResumeAllStub returns pdTRUE, a higher priority task is pending /* If td_task_xTaskResumeAllStub returns pdTRUE, a higher priority task is pending
* Send from an ISR to block */ * Send from an ISR to block */
if( pdTRUE == xReturnValue ) if( pdTRUE == xReturnValue )
@ -171,6 +187,7 @@ void test_macro_xQueueSend_blocking_fail_locked_high_prio_pending( void )
xTaskCheckForTimeOut_Stub( &xQueueSend_locked_xTaskCheckForTimeOutCB ); xTaskCheckForTimeOut_Stub( &xQueueSend_locked_xTaskCheckForTimeOutCB );
xTaskResumeAll_Stub( &xQueueSend_xTaskResumeAllCallback ); xTaskResumeAll_Stub( &xQueueSend_xTaskResumeAllCallback );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* this task is lower priority than the pending task */ /* this task is lower priority than the pending task */
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
@ -256,6 +273,7 @@ void test_macro_xQueueSend_blocking_suspended_assert( void )
uint32_t testVal = getNextMonotonicTestValue(); uint32_t testVal = getNextMonotonicTestValue();
fakeAssertExpectFail(); fakeAssertExpectFail();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
td_task_setSchedulerState( taskSCHEDULER_SUSPENDED ); td_task_setSchedulerState( taskSCHEDULER_SUSPENDED );
@ -282,6 +300,8 @@ void test_macro_xQueueSend_blocking_timeout( void )
uint32_t testVal = getNextMonotonicTestValue(); uint32_t testVal = getNextMonotonicTestValue();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Fill up the queue */ /* Fill up the queue */
TEST_ASSERT_EQUAL( pdTRUE, xQueueSend( xQueue, &testVal, 0 ) ); TEST_ASSERT_EQUAL( pdTRUE, xQueueSend( xQueue, &testVal, 0 ) );
@ -314,6 +334,8 @@ void test_macro_xQueueSend_blocking_locked( void )
uint32_t testVal1 = getNextMonotonicTestValue(); uint32_t testVal1 = getNextMonotonicTestValue();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Fill the queue */ /* Fill the queue */
TEST_ASSERT_EQUAL( pdTRUE, xQueueSend( xQueue, &testVal1, TICKS_TO_WAIT ) ); TEST_ASSERT_EQUAL( pdTRUE, xQueueSend( xQueue, &testVal1, TICKS_TO_WAIT ) );

View file

@ -44,6 +44,18 @@
/* ========================== CALLBACK FUNCTIONS =========================== */ /* ========================== CALLBACK FUNCTIONS =========================== */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================= Unity Fixtures ============================= */ /* ============================= Unity Fixtures ============================= */
void setUp( void ) void setUp( void )
@ -246,6 +258,8 @@ void test_macro_xQueueSend_task_waiting_higher_priority_success( void )
{ {
QueueHandle_t xQueue = xQueueCreate( 1, sizeof( uint32_t ) ); QueueHandle_t xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Insert an item into the event list */ /* Insert an item into the event list */
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
td_task_addFakeTaskWaitingToReceiveFromQueue( xQueue ); td_task_addFakeTaskWaitingToReceiveFromQueue( xQueue );

View file

@ -42,6 +42,18 @@ static SemaphoreHandle_t xSemaphoreHandleStatic;
/* ========================== CALLBACK FUNCTIONS =========================== */ /* ========================== CALLBACK FUNCTIONS =========================== */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================= Unity Fixtures ============================= */ /* ============================= Unity Fixtures ============================= */
void setUp( void ) void setUp( void )
@ -501,6 +513,8 @@ void test_xSemaphoreTake_tasks_waiting_higher_priority( void )
( void ) xSemaphoreGive( xSemaphore ); ( void ) xSemaphoreGive( xSemaphore );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Insert an item into the event list */ /* Insert an item into the event list */
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
td_task_addFakeTaskWaitingToSendToQueue( xSemaphore ); td_task_addFakeTaskWaitingToSendToQueue( xSemaphore );
@ -582,6 +596,7 @@ void test_xSemaphoreTake_blocking_suspended_assert( void )
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary(); SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
fakeAssertExpectFail(); fakeAssertExpectFail();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
vTaskSuspendAll_Stub( td_task_vTaskSuspendAllStubNoCheck ); vTaskSuspendAll_Stub( td_task_vTaskSuspendAllStubNoCheck );
@ -649,6 +664,7 @@ void test_xSemaphoreTake_blocking_success( void )
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;
vFakePortAssertIfInterruptPriorityInvalid_Ignore(); vFakePortAssertIfInterruptPriorityInvalid_Ignore();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
xTaskCheckForTimeOut_Stub( &blocking_success_xTaskCheckForTimeOut_cb ); xTaskCheckForTimeOut_Stub( &blocking_success_xTaskCheckForTimeOut_cb );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
@ -696,6 +712,7 @@ void test_xSemaphoreTake_blocking_success_last_chance( void )
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;
vFakePortAssertIfInterruptPriorityInvalid_Expect(); vFakePortAssertIfInterruptPriorityInvalid_Expect();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
xTaskCheckForTimeOut_Stub( &blocking_last_chance_xTaskCheckForTimeOut_cb ); xTaskCheckForTimeOut_Stub( &blocking_last_chance_xTaskCheckForTimeOut_cb );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
@ -718,6 +735,8 @@ void test_xSemaphoreTake_blocking_timeout( void )
{ {
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary(); SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, TICKS_TO_WAIT ) ); 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_getYieldCount() );
@ -738,6 +757,8 @@ void test_xSemaphoreTake_blocking_locked( void )
/* Create a new binary semaphore */ /* Create a new binary semaphore */
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary(); SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Set private lock counters */ /* Set private lock counters */
vSetQueueRxLock( xSemaphore, queueLOCKED_UNMODIFIED ); vSetQueueRxLock( xSemaphore, queueLOCKED_UNMODIFIED );
vSetQueueTxLock( xSemaphore, queueLOCKED_UNMODIFIED ); vSetQueueTxLock( xSemaphore, queueLOCKED_UNMODIFIED );
@ -787,6 +808,7 @@ void test_xSemaphoreTake_blocking_success_locked_no_pending( void )
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary(); SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
vFakePortAssertIfInterruptPriorityInvalid_Ignore(); vFakePortAssertIfInterruptPriorityInvalid_Ignore();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Export for callbacks */ /* Export for callbacks */
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;
@ -840,6 +862,7 @@ void test_xSemaphoreTake_blocking_timeout_locked_high_prio_pending( void )
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary(); SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
vFakePortAssertIfInterruptPriorityInvalid_Ignore(); vFakePortAssertIfInterruptPriorityInvalid_Ignore();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Export for callbacks */ /* Export for callbacks */
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;
@ -878,6 +901,7 @@ void test_xSemaphoreTake_blocking_success_locked_low_prio_pending( void )
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary(); SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
vFakePortAssertIfInterruptPriorityInvalid_Ignore(); vFakePortAssertIfInterruptPriorityInvalid_Ignore();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Export for callbacks */ /* Export for callbacks */
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;

View file

@ -40,6 +40,18 @@ static SemaphoreHandle_t xSemaphoreHandleStatic;
/* ========================== CALLBACK FUNCTIONS =========================== */ /* ========================== CALLBACK FUNCTIONS =========================== */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================= Unity Fixtures ============================= */ /* ============================= Unity Fixtures ============================= */
void setUp( void ) void setUp( void )
@ -349,6 +361,7 @@ void test_xSemaphoreTake_blocking_suspended_assert( void )
fakeAssertExpectFail(); fakeAssertExpectFail();
vTaskSuspendAll_Stub( td_task_vTaskSuspendAllStubNoCheck ); vTaskSuspendAll_Stub( td_task_vTaskSuspendAllStubNoCheck );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
td_task_setSchedulerState( taskSCHEDULER_SUSPENDED ); td_task_setSchedulerState( taskSCHEDULER_SUSPENDED );
@ -417,6 +430,7 @@ void test_xSemaphoreTake_blocking_success( void )
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;
vFakePortAssertIfInterruptPriorityInvalid_Expect(); vFakePortAssertIfInterruptPriorityInvalid_Expect();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
xTaskCheckForTimeOut_Stub( &blocking_xTaskCheckForTimeOut_cb ); xTaskCheckForTimeOut_Stub( &blocking_xTaskCheckForTimeOut_cb );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
@ -467,6 +481,7 @@ void test_xSemaphoreTake_blocking_success_last_chance( void )
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;
vFakePortAssertIfInterruptPriorityInvalid_Expect(); vFakePortAssertIfInterruptPriorityInvalid_Expect();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
xTaskCheckForTimeOut_Stub( &blocking_last_chance_xTaskCheckForTimeOut_cb ); xTaskCheckForTimeOut_Stub( &blocking_last_chance_xTaskCheckForTimeOut_cb );
uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 ); uxTaskGetNumberOfTasks_IgnoreAndReturn( 1 );
@ -492,6 +507,8 @@ void test_xSemaphoreTake_blocking_timeout( void )
{ {
SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 ); SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, TICKS_TO_WAIT ) ); 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_getYieldCount() );
@ -512,6 +529,8 @@ void test_xSemaphoreTake_blocking_locked( void )
/* Create a new binary semaphore */ /* Create a new binary semaphore */
SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 ); SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Set private lock counters */ /* Set private lock counters */
vSetQueueRxLock( xSemaphore, queueLOCKED_UNMODIFIED ); vSetQueueRxLock( xSemaphore, queueLOCKED_UNMODIFIED );
vSetQueueTxLock( xSemaphore, queueLOCKED_UNMODIFIED ); vSetQueueTxLock( xSemaphore, queueLOCKED_UNMODIFIED );
@ -560,6 +579,7 @@ void test_xSemaphoreTake_blocking_success_locked_no_pending( void )
SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 ); SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 );
vFakePortAssertIfInterruptPriorityInvalid_Ignore(); vFakePortAssertIfInterruptPriorityInvalid_Ignore();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Export for callbacks */ /* Export for callbacks */
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;
@ -613,6 +633,7 @@ void test_xSemaphoreTake_blocking_timeout_locked_high_prio_pending( void )
SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 ); SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 );
vFakePortAssertIfInterruptPriorityInvalid_Ignore(); vFakePortAssertIfInterruptPriorityInvalid_Ignore();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Export for callbacks */ /* Export for callbacks */
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;
@ -651,6 +672,7 @@ void test_xSemaphoreTake_blocking_success_locked_low_prio_pending( void )
SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 ); SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 2, 0 );
vFakePortAssertIfInterruptPriorityInvalid_Ignore(); vFakePortAssertIfInterruptPriorityInvalid_Ignore();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Export for callbacks */ /* Export for callbacks */
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;

View file

@ -38,6 +38,18 @@ static SemaphoreHandle_t xSemaphoreHandleStatic = NULL;
/* ========================== CALLBACK FUNCTIONS =========================== */ /* ========================== CALLBACK FUNCTIONS =========================== */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================= Unity Fixtures ============================= */ /* ============================= Unity Fixtures ============================= */
void setUp( void ) void setUp( void )
@ -468,6 +480,7 @@ void test_macro_xSemaphoreTake_blocking_mutex_inherit_timeout( void )
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */ /* Return a test value from the call to pvTaskIncrementMutexHeldCount */
pvTaskIncrementMutexHeldCount_ExpectAndReturn( ( void * ) xFakeMutexHolder ); pvTaskIncrementMutexHeldCount_ExpectAndReturn( ( void * ) xFakeMutexHolder );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Take the mutex */ /* Take the mutex */
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) ); TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
@ -553,6 +566,8 @@ void test_macro_xSemaphoreTake_blocking_mutex_inherit_disinherit( void )
{ {
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE ); xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex(); SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
xSemaphoreHandleStatic = xSemaphore; xSemaphoreHandleStatic = xSemaphore;

View file

@ -72,6 +72,18 @@ int suiteTearDown( int numFailures )
/* =========================== Helper functions ============================ */ /* =========================== Helper functions ============================ */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================== Test Cases =============================== */ /* ============================== Test Cases =============================== */
@ -429,6 +441,7 @@ void test_macro_xQueueSendFromISR_in_set_locked_and_low_priority_pending( void )
xQueueAddToSet( xQueue, xQueueSet ); xQueueAddToSet( xQueue, xQueueSet );
vFakePortAssertIfInterruptPriorityInvalid_Expect(); vFakePortAssertIfInterruptPriorityInvalid_Expect();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* Insert an item into the event list. */ /* Insert an item into the event list. */
td_task_setFakeTaskPriority( DEFAULT_PRIORITY - 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY - 1 );
@ -556,6 +569,8 @@ void test_macro_xQueueSend_in_set_high_priority_pending( void )
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 ); td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
td_task_addFakeTaskWaitingToReceiveFromQueue( xQueueSet ); td_task_addFakeTaskWaitingToReceiveFromQueue( xQueueSet );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
uint32_t testVal = getNextMonotonicTestValue(); uint32_t testVal = getNextMonotonicTestValue();
/* Add item to queue*/ /* Add item to queue*/
@ -795,6 +810,8 @@ void test_macro_xQueueSend_in_set_blocking_success_locked_no_pending( void )
uint32_t testVal = getNextMonotonicTestValue(); uint32_t testVal = getNextMonotonicTestValue();
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
TEST_ASSERT_EQUAL( pdTRUE, xQueueSend( xQueue, &testVal, 0 ) ); TEST_ASSERT_EQUAL( pdTRUE, xQueueSend( xQueue, &testVal, 0 ) );
xTaskCheckForTimeOut_Stub( &xQueueSend_locked_xTaskCheckForTimeOutCB ); xTaskCheckForTimeOut_Stub( &xQueueSend_locked_xTaskCheckForTimeOutCB );
@ -848,6 +865,8 @@ void test_macro_xQueueSend_in_set_blocking_fail_locked_high_prio_pending( void )
QueueHandle_t xQueue = xQueueCreate( 1, sizeof( uint32_t ) ); QueueHandle_t xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
xQueueAddToSet( xQueue, xQueueSet ); xQueueAddToSet( xQueue, xQueueSet );
/* Export for callbacks */ /* Export for callbacks */
@ -896,6 +915,8 @@ void test_macro_xQueueSend_in_set_blocking_success_locked_low_prio_pending( void
QueueHandle_t xQueue = xQueueCreate( 1, sizeof( uint32_t ) ); QueueHandle_t xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
xQueueAddToSet( xQueue, xQueueSet ); xQueueAddToSet( xQueue, xQueueSet );
/* Export for callbacks */ /* Export for callbacks */
@ -968,6 +989,8 @@ void test_xQueueReceive_in_set_blocking_success_locked_no_pending( void )
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
QueueHandle_t xQueueFromSet = xQueueSelectFromSet( xQueueSet, TICKS_TO_WAIT ); QueueHandle_t xQueueFromSet = xQueueSelectFromSet( xQueueSet, TICKS_TO_WAIT );
TEST_ASSERT_NOT_NULL( xQueueFromSet ); TEST_ASSERT_NOT_NULL( xQueueFromSet );
@ -1035,6 +1058,8 @@ void test_xQueueReceive_in_set_blocking_fail_locked_high_prio_pending( void )
td_task_addFakeTaskWaitingToReceiveFromQueue( xQueueSet ); td_task_addFakeTaskWaitingToReceiveFromQueue( xQueueSet );
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
QueueHandle_t xQueueFromSet = xQueueSelectFromSet( xQueueSet, TICKS_TO_WAIT ); QueueHandle_t xQueueFromSet = xQueueSelectFromSet( xQueueSet, TICKS_TO_WAIT );
TEST_ASSERT_EQUAL( NULL, xQueueFromSet ); TEST_ASSERT_EQUAL( NULL, xQueueFromSet );
@ -1080,6 +1105,8 @@ void test_xQueueReceive_in_set_blocking_success_locked_low_prio_pending( void )
uint32_t checkVal = INVALID_UINT32; uint32_t checkVal = INVALID_UINT32;
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
QueueHandle_t xQueueFromSet = xQueueSelectFromSet( xQueueSet, NUM_CALLS_TO_INTERCEPT ); QueueHandle_t xQueueFromSet = xQueueSelectFromSet( xQueueSet, NUM_CALLS_TO_INTERCEPT );
TEST_ASSERT_EQUAL( NUM_CALLS_TO_INTERCEPT, td_task_getYieldCount() ); TEST_ASSERT_EQUAL( NUM_CALLS_TO_INTERCEPT, td_task_getYieldCount() );

View file

@ -0,0 +1,23 @@
# Indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
include ../makefile.in
# SUITES lists the suites contained in subdirectories of this directory
SUITES += single_priority_no_timeslice
SUITES += single_priority_timeslice
SUITES += multiple_priorities_no_timeslice
SUITES += multiple_priorities_timeslice
# SUITS mock dependency source for coverage test
SUITES += multiple_priorities_no_timeslice_mock
# SUITS for configASSERT
SUITES += config_assert
# PROJECT and SUITE variables are determined based on path like so:
# $(UT_ROOT_DIR)/$(PROJECT)/$(SUITE)
PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)))))
include ../subdir.mk

View file

@ -0,0 +1,170 @@
# FreeRTOS Kernel SMP Unit Test
FreeRTOS Kernel SMP unit test verifies the SMP scheduler logic in tasks.c which
is enclosed by `configNUMBER_OF_CORES > 1`. The common scheduler logic for single
core and SMP is still verified in FreeRTOS/FreeRTOS/Test/CMock/tasks.
## Folder structure and test group naming
FreeRTOS SMP unit test has the following folder structure:
```
./FreeRTOS/FreeRTOS/Test/CMock/smp
├── Makefile
├── config_assert
│ └── config_assert_utest.c
├── multiple_priorities_no_timeslice_mock
│ └── covg_multiple_priorities_no_timeslice_mock_utest.c
├── multiple_priorities_no_timeslice
│ ├── covg_multiple_priorities_no_timeslice_utest.c
│ └── multiple_priorities_no_timeslice_utest.c
├── multiple_priorities_timeslice
│ ├── covg_multiple_priorities_timeslice_utest.c
│ └── multiple_priorities_timeslice_utest.c
├── single_priority_no_timeslice
│ ├── covg_single_priority_no_timeslice_utest.c
│ └── single_priority_no_timeslice_utest.c
├── single_priority_timeslice
│ ├── covg_single_priority_timeslice_utest.c
│ └── single_priority_timeslice_utest.c
├── global_vars.h
├── smp_utest_common.c
└── smp_utest_common.h
```
FreeRTOS SMP unit test cases are divided into groups and each folder represents
a test group. Test cases with same configurations in FreeRTOSConfig.h are grouped
together in a test group.
The following test groups are created for the combinations of `configRUN_MULTIPLE_PRIORITIES`
and `configUSE_TIME_SLICING`:
* single_priority_timeslice
* single_priority_no_timeslice
* multiple_priorities_timeslice
* multiple_priorities_no_timeslice
In order to increase the test coverage rate, test group **multiple_priorities_no_timeslice_mock**
is created to mock the APIs in list.h. The configuration is similar to **multiple_priorities_no_timeslice**.
* multiple_priorities_no_timeslice_mock
config_assert test group is created to cover `configASSERT` in FreeRTOS SMP scheduler logic.
* config_assert
## Functional tests and coverage tests
Each test group has two types of test cases, the functional test cases and coverage
test cases. To distinguish these test cases, the source code file has the following
naming convention:
* Coverage test : covg_\<test_group_name\>_utest.c
* Functional test : \<test_group_name\>_utest.c
### Functional tests
Functional test cases verify that the SMP scheduler logic performs as described
by functional requirements. The test case specifies the functional requirement to
be verified, the test steps and expected result in the comment.
The following is an example of the functional test:
```c
/**
* @brief AWS_IoT-FreeRTOS_SMP_TC-1
* The purpose of this test is to verify when multiple CPU cores are available and
* the FreeRTOS kernel is configured as (configRUN_MULTIPLE_PRIORITIES = 0) that tasks
* of equal priority will execute simultaneously. The kernel will be configured as follows:
*
* #define configRUN_MULTIPLE_PRIORITIES 0
* #define configUSE_TIME_SLICING 0
* #define configNUMBER_OF_CORES (N > 1)
*
* This test can be run with FreeRTOS configured for any number of cores greater than 1 .
*
* Tasks are created prior to starting the scheduler.
*
* Task (T1) Task (TN)
* Priority 1 Priority 1
* State - Ready State - Ready
*
* After calling vTaskStartScheduler()
*
* Task (T1) Task (TN)
* Priority 1 Priority 1
* State - Running (Core 0) State - Running (Core N)
*/
void test_priority_verification_tasks_equal_priority( void )
{
TaskHandle_t xTaskHandles[ configNUMBER_OF_CORES ] = { NULL };
uint32_t i;
/* Create configNUMBER_OF_CORES tasks of equal priority */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskCreate( vSmpTestTask, "SMP Task", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandles[ i ] );
}
vTaskStartScheduler();
/* Verify all configNUMBER_OF_CORES tasks are in the running state */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
verifySmpTask( &xTaskHandles[ i ], eRunning, i );
}
}
```
### Coverage tests
Coverage test cases verify a specific path of SMP scheduler logic.
The test case specifies the lines of code to be covered in the test case.
To minimize dependencies, mock functions are used wherever possible.
The following is an example of the coverage test:
```c
/**
* @brief xTaskResumeFromISR - resume higher priority suspended task
*
* A higher priority task from ISR is resumed in the test case when scheduler
* suspended. The return value of xTaskResumeFromISR indicates yield required
* for the core calling this API.
*
* <b>Coverage</b>
* @code{c}
* prvYieldForTask( pxTCB );
*
* if( xYieldPendings[ portGET_CORE_ID() ] != pdFALSE )
* {
* xYieldRequired = pdTRUE;
* }
* @endcode
* ( xYieldPendings[ portGET_CORE_ID() ] != pdFALSE ) is true.
*/
void test_coverage_xTaskResumeFromISR_resume_higher_priority_suspended_task( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 1U ] = { NULL };
uint32_t i;
BaseType_t xReturn;
/* Setup the variables and structure. */
vListInitialise( &xSuspendedTaskList );
vListInitialise( &xPendingReadyList );
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = 1;
xTaskTCBs[ i ].xTaskRunState = i;
xYieldPendings[ i ] = pdFALSE;
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
}
/* A suspended task is created to be resumed from ISR. The task has higher priority
* than uxTopReadyPriority and the scheduler is suspended. The task will be added
* to xPendingReadyList after resumed from ISR. */
xTaskTCBs[ configNUMBER_OF_CORES ].uxPriority = 2;
listINSERT_END( &xSuspendedTaskList, &xTaskTCBs[ i ].xStateListItem );
uxTopReadyPriority = 1;
uxSchedulerSuspended = pdTRUE;
/* Expections. */
vFakePortAssertIfInterruptPriorityInvalid_Ignore();
/* API calls. */
xReturn = xTaskResumeFromISR( &xTaskTCBs[ i ] );
/* Validateions. In single priority test, the calling core is requested to yield
* since a higher priority task is resumed. */
TEST_ASSERT( xReturn == pdTRUE );
}
```

View file

@ -0,0 +1,156 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "fake_assert.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* https://www.FreeRTOS.org/a00110.html
*----------------------------------------------------------*/
/* SMP test specific configuration */
#define configRUN_MULTIPLE_PRIORITIES 0
#define configNUMBER_OF_CORES 16
#define configUSE_CORE_AFFINITY 1
#define configUSE_TIME_SLICING 0
#define configUSE_TASK_PREEMPTION_DISABLE 0
#define configTICK_CORE 0
#define configUSE_TICKLESS_IDLE 1
/* OS Configuration */
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configTICK_RATE_HZ ( 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 0
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 )
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1
#define portREMOVE_STATIC_QUALIFIER 1
#define portCRITICAL_NESTING_IN_TCB 1
#define portSTACK_GROWTH ( 1 )
#define configUSE_PASSIVE_IDLE_HOOK 0
#define configKERNEL_PROVIDED_STATIC_MEMORY 1
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 7 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 0
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configENABLE_MPU 0
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* This demo makes use of one or more example stats formatting functions. These
* format the raw data provided by the uxTaskGetSystemState() function in to human
* readable ASCII form. See the notes in the implementation of vTaskList() within
* FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Set the following definitions to 1 to include the API function, or zero
* to exclude the API function. In most cases the linker will remove unused
* functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) \
do \
{ \
if( x ) \
{ \
vFakeAssert( true, __FILE__, __LINE__ ); \
} \
else \
{ \
vFakeAssert( false, __FILE__, __LINE__ ); \
} \
} while( 0 )
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,54 @@
# indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
include ../../makefile.in
# PROJECT_SRC lists the .c files under test
PROJECT_SRC := tasks.c
# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files
# Files in PROJECT_DEPS_SRC are excluded from coverage measurements
#PROJECT_DEPS_SRC :=
# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements.
PROJECT_HEADER_DEPS := FreeRTOS.h
# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c)
SUITE_UT_SRC := config_assert_utest.c
# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases.
# Paths are relative to PROJECT_DIR
#SUITE_SUPPORT_SRC :=
# List the headers used by PROJECT_SRC that you would like to mock
MOCK_FILES_FP += $(KERNEL_DIR)/include/list.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/smp/config_assert/list_macros.h
MOCK_FILES_FP += $(KERNEL_DIR)/include/queue.h
MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/portmacro.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/smp/config_assert/local_portable.h
# List any addiitonal flags needed by the preprocessor
CPPFLAGS += -include list_macros.h
# List any addiitonal flags needed by the compiler
CFLAGS +=
# Try not to edit beyond this line unless necessary.
# Project is determined based on path: $(UT_ROOT_DIR)/$(PROJECT)
PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)/../))))
SUITE := $(lastword $(subst /, ,$(dir $(MAKEFILE_ABSPATH))))
# Make variables available to included makefile
export
include ../../testdir.mk

View file

@ -0,0 +1,671 @@
/*
* FreeRTOS V202212.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 config_assert_utest.c */
/* C runtime includes. */
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
/* Tasks includes */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "../global_vars.h"
#include "task.h"
/* Test includes. */
#include "unity.h"
#include "unity_memory.h"
#include "CException.h"
/* Mock includes. */
#include "mock_timers.h"
#include "mock_list.h"
#include "mock_list_macros.h"
#include "mock_fake_assert.h"
#include "mock_fake_port.h"
#include "mock_local_portable.h"
/* ================================= MACROS =============================== */
/**
* @brief CException code for when a configASSERT should be intercepted.
*/
#define configASSERT_E 0xAA101
/**
* @brief simulate up to 10 tasks: add more if needed
* */
#define TCB_ARRAY 10
/**
* @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 Flag which denotes if test need to abort on assertion.
*/
static BaseType_t shouldAbortOnAssertion;
/* =========================== EXTERN VARIABLES =========================== */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
extern void vTaskExitCriticalFromISR( UBaseType_t xSavedInterruptStatus );
extern void prvCheckForRunStateChange( void );
extern volatile UBaseType_t uxDeletedTasksWaitingCleanUp;
extern volatile BaseType_t xSchedulerRunning;
extern volatile UBaseType_t uxSchedulerSuspended;
extern TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ];
extern volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES ];
extern volatile UBaseType_t uxTopReadyPriority;
extern List_t pxReadyTasksLists[ configMAX_PRIORITIES ];
extern volatile TickType_t xTickCount;
extern volatile TickType_t xNextTaskUnblockTime;
/* ========================== STATIC FUNCTIONS ========================== */
static void vFakeAssertStub( bool x,
char * file,
int line,
int cmock_num_calls )
{
if( !x )
{
assertionFailed++;
if( shouldAbortOnAssertion == pdTRUE )
{
Throw( configASSERT_E );
}
}
}
static void validate_and_clear_assertions( void )
{
TEST_ASSERT_EQUAL( 1, assertionFailed );
assertionFailed = 0;
}
void * pvPortMalloc( size_t xSize )
{
return unity_malloc( xSize );
}
void vPortFree( void * pv )
{
return unity_free( pv );
}
/* ============================ Unity Fixtures ============================ */
/*! called before each testcase */
void setUp( void )
{
vFakeAssert_StubWithCallback( vFakeAssertStub );
}
/*! called after each testcase */
void tearDown( void )
{
}
/*! called at the beginning of the whole suite */
void suiteSetUp()
{
}
/*! called at the end of the whole suite */
int suiteTearDown( int numFailures )
{
return numFailures;
}
/* =============================== Callbacks ============================== */
void port_release_task_lock_cb( int num_calls )
{
pxCurrentTCBs[ 0 ]->xTaskRunState = -1; /* taskTASK_YIELDING */
}
/* ============================== Test Cases ============================== */
/**
* @brief This test ensures that the code asserts when the TCB's critical
* nesting count is less than or equal to zero
*
* <b>Coverage</b>
* @code{c}
* prvYieldForTask( pxTCB );
*
* configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U );
* @endcode
*
* configUSE_PREEMPTION == 1
* configNUMBER_OF_CORES > 1
* configUSE_CORE_AFFINITY == 1
*/
void test_prvYieldForTask_assert_critical_nesting_lteq_zero( void )
{
UBaseType_t uxCoreAffinityMask;
TCB_t currentTCB;
memset( &currentTCB, 0x00, sizeof( TCB_t ) );
pxCurrentTCBs[ 0 ] = &currentTCB;
pxCurrentTCBs[ 0 ]->uxCoreAffinityMask = 1;
pxCurrentTCBs[ 0 ]->uxCriticalNesting = 0;
pxCurrentTCBs[ 0 ]->xTaskRunState = -1; /* taskTASK_NOT_RUNNING */
xSchedulerRunning = pdTRUE;
/* Set the new mask to the last core. */
uxCoreAffinityMask = ( 1 << ( configNUMBER_OF_CORES - 1 ) );
vFakePortEnterCriticalSection_Expect();
vFakePortGetCoreID_ExpectAndReturn( 0 );
EXPECT_ASSERT_BREAK( vTaskCoreAffinitySet( pxCurrentTCBs[ 0 ],
uxCoreAffinityMask ) );
validate_and_clear_assertions();
}
/**
* @brief This test ensures that the code asserts when xYieldPending of the
* current core is false and the task is runing
*
* <b>Coverage</b>
* @code{c}
* prvYieldForTask( pxTCB );
*
* configASSERT( ( xYieldPendings[ portGET_CORE_ID() ] == pdTRUE ) ||
* ( taskTASK_IS_RUNNING( pxCurrentTCBs[ portGET_CORE_ID() ] ) == pdFALSE ) );
* @endcode
*
* configNUMBER_OF_CORES > 1
* configRUN_MULTIPLE_PRIORITIES = 0
* configUSE_TASK_PREEMPTION_DISABLE
*/
void test_prvYieldForTask_assert_yieldpending_core_is_false( void )
{
TCB_t unblockedTCB[ configNUMBER_OF_CORES ] = { 0 };
ListItem_t xEventListItem;
TickType_t xItemValue = 0;
for( int i = 0; i < configNUMBER_OF_CORES; ++i )
{
pxCurrentTCBs[ i ] = &unblockedTCB[ i ];
unblockedTCB[ i ].xTaskRunState = -1; /* taskTASK_YIELDING */
}
unblockedTCB[ 0 ].uxCriticalNesting = 1;
unblockedTCB[ 0 ].xTaskRunState = 0;
unblockedTCB[ 0 ].uxTaskAttributes = 2;
unblockedTCB[ 0 ].uxPriority = 1;
unblockedTCB[ 1 ].uxTaskAttributes = 2;
unblockedTCB[ 1 ].uxPriority = 0;
unblockedTCB[ 1 ].xTaskRunState = 1;
unblockedTCB[ 2 ].xTaskRunState = -1;
unblockedTCB[ 3 ].xTaskRunState = configNUMBER_OF_CORES + 2;
uxSchedulerSuspended = 3;
xYieldPendings[ 1 ] = pdFALSE;
listSET_LIST_ITEM_VALUE_ExpectAnyArgs();
listGET_LIST_ITEM_OWNER_ExpectAnyArgsAndReturn( &unblockedTCB[ 0 ] );
listREMOVE_ITEM_ExpectAnyArgs();
listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE );
listREMOVE_ITEM_ExpectAnyArgs();
/* in prvAddTaskToReadyList */
listINSERT_END_ExpectAnyArgs();
/* back */
/* taskENTER_CRITICAL */
vFakePortEnterCriticalSection_Expect();
/* back */
/* prvYieldForTask */
vFakePortGetCoreID_ExpectAndReturn( 0 );
vFakePortGetCoreID_ExpectAndReturn( 1 );
vFakePortGetCoreID_ExpectAndReturn( 1 );
vFakePortGetCoreID_ExpectAndReturn( 1 );
vFakePortGetCoreID_ExpectAndReturn( 0 );
vFakePortGetCoreID_ExpectAndReturn( 0 );
vFakePortGetCoreID_ExpectAndReturn( 0 );
EXPECT_ASSERT_BREAK( vTaskRemoveFromUnorderedEventList( &xEventListItem,
xItemValue ) );
validate_and_clear_assertions();
}
/**
* @brief This test ensures that the code asserts when we are trying to select
* the highest priority task on a specific core while the scheuler is not
* running
*
* <b>Coverage</b>
* @code{c}
* prvSelectHighestPriorityTask( xCoreID );
*
* configASSERT( xSchedulerRunning == pdTRUE );
*
* @endcode
*
* configNUMBER_OF_CORES > 1
*/
void test_prvSelectHighestPriorityTask_assert_scheduler_running_false( void )
{
TCB_t unblockedTCB[ configNUMBER_OF_CORES ] = { 0 };
unblockedTCB[ 0 ].uxCriticalNesting = 0;
pxCurrentTCBs[ 0 ] = &unblockedTCB[ 0 ];
xSchedulerRunning = pdFALSE; /* causes the assert */
uxSchedulerSuspended = pdFALSE;
vFakePortGetTaskLock_Expect();
vFakePortGetISRLock_Expect();
vFakePortGetCoreID_ExpectAndReturn( 0 );
EXPECT_ASSERT_BREAK( vTaskSwitchContext( 1 ) );
validate_and_clear_assertions();
}
/**
* @brief This test ensures that the code asserts when the coreID is not equal
* to the runstate of the task
*
* <b>Coverage</b>
* @code{c}
* prvSelectHighestPriorityTask( xCoreID );
*
* configASSERT( ( pxTCB->xTaskRunState == xCoreID ) || ( pxTCB->xTaskRunState == taskTASK_YIELDING ) );
*
* @endcode
*
* configNUMBER_OF_CORES > 1
*/
void test_prvSelectHighestPriorityTask_assert_coreid_ne_runstate( void )
{
TCB_t unblockedTCB[ configNUMBER_OF_CORES ] = { 0 };
unblockedTCB[ 0 ].uxCriticalNesting = 0;
unblockedTCB[ 0 ].xTaskRunState = 2; /* causes the assert coreID != runstate */
pxCurrentTCBs[ 0 ] = &unblockedTCB[ 0 ];
xSchedulerRunning = pdTRUE;
uxSchedulerSuspended = pdFALSE;
vFakePortGetTaskLock_Expect();
vFakePortGetISRLock_Expect();
vFakePortGetCoreID_ExpectAndReturn( 0 );
listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE );
listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE );
listGET_LIST_ITEM_OWNER_ExpectAnyArgsAndReturn( &unblockedTCB[ 0 ] );
EXPECT_ASSERT_BREAK( vTaskSwitchContext( 0 ) );
validate_and_clear_assertions();
}
/**
* @brief This test ensures that the code asserts if the scheduler is not
* suspended
*
* <b>Coverage</b>
* @code{c}
* vTaskDelete( xTaskToDelete );
*
* configASSERT( uxSchedulerSuspended == 0 );
* @endcode
*
* configNUMBER_OF_CORES > 1
* INCLUDE_vTaskDelete
*/
void test_vTaskDelete_assert_scheduler_suspended_eq_1( void )
{
TaskHandle_t xTaskToDelete = NULL;
TCB_t * pxTCB = malloc( sizeof( TCB_t ) );
pxTCB->pxStack = malloc( 200 );
pxTCB->xTaskRunState = 1; /* task running on core 1 */
xTaskToDelete = ( TaskHandle_t ) pxTCB;
uxSchedulerSuspended = 1; /* asserts the code */
xSchedulerRunning = pdTRUE;
vFakePortEnterCriticalSection_Expect();
uxListRemove_ExpectAnyArgsAndReturn( pdTRUE );
listLIST_ITEM_CONTAINER_ExpectAnyArgsAndReturn( NULL );
vListInsertEnd_ExpectAnyArgs();
vPortCurrentTaskDying_ExpectAnyArgs();
vFakePortGetCoreID_ExpectAndReturn( 1 );
EXPECT_ASSERT_BREAK( vTaskDelete( xTaskToDelete ) );
validate_and_clear_assertions();
free( pxTCB->pxStack );
free( pxTCB );
}
/**
* @brief This test ensures that the code asserts when a task is suspended while
* the scheduler is suspended
*
* <b>Coverage</b>
* @code{c}
* vTaskDelete( xTaskToDelete );
*
* configASSERT( uxSchedulerSuspended == 0 );
*
* @endcode
*
* configNUMBER_OF_CORES > 1
* INCLUDE_vTaskSuspend
*/
void test_vTaskSuspend_assert_schedulersuspended_ne_zero( void )
{
TaskHandle_t xTaskToSuspend;
TCB_t * pxTCB = malloc( sizeof( TCB_t ) );
xTaskToSuspend = ( TaskHandle_t ) pxTCB;
xSchedulerRunning = pdTRUE;
pxTCB->xTaskRunState = 1;
uxSchedulerSuspended = 1; /* asserts the code */
vFakePortEnterCriticalSection_Expect();
uxListRemove_ExpectAnyArgsAndReturn( pdTRUE );
listLIST_ITEM_CONTAINER_ExpectAnyArgsAndReturn( NULL );
vListInsertEnd_ExpectAnyArgs();
listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE );
vFakePortGetCoreID_ExpectAndReturn( 1 );
EXPECT_ASSERT_BREAK( vTaskSuspend( xTaskToSuspend ) );
validate_and_clear_assertions();
free( pxTCB );
}
/**
* @brief This test ensures that the code asserts when we try to switch
* context with a current task that is holding a
* critical section
*
* <b>Coverage</b>
* @code{c}
* vTaskSwitchContext( xCoreID );
*
* configASSERT( portGET_CRITICAL_NESTING_COUNT() == 0 );
*
* @endcode
*
* configNUMBER_OF_CORES > 1
*/
void test_vTaskSwitchContext_assert_nexting_count_ne_zero( void )
{
TCB_t currentTCB = { 0 };
currentTCB.uxCriticalNesting = 1; /* causes the assert */
pxCurrentTCBs[ 1 ] = &currentTCB;
vFakePortGetTaskLock_Expect();
vFakePortGetISRLock_Expect();
vFakePortGetCoreID_ExpectAndReturn( 1 );
EXPECT_ASSERT_BREAK( vTaskSwitchContext( 1 ) );
validate_and_clear_assertions();
}
/**
* @brief This test ensures that the code asserts when we try to exit a critical
* section while the current tasks critical count is zero
*
* <b>Coverage</b>
* @code{c}
* vTaskExitCritical();
*
* configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U );
*
* @endcode
*
* configNUMBER_OF_CORES > 1
*/
void test_vTaskExitCritical_assert_critical_nesting_eq_zero( void )
{
TCB_t currentTCB = { 0 };
xSchedulerRunning = pdTRUE;
currentTCB.uxCriticalNesting = 0; /* causes the assert */
pxCurrentTCBs[ 1 ] = &currentTCB;
vFakePortGetCoreID_ExpectAndReturn( 1 );
EXPECT_ASSERT_BREAK( vTaskExitCritical() );
validate_and_clear_assertions();
}
/**
* @brief This test ensures that the code asserts when we try to exit a critical
* section while the current tasks critical count is zero
*
* <b>Coverage</b>
* @code{c}
* vTaskExitCriticalFromISR();
*
* configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U );
*
* @endcode
*
* configNUMBER_OF_CORES > 1
*/
void test_vTaskExitCriticalFromISR_assertcritical_nesting_eq_zero( void )
{
TCB_t currentTCB = { 0 };
xSchedulerRunning = pdTRUE;
currentTCB.uxCriticalNesting = 0; /* causes the assert */
pxCurrentTCBs[ 1 ] = &currentTCB;
vFakePortGetCoreID_ExpectAndReturn( 1 );
EXPECT_ASSERT_BREAK( vTaskExitCriticalFromISR( 1 ) );
validate_and_clear_assertions();
}
/**
* @brief This test ensures that the code asserts when the next unblock time is
* less than the xTickCount
*
* <b>Coverage</b>
* @code{c}
* prvIdleTask();
*
* configASSERT( xNextTaskUnblockTime >= xTickCount );
*
* @endcode
*
* configNUMBER_OF_CORES > 1
* configUSE_TICKLESS_IDLE != 0
*/
void test_prvGetExpectedIdleTime_assert_nextUnblock_lt_xTickCount( void )
{
TCB_t xTCB = { 0 };
xTickCount = 250;
xNextTaskUnblockTime = 240; /* expectedidletime = xNextTaskUnblockTime - xTickCount */
pxCurrentTCBs[ 0 ] = &xTCB;
xTCB.uxPriority = tskIDLE_PRIORITY;
/* Test Setup */
uxDeletedTasksWaitingCleanUp = 0;
uxTopReadyPriority = tskIDLE_PRIORITY;
/* Test Expectations */
vFakePortYield_Expect();
listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 0 );
ulFakePortSetInterruptMask_ExpectAndReturn( 0 );
vFakePortGetCoreID_ExpectAndReturn( 0 );
vFakePortClearInterruptMask_Expect( 0 );
listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 0 );
/* vTaskSuspendAll */
vFakePortAssertIfISR_Expect();
ulFakePortSetInterruptMask_ExpectAndReturn( 0 );
vFakePortGetTaskLock_Expect();
vFakePortGetISRLock_Expect();
vFakePortReleaseISRLock_Expect();
vFakePortClearInterruptMask_Expect( 0 );
/* API Call */
portTASK_FUNCTION( prvIdleTask, args );
EXPECT_ASSERT_BREAK( prvIdleTask( NULL ) );
/* Test Verifications */
validate_and_clear_assertions();
}
/**
* @brief vTaskStepTick - assert if scheduler suspended.
*
* <b>Coverage</b>
* @code{c}
* configASSERT( uxSchedulerSuspended );
* @endcode
*/
void test_vTaskStepTick_assert_scheduler_not_suspended( void )
{
TickType_t xTicksToJump;
xTickCount = 230;
xTicksToJump = 10;
xNextTaskUnblockTime = 240;
uxSchedulerSuspended = pdFALSE;
/* API Call */
EXPECT_ASSERT_BREAK( vTaskStepTick( xTicksToJump ) );
/* Test Verifications */
validate_and_clear_assertions();
}
/**
* @brief prvCheckForRunStateChange - task state not changed.
*
* When the task is able to run after calling portENABLE_INTERRUPTS. The task state
* is supposed to be changed to run state. This test cover the assertion of this scenario.
*
* <b>Coverage</b>
* @code{c}
* configASSERT( pxThisTCB->xTaskRunState != taskTASK_YIELDING );
* @endcode
*/
void test_prvCheckForRunStateChange_assert_task_state_not_changed( void )
{
TCB_t xTaskTCB = { NULL };
pxCurrentTCBs[ 0 ] = &xTaskTCB;
xTaskTCB.uxCriticalNesting = 0;
xTaskTCB.xTaskRunState = taskTASK_YIELDING;
uxSchedulerSuspended = 1;
/* Expection. */
vFakePortAssertIfISR_Expect();
vFakePortGetCoreID_ExpectAndReturn( 0 );
vFakePortGetCoreID_ExpectAndReturn( 0 );
vFakePortReleaseTaskLock_Expect();
vFakePortEnableInterrupts_Expect();
/* API Call. */
EXPECT_ASSERT_BREAK( prvCheckForRunStateChange() );
/* Test Verifications */
validate_and_clear_assertions();
}
/**
* @brief vTaskStepTick - assert if scheduler suspended.
*
* <b>Coverage</b>
* @code{c}
* configASSERT( xTicksToJump != ( TickType_t ) 0 );
* @endcode
*/
void test_vTaskStepTick_assert_tick_to_jump_eq_0( void )
{
TickType_t xTicksToJump;
xTickCount = 240;
xTicksToJump = 0;
xNextTaskUnblockTime = 240;
uxSchedulerSuspended = pdTRUE;
/* API Call */
EXPECT_ASSERT_BREAK( vTaskStepTick( xTicksToJump ) );
/* Test Verifications */
validate_and_clear_assertions();
}

View file

@ -0,0 +1,73 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef LIST_MACRO_H
#define LIST_MACRO_H
#include <FreeRTOS.h>
#include <task.h>
#include <portmacro.h>
#include <list.h>
struct tskTaskControlBlock;
#undef listLIST_IS_EMPTY
BaseType_t listLIST_IS_EMPTY( const List_t * pxList );
#undef listGET_OWNER_OF_HEAD_ENTRY
struct tskTaskControlBlock * listGET_OWNER_OF_HEAD_ENTRY( const List_t * pxList );
#undef listIS_CONTAINED_WITHIN
BaseType_t listIS_CONTAINED_WITHIN( List_t * list,
const ListItem_t * listItem );
#undef listGET_LIST_ITEM_VALUE
TickType_t listGET_LIST_ITEM_VALUE( ListItem_t * listItem );
#undef listSET_LIST_ITEM_VALUE
void listSET_LIST_ITEM_VALUE( ListItem_t * listItem,
TickType_t itemValue );
#undef listLIST_ITEM_CONTAINER
List_t * listLIST_ITEM_CONTAINER( const ListItem_t * listItem );
#undef listCURRENT_LIST_LENGTH
UBaseType_t listCURRENT_LIST_LENGTH( List_t * list );
#undef listGET_ITEM_VALUE_OF_HEAD_ENTRY
TickType_t listGET_ITEM_VALUE_OF_HEAD_ENTRY( List_t * list );
#undef listGET_LIST_ITEM_OWNER
struct tskTaskControlBlock * listGET_LIST_ITEM_OWNER( ListItem_t * listItem );
#undef listINSERT_END
void listINSERT_END( List_t * pxList,
ListItem_t * listItem );
#undef listREMOVE_ITEM
void listREMOVE_ITEM( ListItem_t * listItem );
#endif /* ifndef LIST_MACRO_H */

View file

@ -0,0 +1,40 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef LOCAL_PORTABLE_H
#define LOCAL_PORTABLE_H
BaseType_t xPortStartScheduler( void );
void vPortEndScheduler( void );
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters );
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters );
#endif /* ifndef LOCAL_PORTABLE_H */

View file

@ -0,0 +1,148 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef GLOBAL_VARS_H
#define GLOBAL_VARS_H
#include "task.h"
#include <stdbool.h>
/* Indicates that the task is an Idle task. */
#define taskATTRIBUTE_IS_IDLE ( UBaseType_t ) ( 1UL << 0UL )
/*
* Macros used by vListTask to indicate which state a task is in.
*/
#define tskRUNNING_CHAR ( 'X' )
#define tskBLOCKED_CHAR ( 'B' )
#define tskREADY_CHAR ( 'R' )
#define tskDELETED_CHAR ( 'D' )
#define tskSUSPENDED_CHAR ( 'S' )
/* Values that can be assigned to the ucNotifyState member of the TCB. */
#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 ) /* Must be zero as it is the initialised value. */
#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 )
#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 )
/* Indicates that the task is not actively running on any core. */
#define taskTASK_NOT_RUNNING ( TaskRunning_t ) ( -1 )
/* Indicates that the task is actively running but scheduled to yield. */
#define taskTASK_YIELDING ( TaskRunning_t ) ( -2 )
#if ( configUSE_16_BIT_TICKS == 1 )
#define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U
#else
#define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL
#endif
typedef BaseType_t TaskRunning_t;
typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */
{
volatile StackType_t * pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
#endif
#if ( configUSE_CORE_AFFINITY == 1 ) && ( configNUMBER_OF_CORES > 1 )
UBaseType_t uxCoreAffinityMask; /*< Used to link the task to certain cores. UBaseType_t must have greater than or equal to the number of bits as confNUM_CORES. */
#endif
ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
ListItem_t xEventListItem; /*< Used to reference a task from an event list. */
UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */
StackType_t * pxStack; /*< Points to the start of the stack. */
#if ( configNUMBER_OF_CORES > 1 )
volatile TaskRunning_t xTaskRunState; /*< Used to identify the core the task is running on, if the task is running. Otherwise, identifies the task's state - not running or yielding. */
UBaseType_t uxTaskAttributes; /*< Task's attributes - currently used to identify the idle tasks. */
#endif
char pcTaskName[ configMAX_TASK_NAME_LEN ]; /*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
BaseType_t xPreemptionDisable; /*< Used to prevent the task from being preempted. */
#endif
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t * pxEndOfStack; /*< Points to the highest valid address for the stack. */
#endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
#endif
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */
UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
UBaseType_t uxMutexesHeld;
#endif
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
TaskHookFunction_t pxTaskTag;
#endif
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
#if ( configGENERATE_RUN_TIME_STATS == 1 )
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
#endif
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
configTLS_BLOCK_TYPE xTLSBlock; /*< Memory block used as Thread Local Storage (TLS) Block for the task. */
#endif
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
#endif
/* See the comments in FreeRTOS.h with the definition of
* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */
#endif
#if ( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDelayAborted;
#endif
#if ( configUSE_POSIX_ERRNO == 1 )
int iTaskErrno;
#endif
} tskTCB;
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
* below to enable the use of older kernel aware debuggers. */
typedef tskTCB TCB_t;
#endif /* ifndef GLOBAL_VARS_H */

View file

@ -0,0 +1,158 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "fake_assert.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* https://www.FreeRTOS.org/a00110.html
*----------------------------------------------------------*/
/* SMP test specific configuration */
#define configRUN_MULTIPLE_PRIORITIES 1
#define configNUMBER_OF_CORES 16
#define configUSE_CORE_AFFINITY 1
#define configUSE_TIME_SLICING 0
#define configUSE_TASK_PREEMPTION_DISABLE 1
#define configTICK_CORE 0
/* OS Configuration */
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configTICK_RATE_HZ ( 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 )
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1
#define portREMOVE_STATIC_QUALIFIER 1
#define portCRITICAL_NESTING_IN_TCB 1
#define portSTACK_GROWTH ( 1 )
#define configUSE_MINIMAL_IDLE_HOOK 0 /* Keep this for backward compatibility. */
#define configUSE_PASSIVE_IDLE_HOOK 0
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 4
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 7 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 0
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configENABLE_MPU 0
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* This demo makes use of one or more example stats formatting functions. These
* format the raw data provided by the uxTaskGetSystemState() function in to human
* readable ASCII form. See the notes in the implementation of vTaskList() within
* FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/* Set the following definitions to 1 to include the API function, or zero
* to exclude the API function. In most cases the linker will remove unused
* functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) \
do \
{ \
if( x ) \
{ \
vFakeAssert( true, __FILE__, __LINE__ ); \
} \
else \
{ \
vFakeAssert( false, __FILE__, __LINE__ ); \
} \
} while( 0 )
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,47 @@
# indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
include ../../makefile.in
# PROJECT_SRC lists the .c files under test
PROJECT_SRC := tasks.c
# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files
# Files in PROJECT_DEPS_SRC are excluded from coverage measurements
PROJECT_DEPS_SRC := list.c queue.c
# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements.
PROJECT_HEADER_DEPS := FreeRTOS.h
# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c)
SUITE_UT_SRC := multiple_priorities_no_timeslice_utest.c covg_multiple_priorities_no_timeslice_utest.c
# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases.
# Paths are relative to PROJECT_DIR
SUITE_SUPPORT_SRC := smp_utest_common.c
# List the headers used by PROJECT_SRC that you would like to mock
MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h
# List any addiitonal flags needed by the preprocessor
CPPFLAGS +=
# List any addiitonal flags needed by the compiler
CFLAGS +=
# Try not to edit beyond this line unless necessary.
# Project is determined based on path: $(UT_ROOT_DIR)/$(PROJECT)
PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)/../))))
SUITE := $(lastword $(subst /, ,$(dir $(MAKEFILE_ABSPATH))))
# Make variables available to included makefile
export
include ../../testdir.mk

View file

@ -0,0 +1,161 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "fake_assert.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* https://www.FreeRTOS.org/a00110.html
*----------------------------------------------------------*/
/* SMP test specific configuration */
#define configRUN_MULTIPLE_PRIORITIES 1
#define configNUMBER_OF_CORES 16
#define configUSE_CORE_AFFINITY 1
#define configUSE_TIME_SLICING 0
#define configUSE_TASK_PREEMPTION_DISABLE 1
#define configTICK_CORE 0
#define configUSE_TICKLESS_IDLE 1
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
/* OS Configuration */
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configTICK_RATE_HZ ( 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 0
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 )
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1
#define portREMOVE_STATIC_QUALIFIER 1
#define portCRITICAL_NESTING_IN_TCB 1
#define portSTACK_GROWTH ( 1 )
#define configUSE_PASSIVE_IDLE_HOOK 1
#define configKERNEL_PROVIDED_STATIC_MEMORY 1
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
extern const char * pcIdleTaskName;
#define configIDLE_TASK_NAME pcIdleTaskName
#define configMAX_PRIORITIES ( 7 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 0
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configENABLE_MPU 0
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* This demo makes use of one or more example stats formatting functions. These
* format the raw data provided by the uxTaskGetSystemState() function in to human
* readable ASCII form. See the notes in the implementation of vTaskList() within
* FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/* Set the following definitions to 1 to include the API function, or zero
* to exclude the API function. In most cases the linker will remove unused
* functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) \
do \
{ \
if( x ) \
{ \
vFakeAssert( true, __FILE__, __LINE__ ); \
} \
else \
{ \
vFakeAssert( false, __FILE__, __LINE__ ); \
} \
} while( 0 )
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
#define portSUPPRESS_TICKS_AND_SLEEP vPortSuppressTicksAndSleep
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,51 @@
# indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
include ../../makefile.in
# PROJECT_SRC lists the .c files under test
PROJECT_SRC := tasks.c
# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files
# Files in PROJECT_DEPS_SRC are excluded from coverage measurements
#PROJECT_DEPS_SRC :=
# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements.
PROJECT_HEADER_DEPS := FreeRTOS.h
# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c)
SUITE_UT_SRC := covg_multiple_priorities_no_timeslice_mock_utest.c
# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases.
# Paths are relative to PROJECT_DIR
#SUITE_SUPPORT_SRC :=
# List the headers used by PROJECT_SRC that you would like to mock
MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h
MOCK_FILES_FP += $(KERNEL_DIR)/include/list.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/smp/multiple_priorities_no_timeslice_mock/list_macros.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/smp/multiple_priorities_no_timeslice_mock/local_portable.h
# List any addiitonal flags needed by the preprocessor
CPPFLAGS += -include list_macros.h
# List any addiitonal flags needed by the compiler
CFLAGS +=
# Try not to edit beyond this line unless necessary.
# Project is determined based on path: $(UT_ROOT_DIR)/$(PROJECT)
PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)/../))))
SUITE := $(lastword $(subst /, ,$(dir $(MAKEFILE_ABSPATH))))
# Make variables available to included makefile
export
include ../../testdir.mk

View file

@ -0,0 +1,74 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef LIST_MACRO_H
#define LIST_MACRO_H
#include <FreeRTOS.h>
#include <task.h>
#include <portmacro.h>
#include <list.h>
struct tskTaskControlBlock;
#undef listLIST_IS_EMPTY
BaseType_t listLIST_IS_EMPTY( const List_t * pxList );
#undef listGET_OWNER_OF_HEAD_ENTRY
struct tskTaskControlBlock * listGET_OWNER_OF_HEAD_ENTRY( const List_t * pxList );
#undef listIS_CONTAINED_WITHIN
BaseType_t listIS_CONTAINED_WITHIN( List_t * list,
const ListItem_t * listItem );
#undef listGET_LIST_ITEM_VALUE
TickType_t listGET_LIST_ITEM_VALUE( ListItem_t * listItem );
#undef listSET_LIST_ITEM_VALUE
void listSET_LIST_ITEM_VALUE( ListItem_t * listItem,
TickType_t itemValue );
#undef listLIST_ITEM_CONTAINER
List_t * listLIST_ITEM_CONTAINER( const ListItem_t * listItem );
#undef listCURRENT_LIST_LENGTH
UBaseType_t listCURRENT_LIST_LENGTH( List_t * list );
#undef listGET_ITEM_VALUE_OF_HEAD_ENTRY
TickType_t listGET_ITEM_VALUE_OF_HEAD_ENTRY( List_t * list );
#undef listGET_LIST_ITEM_OWNER
struct tskTaskControlBlock * listGET_LIST_ITEM_OWNER( ListItem_t * listItem );
#undef listINSERT_END
void listINSERT_END( List_t * pxList,
ListItem_t * listItem );
#undef listREMOVE_ITEM
void listREMOVE_ITEM( ListItem_t * listItem );
#endif /* ifndef LIST_MACRO_H */

View file

@ -0,0 +1,37 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef LOCAL_PORTABLE_H
#define LOCAL_PORTABLE_H
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters );
BaseType_t xPortStartScheduler( void );
void vPortEndScheduler( void );
#endif /* LOCAL_PORTABLE_H */

View file

@ -0,0 +1,156 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "fake_assert.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* https://www.FreeRTOS.org/a00110.html
*----------------------------------------------------------*/
/* SMP test specific configuration */
#define configRUN_MULTIPLE_PRIORITIES 1
#define configNUMBER_OF_CORES 16
#define configUSE_CORE_AFFINITY 1
#define configUSE_TIME_SLICING 1
#define configUSE_TASK_PREEMPTION_DISABLE 1
#define configTICK_CORE 0
/* OS Configuration */
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configTICK_RATE_HZ ( 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 )
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1
#define portREMOVE_STATIC_QUALIFIER 1
#define portCRITICAL_NESTING_IN_TCB 1
#define portSTACK_GROWTH ( 1 )
#define configUSE_PASSIVE_IDLE_HOOK 0
#define configKERNEL_PROVIDED_STATIC_MEMORY 1
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 7 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 0
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configENABLE_MPU 0
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* This demo makes use of one or more example stats formatting functions. These
* format the raw data provided by the uxTaskGetSystemState() function in to human
* readable ASCII form. See the notes in the implementation of vTaskList() within
* FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/* Set the following definitions to 1 to include the API function, or zero
* to exclude the API function. In most cases the linker will remove unused
* functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) \
do \
{ \
if( x ) \
{ \
vFakeAssert( true, __FILE__, __LINE__ ); \
} \
else \
{ \
vFakeAssert( false, __FILE__, __LINE__ ); \
} \
} while( 0 )
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,47 @@
# indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
include ../../makefile.in
# PROJECT_SRC lists the .c files under test
PROJECT_SRC := tasks.c
# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files
# Files in PROJECT_DEPS_SRC are excluded from coverage measurements
PROJECT_DEPS_SRC := list.c queue.c
# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements.
PROJECT_HEADER_DEPS := FreeRTOS.h
# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c)
SUITE_UT_SRC := multiple_priorities_timeslice_utest.c covg_multiple_priorities_timeslice_utest.c
# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases.
# Paths are relative to PROJECT_DIR
SUITE_SUPPORT_SRC := smp_utest_common.c
# List the headers used by PROJECT_SRC that you would like to mock
MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h
# List any addiitonal flags needed by the preprocessor
CPPFLAGS +=
# List any addiitonal flags needed by the compiler
CFLAGS +=
# Try not to edit beyond this line unless necessary.
# Project is determined based on path: $(UT_ROOT_DIR)/$(PROJECT)
PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)/../))))
SUITE := $(lastword $(subst /, ,$(dir $(MAKEFILE_ABSPATH))))
# Make variables available to included makefile
export
include ../../testdir.mk

View file

@ -0,0 +1,405 @@
/*
* FreeRTOS V202212.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 covg_multiple_priority_timeslice_utest.c */
/* C runtime includes. */
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
/* Task includes */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "event_groups.h"
#include "queue.h"
/* Test includes. */
#include "unity.h"
#include "unity_memory.h"
#include "../global_vars.h"
#include "../smp_utest_common.h"
/* Mock includes. */
#include "mock_timers.h"
#include "mock_fake_assert.h"
#include "mock_fake_port.h"
/* =========================== EXTERN VARIABLES =========================== */
extern volatile UBaseType_t uxDeletedTasksWaitingCleanUp;
extern volatile TCB_t * pxCurrentTCBs[ configNUMBER_OF_CORES ];
extern UBaseType_t uxTopReadyPriority;
extern List_t pxReadyTasksLists[ configMAX_PRIORITIES ];
extern List_t xDelayedTaskList1;
extern List_t * pxDelayedTaskList;
extern UBaseType_t uxSchedulerSuspended;
extern BaseType_t xTickCount;
extern BaseType_t xNextTaskUnblockTime;
extern BaseType_t xYieldPendings[ configNUMBER_OF_CORES ];
/* =========================== EXTERN FUNCTIONS =========================== */
extern void prvIdleTask( void );
extern void prvPassiveIdleTask( void );
extern BaseType_t xTaskIncrementTick( void );
/* ============================ Unity Fixtures ============================ */
/*! called before each testcase */
void setUp( void )
{
commonSetUp();
}
/*! called after each testcase */
void tearDown( void )
{
commonTearDown();
}
/*! called at the beginning of the whole suite */
void suiteSetUp()
{
}
/*! called at the end of the whole suite */
int suiteTearDown( int numFailures )
{
return numFailures;
}
/* ============================== Test Cases ============================== */
/**
* @brief xTaskIncrementTick - no equal priority task for time slice.
*
* No equal priority ready task when incrementing tick. Verify that the return value
* indicates switching is not required.
*
* <b>Coverage</b>
* @code{c}
* for( x = ( ( UBaseType_t ) 0 ); x < ( ( UBaseType_t ) configNUMBER_OF_CORES ); x++ )
* {
* if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCBs[ x ]->uxPriority ] ) ) > ( UBaseType_t ) 1 )
* {
* xYieldRequiredForCore[ x ] = pdTRUE;
* }
* else
* {
* mtCOVERAGE_TEST_MARKER();
* }
* }
* @endcode
* ( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCBs[ x ]->uxPriority ] ) ) > ( UBaseType_t ) 1 ) is false.
*/
void test_coverage_xTaskIncrementTick_no_eq_priority_task( void )
{
BaseType_t xReturn;
TCB_t xTaskTCBs[ configNUMBER_OF_CORES ] = { NULL };
TCB_t xTaskTCB = { NULL };
uint32_t i;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to idle priority. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY + 1;
uxSchedulerSuspended = pdFALSE;
xTickCount = 0;
xNextTaskUnblockTime = 0;
vListInitialise( &xDelayedTaskList1 );
pxDelayedTaskList = &xDelayedTaskList1;
/* Create idle tasks and add it into the ready list. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = tskIDLE_PRIORITY;
xTaskTCBs[ i ].xStateListItem.pvOwner = &xTaskTCBs[ i ];
xTaskTCBs[ i ].uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xTaskRunState = i;
xTaskTCBs[ i ].xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCBs[ i ].uxTaskAttributes = taskATTRIBUTE_IS_IDLE;
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Create one more higher priority task to run on core 0. */
xTaskTCBs[ 0 ].xTaskRunState = taskTASK_NOT_RUNNING;
xTaskTCB.uxPriority = tskIDLE_PRIORITY + 1;
xTaskTCB.xStateListItem.pvOwner = &xTaskTCB;
xTaskTCB.uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ 0 ] = &xTaskTCB;
xTaskTCB.xTaskRunState = 0;
xTaskTCB.xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ];
xTaskTCB.uxTaskAttributes = 0;
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ], &xTaskTCB.xStateListItem );
/* API calls. */
xReturn = xTaskIncrementTick();
/* Validations. */
/* Core 0 is running a higher priority task. No other task of equal priority is
* waiting to run. Switching is not required in this test. */
TEST_ASSERT_EQUAL( pdFALSE, xReturn );
TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime );
}
/**
* @brief xTaskIncrementTick - current core has yield pending.
*
* No equal priority ready task when incrementing tick. However, the current core
* has yield pending. Verify that the return value indicates switching is required.
*
* <b>Coverage</b>
* @code{c}
* if( ( xYieldRequiredForCore[ x ] != pdFALSE ) || ( xYieldPendings[ x ] != pdFALSE ) )
* {
* if( x == ( UBaseType_t ) xCoreID )
* {
* xSwitchRequired = pdTRUE;
* }
* else
* {
* prvYieldCore( x );
* }
* }
* @endcode
* ( xYieldRequiredForCore[ x ] != pdFALSE ) is false.
* ( xYieldPendings[ x ] != pdFALSE ) is true.
* ( x == ( UBaseType_t ) xCoreID ) is true.
*/
void test_coverage_xTaskIncrementTick_no_eq_priority_task_yield_pending( void )
{
BaseType_t xReturn;
TCB_t xTaskTCBs[ configNUMBER_OF_CORES ] = { NULL };
TCB_t xTaskTCB = { NULL };
uint32_t i;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to idle priority. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY + 1;
uxSchedulerSuspended = pdFALSE;
xTickCount = 0;
xNextTaskUnblockTime = 0;
vListInitialise( &xDelayedTaskList1 );
pxDelayedTaskList = &xDelayedTaskList1;
/* Create idle tasks and add it into the ready list. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = tskIDLE_PRIORITY;
xTaskTCBs[ i ].xStateListItem.pvOwner = &xTaskTCBs[ i ];
xTaskTCBs[ i ].uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xTaskRunState = i;
xTaskTCBs[ i ].xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCBs[ i ].uxTaskAttributes = taskATTRIBUTE_IS_IDLE;
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Create one more higher priority task to run on core 0. */
xTaskTCBs[ 0 ].xTaskRunState = taskTASK_NOT_RUNNING;
xTaskTCB.uxPriority = tskIDLE_PRIORITY + 1;
xTaskTCB.xStateListItem.pvOwner = &xTaskTCB;
xTaskTCB.uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ 0 ] = &xTaskTCB;
xYieldPendings[ 0 ] = pdTRUE;
xTaskTCB.xTaskRunState = 0;
xTaskTCB.xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ];
xTaskTCB.uxTaskAttributes = 0;
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ], &xTaskTCB.xStateListItem );
/* API calls. */
xReturn = xTaskIncrementTick();
/* Validations. */
/* Core 0 is running a higher priority task. No other task of equal priority is
* waiting to run. However, core 0 has yield pending. Switching is required for
* core 0. */
TEST_ASSERT_EQUAL( pdTRUE, xReturn );
TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime );
}
/**
* @brief xTaskIncrementTick - task with preemption disabled.
*
* The running task has preemption disabled. Verify the return value indicates switching
* is not required.
*
* <b>Coverage</b>
* @code{c}
* for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configNUMBER_OF_CORES; x++ )
* {
* #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
* if( pxCurrentTCBs[ x ]->xPreemptionDisable == pdFALSE )
* #endif
* {
* ....
* }
* ...
* }
* @endcode
* ( pxCurrentTCBs[ x ]->xPreemptionDisable == pdFALSE ) is false.
*/
void test_coverage_xTaskIncrementTick_preemption_disabled_task( void )
{
BaseType_t xReturn;
TCB_t xTaskTCBs[ configNUMBER_OF_CORES ] = { NULL };
TCB_t xTaskTCB = { NULL };
uint32_t i;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to idle priority. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY;
uxSchedulerSuspended = pdFALSE;
xTickCount = 0;
xNextTaskUnblockTime = 0;
vListInitialise( &xDelayedTaskList1 );
pxDelayedTaskList = &xDelayedTaskList1;
/* Create idle tasks and add it into the ready list. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = tskIDLE_PRIORITY;
xTaskTCBs[ i ].xStateListItem.pvOwner = &xTaskTCBs[ i ];
xTaskTCBs[ i ].uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xTaskRunState = i;
xTaskTCBs[ i ].xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCBs[ i ].uxTaskAttributes = taskATTRIBUTE_IS_IDLE;
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Create one more task with preemption disabled to run on core 0. */
xTaskTCBs[ 0 ].xTaskRunState = taskTASK_NOT_RUNNING;
xTaskTCB.uxPriority = tskIDLE_PRIORITY;
xTaskTCB.xStateListItem.pvOwner = &xTaskTCB;
xTaskTCB.uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ 0 ] = &xTaskTCB;
xTaskTCB.xTaskRunState = 0;
xTaskTCB.xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCB.uxTaskAttributes = 0;
xTaskTCB.xPreemptionDisable = pdTRUE;
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCB.xStateListItem );
/* API calls. */
xReturn = xTaskIncrementTick();
/* Validations. */
/* Equal priority task is waiting to run. Preemption is disabled for task running
* on core 0. Switching is not required in this test. */
TEST_ASSERT_EQUAL( pdFALSE, xReturn );
TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime );
}
/**
* @brief xTaskIncrementTick - ready higher priority delayed task.
*
* Verify that the core is yielding when ready a higher priority delayed ready task.
*
* <b>Coverage</b>
* @code{c}
* prvAddTaskToReadyList( pxTCB );
* ...
* #if ( configUSE_PREEMPTION == 1 )
* {
* ...
* #if ( configNUMBER_OF_CORES == 1 )
* {
* ...
* }
* #else
* {
* prvYieldForTask( pxTCB );
* }
* #endif
* }
* #endif
* @endcode
* prvYieldForTask( pxTCB ) is covered.
*/
void test_coverage_xTaskIncrementTick_ready_higher_priority_delayed_task( void )
{
BaseType_t xReturn;
TCB_t xTaskTCBs[ configNUMBER_OF_CORES ] = { NULL };
TCB_t xTaskTCB = { NULL };
List_t xEventList = { 0 };
uint32_t i;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to idle priority. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ] ) );
vListInitialise( &xEventList );
uxTopReadyPriority = tskIDLE_PRIORITY;
uxSchedulerSuspended = pdFALSE;
xTickCount = 0;
xNextTaskUnblockTime = 0;
vListInitialise( &xDelayedTaskList1 );
pxDelayedTaskList = &xDelayedTaskList1;
/* Create idle tasks and add it into the ready list. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = tskIDLE_PRIORITY;
xTaskTCBs[ i ].xStateListItem.pvOwner = &xTaskTCBs[ i ];
xTaskTCBs[ i ].uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xTaskRunState = i;
xTaskTCBs[ i ].xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCBs[ i ].uxTaskAttributes = taskATTRIBUTE_IS_IDLE;
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Create one more higher priority task to run on core 0. */
xTaskTCB.uxPriority = tskIDLE_PRIORITY + 1;
xTaskTCB.xStateListItem.pvOwner = &xTaskTCB;
xTaskTCB.uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
xTaskTCB.xTaskRunState = 0;
xTaskTCB.xStateListItem.pxContainer = pxDelayedTaskList;
xTaskTCB.uxTaskAttributes = 0;
xTaskTCB.xPreemptionDisable = pdTRUE;
listINSERT_END( pxDelayedTaskList, &xTaskTCB.xStateListItem );
xTaskTCB.xEventListItem.pvOwner = &xTaskTCB;
xTaskTCB.xEventListItem.pxContainer = &xEventList;
listINSERT_END( &xEventList, &xTaskTCB.xEventListItem );
/* API calls. */
xReturn = xTaskIncrementTick();
/* Validations. */
/* Core 0 is running a idle priority task. Switching is required in this test. */
TEST_ASSERT_EQUAL( pdTRUE, xReturn );
/* The implementation will select the last core to yield for the higher priority
* task. Verify that the task running on the last core has state taskTASK_YIELDING. */
TEST_ASSERT_EQUAL( taskTASK_YIELDING, xTaskTCBs[ configNUMBER_OF_CORES - 1 ].xTaskRunState );
TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime );
}

View file

@ -0,0 +1,155 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "fake_assert.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* https://www.FreeRTOS.org/a00110.html
*----------------------------------------------------------*/
/* SMP test specific configuration */
#define configRUN_MULTIPLE_PRIORITIES 0
#define configNUMBER_OF_CORES 16
#define configUSE_CORE_AFFINITY 0
#define configUSE_TIME_SLICING 0
#define configUSE_TASK_PREEMPTION_DISABLE 0
#define configTICK_CORE 0
/* OS Configuration */
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configTICK_RATE_HZ ( 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 0
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 )
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1
#define portREMOVE_STATIC_QUALIFIER 1
#define portCRITICAL_NESTING_IN_TCB 1
#define portSTACK_GROWTH ( 1 )
#define configUSE_PASSIVE_IDLE_HOOK 0
#define configUSE_TICKLESS_IDLE 1
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 7 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 0
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configENABLE_MPU 0
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* This demo makes use of one or more example stats formatting functions. These
* format the raw data provided by the uxTaskGetSystemState() function in to human
* readable ASCII form. See the notes in the implementation of vTaskList() within
* FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/* Set the following definitions to 1 to include the API function, or zero
* to exclude the API function. In most cases the linker will remove unused
* functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) \
do \
{ \
if( x ) \
{ \
vFakeAssert( true, __FILE__, __LINE__ ); \
} \
else \
{ \
vFakeAssert( false, __FILE__, __LINE__ ); \
} \
} while( 0 )
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,45 @@
# indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
include ../../makefile.in
# PROJECT_SRC lists the .c files under test
PROJECT_SRC := tasks.c
# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files
# Files in PROJECT_DEPS_SRC are excluded from coverage measurements
PROJECT_DEPS_SRC := list.c queue.c
# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements.
PROJECT_HEADER_DEPS := FreeRTOS.h
# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c)
SUITE_UT_SRC := single_priority_no_timeslice_utest.c covg_single_priority_no_timeslice_utest.c
# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases.
# Paths are relative to PROJECT_DIR
SUITE_SUPPORT_SRC := smp_utest_common.c
# List the headers used by PROJECT_SRC that you would like to mock
MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h
# List any addiitonal flags needed by the preprocessor
CPPFLAGS +=
# List any addiitonal flags needed by the compiler
CFLAGS +=
# Try not to edit beyond this line unless necessary.
# Project is determined based on path: $(UT_ROOT_DIR)/$(PROJECT)
PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)/../))))
SUITE := $(lastword $(subst /, ,$(dir $(MAKEFILE_ABSPATH))))
# Make variables available to included makefile
export
include ../../testdir.mk

View file

@ -0,0 +1,452 @@
/*
* FreeRTOS V202212.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 single_priority_no_timeslice_covg_utest */
/* C runtime includes. */
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
/* Task includes */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "event_groups.h"
#include "queue.h"
/* Test includes. */
#include "unity.h"
#include "unity_memory.h"
#include "../global_vars.h"
#include "../smp_utest_common.h"
/* Mock includes. */
#include "mock_timers.h"
#include "mock_fake_assert.h"
#include "mock_fake_port.h"
#define MAX_TASKS 3
/* =========================== EXTERN FUNCTIONS =========================== */
extern void prvCheckForRunStateChange( void );
/* =========================== EXTERN VARIABLES =========================== */
extern volatile UBaseType_t uxDeletedTasksWaitingCleanUp;
extern volatile UBaseType_t uxSchedulerSuspended;
extern volatile TCB_t * pxCurrentTCBs[ configNUMBER_OF_CORES ];
extern List_t xSuspendedTaskList;
extern List_t xPendingReadyList;
extern volatile UBaseType_t uxTopReadyPriority;
extern volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES ];
extern volatile TickType_t xNextTaskUnblockTime;
extern volatile TickType_t xTickCount;
extern TickType_t xPendedTicks;
/* ============================ Unity Fixtures ============================ */
/*! called before each testcase */
void setUp( void )
{
commonSetUp();
}
/*! called after each testcase */
void tearDown( void )
{
commonTearDown();
}
/*! called at the beginning of the whole suite */
void suiteSetUp()
{
}
/*! called at the end of the whole suite */
int suiteTearDown( int numFailures )
{
return numFailures;
}
/* ============================== Helper functions for Test Cases ============================== */
void created_task( void * arg )
{
while( 1 )
{
vTaskDelay( 100 );
}
}
static void prvPortEnableInterruptsCb( int cmock_num_calls )
{
( void ) cmock_num_calls;
pxCurrentTCBs[ 0 ]->xTaskRunState = 0;
}
/* ============================== Test Cases ============================== */
/**
* @brief prvCheckForRunStateChange - first time enter critical section.
*
* Check for run state when entering the critical section for the first time. Verify
* that the task is of running state when exiting this function.
*
* <b>Coverage</b>
* @code{c}
* if( uxPrevCriticalNesting == 0U )
* {
* configASSERT( uxPrevSchedulerSuspended != ( UBaseType_t ) pdFALSE );
* portRELEASE_ISR_LOCK();
* }
* @endcode
* ( uxPrevCriticalNesting == 0U ) is false.
*/
void test_coverage_prvCheckForRunStateChange_first_time_critical_section( void )
{
TCB_t xTaskTCB = { NULL };
pxCurrentTCBs[ 0 ] = &xTaskTCB;
xTaskTCB.uxCriticalNesting = 1;
xTaskTCB.xTaskRunState = taskTASK_YIELDING;
uxSchedulerSuspended = 0;
/* Clear callback in commonSetUp. */
vFakePortCheckIfInISR_StopIgnore();
vFakePortEnableInterrupts_StopIgnore();
vFakePortGetISRLock_StubWithCallback( NULL );
vFakePortGetTaskLock_StubWithCallback( NULL );
vFakePortReleaseISRLock_StubWithCallback( NULL );
vFakePortReleaseTaskLock_StubWithCallback( NULL );
/* Expection. */
vFakePortEnableInterrupts_StubWithCallback( prvPortEnableInterruptsCb );
vFakePortReleaseISRLock_Expect();
vFakePortReleaseTaskLock_Expect();
vFakePortGetTaskLock_Expect();
vFakePortGetISRLock_Expect();
/* API Call. */
prvCheckForRunStateChange();
/* Validation. */
/* Critical nesting count is set correctly. */
TEST_ASSERT_EQUAL( 1, xTaskTCB.uxCriticalNesting );
/* Task is of running state now. */
TEST_ASSERT_EQUAL( 0, xTaskTCB.xTaskRunState );
}
/**
* @brief prvCheckForRunStateChange - first time suspend scheduler.
*
* Check for run state when suspending the scheduler for the first time. Verify
* that the task is of running state when exiting this function.
*
* <b>Coverage</b>
* @code{c}
* if( uxPrevCriticalNesting == 0U )
* {
* configASSERT( uxPrevSchedulerSuspended != ( UBaseType_t ) pdFALSE );
* portRELEASE_ISR_LOCK();
* }
* @endcode
* ( uxPrevCriticalNesting == 0U ) is true.
*/
void test_coverage_prvCheckForRunStateChange_first_time_suspend_scheduler( void )
{
TCB_t xTaskTCB = { NULL };
pxCurrentTCBs[ 0 ] = &xTaskTCB;
xTaskTCB.uxCriticalNesting = 0;
xTaskTCB.xTaskRunState = taskTASK_YIELDING;
uxSchedulerSuspended = 0;
/* Clear callback in commonSetUp. */
vFakePortCheckIfInISR_StopIgnore();
vFakePortEnableInterrupts_StopIgnore();
vFakePortGetTaskLock_StubWithCallback( NULL );
vFakePortReleaseTaskLock_StubWithCallback( NULL );
/* Expection. */
vFakePortEnableInterrupts_StubWithCallback( prvPortEnableInterruptsCb );
vFakePortReleaseTaskLock_Expect();
vFakePortGetTaskLock_Expect();
vFakePortGetISRLock_Expect();
vFakePortReleaseISRLock_Expect();
/* API Call. */
prvCheckForRunStateChange();
/* Validation. */
/* Critical nesting count is set correctly. */
TEST_ASSERT_EQUAL( 0, uxSchedulerSuspended );
/* Task is of running state now. */
TEST_ASSERT_EQUAL( 0, xTaskTCB.xTaskRunState );
}
/*
* The kernel will be configured as follows:
#define configNUMBER_OF_CORES (N > 1)
#define configUSE_CORE_AFFINITY 1
* Coverage for
* static TickType_t prvGetExpectedIdleTime( void )
*/
/*
* Coverage for: UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* const UBaseType_t uxArraySize,
* configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime )
*/
void test_task_get_system_state( void )
{
TaskStatus_t * tsk_status_array;
TaskHandle_t created_handles[ 3 ];
tsk_status_array = calloc( MAX_TASKS, sizeof( TaskStatus_t ) );
for( int i = 0; i < 3; i++ )
{
xTaskCreate( created_task, "Created Task", configMINIMAL_STACK_SIZE, NULL, 1, &created_handles[ i ] );
}
/*Get System states */
int no_of_tasks = uxTaskGetSystemState( tsk_status_array, MAX_TASKS, NULL );
TEST_ASSERT( ( no_of_tasks > 0 ) && ( no_of_tasks <= MAX_TASKS ) );
}
/*
* Coverage for: UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* const UBaseType_t uxArraySize,
* configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime )
*/
void test_task_get_system_state_custom_time( void )
{
TaskStatus_t * tsk_status_array;
TaskHandle_t created_handles[ 3 ];
uint32_t ulTotalRunTime = ( uint32_t ) 200; /* Custom time value */
tsk_status_array = calloc( MAX_TASKS, sizeof( TaskStatus_t ) );
for( int i = 0; i < 3; i++ )
{
xTaskCreate( created_task, "Created Task", configMINIMAL_STACK_SIZE, NULL, 1, &created_handles[ i ] );
}
/*Get System states */
int no_of_tasks = uxTaskGetSystemState( tsk_status_array, MAX_TASKS, &ulTotalRunTime );
TEST_ASSERT( ( no_of_tasks > 0 ) && ( no_of_tasks <= MAX_TASKS ) );
}
/*
* Coverage for: UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* const UBaseType_t uxArraySize,
* configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime )
*/
void test_task_get_system_state_unavilable_task_space( void )
{
TaskStatus_t * tsk_status_array;
TaskHandle_t created_handles[ 3 ];
tsk_status_array = calloc( MAX_TASKS, sizeof( TaskStatus_t ) );
for( int i = 0; i < 3; i++ )
{
xTaskCreate( created_task, "Created Task", configMINIMAL_STACK_SIZE, NULL, 1, &created_handles[ i ] );
}
/*Get System states */
int no_of_tasks = uxTaskGetSystemState( tsk_status_array, MAX_TASKS - 1, NULL );
TEST_ASSERT( ( no_of_tasks == 0 ) && ( no_of_tasks <= MAX_TASKS ) );
}
/**
* @brief vTaskStepTick - step ticks to next task unblock time.
*
* Step ticks to next task unblock time to increase xPendedTicks. Verify that xTickCount
* and xPendedTicks are increased accordingly.
*
* <b>Coverage</b>
* @code{c}
* if( ( xTickCount + xTicksToJump ) == xNextTaskUnblockTime )
* {
* ...
* taskENTER_CRITICAL();
* {
* xPendedTicks++;
* }
* taskEXIT_CRITICAL();
* xTicksToJump--;
* }
* @endcode
* ( ( xTickCount + xTicksToJump ) == xNextTaskUnblockTime ) is true.
*/
void test_coverage_vTaskStepTick_eq_task_unblock_time( void )
{
TickType_t xTicksToJump;
/* Setup the variables and structure. */
xPendedTicks = 0;
xTickCount = 10;
xTicksToJump = 10;
uxSchedulerSuspended = pdTRUE;
xNextTaskUnblockTime = 20;
/* Clear callback in commonSetUp. */
vFakePortEnterCriticalSection_StubWithCallback( NULL );
vFakePortExitCriticalSection_StubWithCallback( NULL );
/* Expections. */
vFakePortEnterCriticalSection_Expect();
vFakePortExitCriticalSection_Expect();
/* API call. */
vTaskStepTick( xTicksToJump );
/* Validations. */
/* xTickCount is set to one tick before xNextUnblockTime. */
TEST_ASSERT_EQUAL( 19, xTickCount );
/* xPendedTicks is increased. */
TEST_ASSERT_EQUAL( 1, xPendedTicks );
}
/**
* @brief xTaskResumeFromISR - resume higher priority suspended task
*
* This test resume a higher priority task from ISR when scheduler suspended. The
* return value of xTaskResumeFromISR indicates yield required for the core calling
* this API.
*
* <b>Coverage</b>
* @code{c}
* #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_PREEMPTION == 1 ) )
* {
* prvYieldForTask( pxTCB );
*
* if( xYieldPendings[ portGET_CORE_ID() ] != pdFALSE )
* {
* xYieldRequired = pdTRUE;
* }
* }
* #endif
* @endcode
* ( xYieldPendings[ portGET_CORE_ID() ] != pdFALSE ) is true.
*/
void test_coverage_xTaskResumeFromISR_resume_higher_priority_suspended_task( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 1U ] = { NULL };
uint32_t i;
BaseType_t xReturn;
/* Setup the variables and structure. */
vListInitialise( &xSuspendedTaskList );
vListInitialise( &xPendingReadyList );
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = 1;
xTaskTCBs[ i ].xTaskRunState = i;
xYieldPendings[ i ] = pdFALSE;
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
}
/* A suspended task is created to be resumed from ISR. The task has higher priority
* than uxTopReadyPriority and the scheduler is suspended. The task will be added
* to xPendingReadyList after resumed from ISR. */
xTaskTCBs[ configNUMBER_OF_CORES ].uxPriority = 2;
listINSERT_END( &xSuspendedTaskList, &xTaskTCBs[ i ].xStateListItem );
uxTopReadyPriority = 1;
uxSchedulerSuspended = pdTRUE;
/* Expections. */
vFakePortAssertIfInterruptPriorityInvalid_Ignore();
/* API calls. */
xReturn = xTaskResumeFromISR( &xTaskTCBs[ i ] );
/* Validations. In single priority test, the calling core is requested to yield
* since a higher priority task is resumed. */
TEST_ASSERT( xReturn == pdTRUE );
}
/**
* @brief xTaskResumeFromISR - resume lower priority suspended task
*
* This test resume a lower priority task from ISR when scheduler suspended. The
* return value of xTaskResumeFromISR indicates yield not required for the core
* calling this API.
*
* <b>Coverage</b>
* @code{c}
* #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_PREEMPTION == 1 ) )
* {
* prvYieldForTask( pxTCB );
*
* if( xYieldPendings[ portGET_CORE_ID() ] != pdFALSE )
* {
* xYieldRequired = pdTRUE;
* }
* }
* #endif
* @endcode
* ( xYieldPendings[ portGET_CORE_ID() ] != pdFALSE ) is false.
*/
void test_coverage_xTaskResumeFromISR_resume_lower_priority_suspended_task( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 1U ] = { NULL };
uint32_t i;
BaseType_t xReturn;
/* Setup the variables and structure. */
vListInitialise( &xSuspendedTaskList );
vListInitialise( &xPendingReadyList );
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = 2;
xTaskTCBs[ i ].xTaskRunState = i;
xYieldPendings[ i ] = pdFALSE;
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
}
/* A suspended task is created to be resumed from ISR. The task has lower priority
* than uxTopReadyPriority and the scheduler is suspended. The task will be added
* to xPendingReadyList after resumed from ISR. */
xTaskTCBs[ configNUMBER_OF_CORES ].uxPriority = 1;
listINSERT_END( &xSuspendedTaskList, &xTaskTCBs[ i ].xStateListItem );
uxTopReadyPriority = 2;
uxSchedulerSuspended = pdTRUE;
/* Expections. */
vFakePortAssertIfInterruptPriorityInvalid_Ignore();
/* API calls. */
xReturn = xTaskResumeFromISR( &xTaskTCBs[ i ] );
/* Validations. In single priority test, the calling core is not requested to yield
* since a lower priority task is resumed. */
TEST_ASSERT( xReturn == pdFALSE );
}

View file

@ -0,0 +1,158 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "fake_assert.h"
#include "fake_infiniteloop.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* https://www.FreeRTOS.org/a00110.html
*----------------------------------------------------------*/
/* SMP test specific configuration */
#define configRUN_MULTIPLE_PRIORITIES 0
#define configNUMBER_OF_CORES 16
#define configUSE_CORE_AFFINITY 1
#define configUSE_TIME_SLICING 1
#define configUSE_TASK_PREEMPTION_DISABLE 0
#define configTICK_CORE 0
/* OS Configuration */
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configTICK_RATE_HZ ( 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configIDLE_TASK_NAME "idle short"
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 0
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 )
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1
#define portREMOVE_STATIC_QUALIFIER 1
#define portCRITICAL_NESTING_IN_TCB 1
#define portSTACK_GROWTH ( 1 )
#define configUSE_PASSIVE_IDLE_HOOK 1
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 7 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 0
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configENABLE_MPU 0
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* This demo makes use of one or more example stats formatting functions. These
* format the raw data provided by the uxTaskGetSystemState() function in to human
* readable ASCII form. See the notes in the implementation of vTaskList() within
* FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/* Set the following definitions to 1 to include the API function, or zero
* to exclude the API function. In most cases the linker will remove unused
* functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) \
do \
{ \
if( x ) \
{ \
vFakeAssert( true, __FILE__, __LINE__ ); \
} \
else \
{ \
vFakeAssert( false, __FILE__, __LINE__ ); \
} \
} while( 0 )
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
#define configCONTROL_INFINITE_LOOP vFakeInfiniteLoop
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,46 @@
# indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
include ../../makefile.in
# PROJECT_SRC lists the .c files under test
PROJECT_SRC := tasks.c
# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files
# Files in PROJECT_DEPS_SRC are excluded from coverage measurements
PROJECT_DEPS_SRC := list.c queue.c
# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements.
PROJECT_HEADER_DEPS := FreeRTOS.h
# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c)
SUITE_UT_SRC := single_priority_timeslice_utest.c covg_single_priority_timeslice_utest.c
# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases.
# Paths are relative to PROJECT_DIR
SUITE_SUPPORT_SRC := smp_utest_common.c
# List the headers used by PROJECT_SRC that you would like to mock
MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h
MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_infiniteloop.h
# List any addiitonal flags needed by the preprocessor
CPPFLAGS +=
# List any addiitonal flags needed by the compiler
CFLAGS +=
# Try not to edit beyond this line unless necessary.
# Project is determined based on path: $(UT_ROOT_DIR)/$(PROJECT)
PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)/../))))
SUITE := $(lastword $(subst /, ,$(dir $(MAKEFILE_ABSPATH))))
# Make variables available to included makefile
export
include ../../testdir.mk

View file

@ -0,0 +1,673 @@
/*
* FreeRTOS V202212.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 covg_single_priority_timeslice_utest.c */
/* C runtime includes. */
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
/* Task includes */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "event_groups.h"
#include "queue.h"
/* Test includes. */
#include "unity.h"
#include "unity_memory.h"
#include "../global_vars.h"
#include "../smp_utest_common.h"
/* Mock includes. */
#include "mock_timers.h"
#include "mock_fake_assert.h"
#include "mock_fake_port.h"
#include "mock_fake_infiniteloop.h"
/* =========================== EXTERN VARIABLES =========================== */
extern volatile UBaseType_t uxDeletedTasksWaitingCleanUp;
extern volatile TCB_t * pxCurrentTCBs[ configNUMBER_OF_CORES ];
extern UBaseType_t uxTopReadyPriority;
extern List_t pxReadyTasksLists[ configMAX_PRIORITIES ];
extern BaseType_t xSchedulerRunning;
extern UBaseType_t uxCurrentNumberOfTasks;
extern volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES ];
/* =========================== EXTERN FUNCTIONS =========================== */
extern void prvIdleTask( void );
extern void prvPassiveIdleTask( void );
extern void prvSelectHighestPriorityTask( BaseType_t xCoreID );
/* ============================ Unity Fixtures ============================ */
/*! called before each testcase */
void setUp( void )
{
commonSetUp();
}
/*! called after each testcase */
void tearDown( void )
{
commonTearDown();
}
/*! called at the beginning of the whole suite */
void suiteSetUp()
{
}
/*! called at the end of the whole suite */
int suiteTearDown( int numFailures )
{
return numFailures;
}
/* ============================= HELPER FUNCTIONS ========================= */
void vApplicationPassiveIdleHook( void )
{
/* Adding this function to pass compilation. */
}
/* ============================== Test Cases ============================== */
/* @brief prvIdleTask - no other idle priority task
*
* This test calls the prvPassiveIdleTask to cover the condition that no other idle
* priority task in the ready list. The task is still the running task on core 0.
*
* <b>Coverage</b>
* @code{c}
* if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES )
* {
* taskYIELD();
* }
* else
* {
* mtCOVERAGE_TEST_MARKER();
* }
* @endcode
* ( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES ) is false.
*/
void test_coverage_prvIdleTask_no_other_idle_priority_task( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES ] = { 0 };
uint32_t i;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to idle priority. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY;
/* Create idle tasks and add it into the ready list. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = tskIDLE_PRIORITY;
xTaskTCBs[ i ].xTaskRunState = i;
xTaskTCBs[ i ].xStateListItem.pvOwner = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCBs[ i ].uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Expectations. */
vFakeInfiniteLoop_ExpectAndReturn( 1 );
vFakeInfiniteLoop_ExpectAndReturn( 0 );
/* API calls. Runs the idle task function on core 0. */
prvIdleTask();
/* Validations. xTaskTCBs[ 0 ] still runs on core 0. */
configASSERT( pxCurrentTCBs[ 0 ] == &xTaskTCBs[ 0 ] );
}
/* @brief prvIdleTask - yield for idle priority task
*
* This test calls the prvPassiveIdleTask to cover the condition that there are more
* idle priority level tasks than configNUMBER_OF_CORES. Yield is called in prvPassiveIdleTask.
*
* <b>Coverage</b>
* @code{c}
* if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES )
* {
* taskYIELD();
* }
* else
* {
* mtCOVERAGE_TEST_MARKER();
* }
* @endcode
* ( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES ) is true.
*/
void test_coverage_prvIdleTask_yield_for_idle_priority_task( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 1 ] = { 0 };
uint32_t i;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to idle priority. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY;
/* Create idle tasks and add it into the ready list. Create one more idle priority level
* in the loop. */
for( i = 0; i < ( configNUMBER_OF_CORES + 1U ); i++ )
{
xTaskTCBs[ i ].uxPriority = tskIDLE_PRIORITY;
xTaskTCBs[ i ].xStateListItem.pvOwner = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCBs[ i ].uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
if( i < configNUMBER_OF_CORES )
{
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xTaskRunState = i;
}
else
{
xTaskTCBs[ i ].xTaskRunState = -1; /* Set run state to taskTASK_NOT_RUNNING. */
}
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Expectations. */
vFakeInfiniteLoop_ExpectAndReturn( 1 );
vFakeInfiniteLoop_ExpectAndReturn( 0 );
/* API calls. Runs the idle task function on core 0. */
prvIdleTask();
/* Validations. xTaskTCBs[ i ] runs on core 0. */
configASSERT( pxCurrentTCBs[ 0 ] == &xTaskTCBs[ i ] );
}
/* @brief prvPassiveIdleTask - no other idle priority task
*
* This test calls the prvPassiveIdleTask to cover the condition that no other idle
* priority task in the ready list. The task is still the running task on core 0.
*
* <b>Coverage</b>
* @code{c}
* if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES )
* {
* taskYIELD();
* }
* else
* {
* mtCOVERAGE_TEST_MARKER();
* }
* @endcode
* ( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES ) is false.
*/
void test_coverage_prvPassiveIdleTask_no_other_idle_priority_task( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES ] = { 0 };
uint32_t i;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to idle priority. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY;
/* Create idle tasks and add it into the ready list. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
xTaskTCBs[ i ].uxPriority = tskIDLE_PRIORITY;
xTaskTCBs[ i ].xTaskRunState = i;
xTaskTCBs[ i ].xStateListItem.pvOwner = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCBs[ i ].uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Expectations. */
vFakeInfiniteLoop_ExpectAndReturn( 1 );
vFakeInfiniteLoop_ExpectAndReturn( 0 );
/* API calls. Runs the idle task function on core 0. */
prvPassiveIdleTask();
/* Validations. xTaskTCBs[ 0 ] still runs on core 0. */
configASSERT( pxCurrentTCBs[ 0 ] == &xTaskTCBs[ 0 ] );
}
/* @brief prvPassiveIdleTask - yield for idle priority task
*
* This test calls the prvPassiveIdleTask to cover the condition that there are more
* idle priority level tasks than configNUMBER_OF_CORES. Yield is called in prvPassiveIdleTask.
*
* <b>Coverage</b>
* @code{c}
* if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES )
* {
* taskYIELD();
* }
* else
* {
* mtCOVERAGE_TEST_MARKER();
* }
* @endcode
* ( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES ) is true.
*/
void test_coverage_prvPassiveIdleTask_yield_for_idle_priority_task( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 1 ] = { 0 };
uint32_t i;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to idle priority. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY;
/* Create idle tasks and add it into the ready list. Create one more idle priority level
* in the loop. */
for( i = 0; i < ( configNUMBER_OF_CORES + 1U ); i++ )
{
xTaskTCBs[ i ].uxPriority = tskIDLE_PRIORITY;
xTaskTCBs[ i ].xStateListItem.pvOwner = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ];
xTaskTCBs[ i ].uxCoreAffinityMask = ( ( 1U << configNUMBER_OF_CORES ) - 1U );
if( i < configNUMBER_OF_CORES )
{
pxCurrentTCBs[ i ] = &xTaskTCBs[ i ];
xTaskTCBs[ i ].xTaskRunState = i;
}
else
{
xTaskTCBs[ i ].xTaskRunState = -1; /* Set run state to taskTASK_NOT_RUNNING. */
}
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Expectations. */
vFakeInfiniteLoop_ExpectAndReturn( 1 );
vFakeInfiniteLoop_ExpectAndReturn( 0 );
/* API calls. Runs the idle task function on core 0. */
prvPassiveIdleTask();
/* Validations. xTaskTCBs[ i ] runs on core 0. */
configASSERT( pxCurrentTCBs[ 0 ] == &xTaskTCBs[ i ] );
}
/* @brief prvSelectHighestPriorityTask - not schedule none idle task.
*
* Verify that none idle task can't be scheduled when there is higher priority task
* running with single priority config.
*
* <b>Coverage</b>
* @code{c}
* if( uxCurrentPriority < uxTopReadyPriority )
* {
* if( ( pxTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) == 0 )
* {
* continue;
* }
* }
* @endcode
* ( ( pxTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) == 0 ) is true.
*/
void test_coverage_prvSelectHighestPriorityTask_not_schedule_none_idle_task( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 2U ] = { 0 };
uint32_t i = 0;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to higher
* priority than idle. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY + 1;
uxCurrentNumberOfTasks = 0;
/* Create one normal task to be inserted at the beginning of ready list. */
vCreateStaticTestTaskAffinity( &xTaskTCBs[ 0 ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY,
taskTASK_NOT_RUNNING,
pdFALSE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ 0 ].xStateListItem );
/* Create core numbers running idle task. */
for( i = 1; i < ( configNUMBER_OF_CORES + 1 ); i++ )
{
vCreateStaticTestTaskAffinity( &xTaskTCBs[ i ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY,
( i - 1 ),
pdTRUE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Create one higher priority normal task running on core one. */
vCreateStaticTestTaskAffinity( &xTaskTCBs[ i ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY + 1,
1,
pdFALSE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ], &xTaskTCBs[ i ].xStateListItem );
/* The original core 1 idle task now is not running. */
xTaskTCBs[ 2 ].xTaskRunState = taskTASK_NOT_RUNNING;
/* The ready list has the following status.
* Ready list [ 0 ] : T0, T1(0), T2, ..., TN(N-1).
* Ready list [ 1 ] : TN+1(1). */
/* API calls. Select task for core 0. */
prvSelectHighestPriorityTask( 0 );
/* Validations.*/
/* T0 won't be selected to run after calling prvSelectHighestPriorityTask since
* it is not an idle task and top priority is higher than idle. */
TEST_ASSERT_NOT_EQUAL( &xTaskTCBs[ 0 ], pxCurrentTCBs[ 0 ] );
/* T1 is not running since other idle task will be selected first. */
TEST_ASSERT_EQUAL( taskTASK_NOT_RUNNING, xTaskTCBs[ 0 ].xTaskRunState );
/* T2 is selected to run on core 0. */
TEST_ASSERT_EQUAL( 0, xTaskTCBs[ 2 ].xTaskRunState );
}
/* @brief prvSelectHighestPriorityTask - yield for previous task with core affinity.
*
* prvSelectHighestPriorityTask selects a task to run on specified core. The scheduler
* also selects another core to yield for previous task if the condition is satisfied.
* This test verifies the coverage of taskTASK_YIELDING condition.
*
* <b>Coverage</b>
* @code{c}
* if( ( xTaskPriority < xLowestPriority ) &&
* ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) &&
* ( xYieldPendings[ uxCore ] == pdFALSE ) )
* {
* #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
* if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE )
* #endif
* {
* xLowestPriority = xTaskPriority;
* xLowestPriorityCore = uxCore;
* }
* }
* @endcode
* ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) is false.
*/
void test_coverage_prvSelectHighestPriorityTask_affinity_task_yielding( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 2 ] = { 0 };
uint32_t i = 0;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to higher
* priority than idle. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY + 1;
uxCurrentNumberOfTasks = 0;
/* Create core numbers running idle task. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
vCreateStaticTestTaskAffinity( &xTaskTCBs[ i ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY,
i,
pdTRUE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Create two higher priority normal task. */
for( i = configNUMBER_OF_CORES; i < ( configNUMBER_OF_CORES + 2 ); i++ )
{
vCreateStaticTestTaskAffinity( &xTaskTCBs[ i ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY + 1,
taskTASK_NOT_RUNNING,
pdFALSE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ], &xTaskTCBs[ i ].xStateListItem );
}
/* Core 0 runs task TN. The original core 0 idle task now is not running. */
xTaskTCBs[ 0 ].xTaskRunState = taskTASK_NOT_RUNNING;
pxCurrentTCBs[ 0 ] = &xTaskTCBs[ configNUMBER_OF_CORES ];
xTaskTCBs[ configNUMBER_OF_CORES ].xTaskRunState = 0;
/* Idle task 1 is yielding. */
xTaskTCBs[ 1 ].xTaskRunState = taskTASK_YIELDING;
/* Setup the affinity mask for TN and TN+1. */
xTaskTCBs[ configNUMBER_OF_CORES ].uxCoreAffinityMask = ( 1 << 0 ) | ( 1 << 1 );
xTaskTCBs[ configNUMBER_OF_CORES + 1 ].uxCoreAffinityMask = ( 1 << 0 );
/* The ready list has the following status.
* Ready list [ 0 ] : T0, T1(yielding), T2(2), ..., TN-1(N-1).
* Ready list [ 1 ] : TN(0), TN+1. */
/* API calls. Select task for core 0. Task TN+1 will be selected. Scheduler
* tries to find another core to yield for TN. The affinity mask limited the
* core for TN to run on core 1 only ( core 0 is running TN+1 ). Idle task 1 is
* yielding. Therefore, no core will yield for TN. */
prvSelectHighestPriorityTask( 0 );
/* Validations.*/
/* T0 won't be selected to run after calling prvSelectHighestPriorityTask since
* it can only runs on core 0 and core 1. Task on core 1 is yielding. */
TEST_ASSERT_NOT_EQUAL( &xTaskTCBs[ 0 ], pxCurrentTCBs[ 0 ] );
/* T1 is still running on core 1 since it is yielding. */
TEST_ASSERT_EQUAL( &xTaskTCBs[ 1 ], pxCurrentTCBs[ 1 ] );
/* TN+1 is selected to run on core 0. */
TEST_ASSERT_EQUAL( 0, xTaskTCBs[ configNUMBER_OF_CORES + 1 ].xTaskRunState );
}
/* @brief prvSelectHighestPriorityTask - yield for previous task with core affinity.
*
* prvSelectHighestPriorityTask selects a task to run on specified core. The scheduler
* also selects another core to yield for previous task if the condition is satisfied.
* This test verifies the coverage of invalid run state condition.
*
* <b>Coverage</b>
* @code{c}
* if( ( xTaskPriority < xLowestPriority ) &&
* ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) &&
* ( xYieldPendings[ uxCore ] == pdFALSE ) )
* {
* #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
* if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE )
* #endif
* {
* xLowestPriority = xTaskPriority;
* xLowestPriorityCore = uxCore;
* }
* }
* @endcode
* ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) is false.
*/
void test_coverage_prvSelectHighestPriorityTask_affinity_task_state_invalid( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 2 ] = { 0 };
uint32_t i = 0;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to higher
* priority than idle. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY + 1;
uxCurrentNumberOfTasks = 0;
/* Create core numbers running idle task. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
vCreateStaticTestTaskAffinity( &xTaskTCBs[ i ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY,
i,
pdTRUE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Create two higher priority normal task. */
for( i = configNUMBER_OF_CORES; i < ( configNUMBER_OF_CORES + 2 ); i++ )
{
vCreateStaticTestTaskAffinity( &xTaskTCBs[ i ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY + 1,
taskTASK_NOT_RUNNING,
pdFALSE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ], &xTaskTCBs[ i ].xStateListItem );
}
/* Core 0 runs task TN. The original core 0 idle task now is not running. */
xTaskTCBs[ 0 ].xTaskRunState = taskTASK_NOT_RUNNING;
pxCurrentTCBs[ 0 ] = &xTaskTCBs[ configNUMBER_OF_CORES ];
xTaskTCBs[ configNUMBER_OF_CORES ].xTaskRunState = 0;
/* Idle task 1 is of invalid run state. */
xTaskTCBs[ 1 ].xTaskRunState = configNUMBER_OF_CORES;
/* Setup the affinity mask for TN and TN+1. */
xTaskTCBs[ configNUMBER_OF_CORES ].uxCoreAffinityMask = ( 1 << 0 ) | ( 1 << 1 );
xTaskTCBs[ configNUMBER_OF_CORES + 1 ].uxCoreAffinityMask = ( 1 << 0 );
/* The ready list has the following status.
* Ready list [ 0 ] : T0, T1(yielding), T2(2), ..., TN-1(N-1).
* Ready list [ 1 ] : TN(0), TN+1. */
/* API calls. Select task for core 0. Task TN+1 will be selected. Scheduler
* tries to find another core to yield for TN. The affinity mask limited the
* core for TN to run on core 1 only ( core 0 is running TN+1 ). Idle task 1 has
* invalid run state. Therefore, no core will yield for TN. */
prvSelectHighestPriorityTask( 0 );
/* Validations.*/
/* T0 won't be selected to run after calling prvSelectHighestPriorityTask since
* it can only runs on core 0 and core 1. */
TEST_ASSERT_NOT_EQUAL( &xTaskTCBs[ 0 ], pxCurrentTCBs[ 0 ] );
/* TN+1 is selected to run on core 0. */
TEST_ASSERT_EQUAL( 0, xTaskTCBs[ configNUMBER_OF_CORES + 1 ].xTaskRunState );
}
/* @brief prvSelectHighestPriorityTask - yield for previous task with core affinity.
*
* prvSelectHighestPriorityTask selects a task to run on specified core. The scheduler
* also selects another core to yield for previous task if the condition is satisfied.
* This test verifies the coverage of yield pending condition.
*
* <b>Coverage</b>
* @code{c}
* if( ( xTaskPriority < xLowestPriority ) &&
* ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) &&
* ( xYieldPendings[ uxCore ] == pdFALSE ) )
* {
* #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
* if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE )
* #endif
* {
* xLowestPriority = xTaskPriority;
* xLowestPriorityCore = uxCore;
* }
* }
* @endcode
* ( xYieldPendings[ uxCore ] == pdFALSE ) is false.
*/
void test_coverage_prvSelectHighestPriorityTask_affinity_task_yield_pending( void )
{
TCB_t xTaskTCBs[ configNUMBER_OF_CORES + 2 ] = { 0 };
uint32_t i = 0;
/* Setup the variables and structure. */
/* Initialize the idle priority ready list and set top ready priority to higher
* priority than idle. */
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) );
vListInitialise( &( pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ] ) );
uxTopReadyPriority = tskIDLE_PRIORITY + 1;
uxCurrentNumberOfTasks = 0;
/* Create core numbers running idle task. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
vCreateStaticTestTaskAffinity( &xTaskTCBs[ i ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY,
i,
pdTRUE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCBs[ i ].xStateListItem );
}
/* Create two higher priority normal task. */
for( i = configNUMBER_OF_CORES; i < ( configNUMBER_OF_CORES + 2 ); i++ )
{
vCreateStaticTestTaskAffinity( &xTaskTCBs[ i ],
( ( 1U << configNUMBER_OF_CORES ) - 1U ),
tskIDLE_PRIORITY + 1,
taskTASK_NOT_RUNNING,
pdFALSE );
listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY + 1 ], &xTaskTCBs[ i ].xStateListItem );
}
/* Core 0 runs task TN. The original core 0 idle task now is not running. */
xTaskTCBs[ 0 ].xTaskRunState = taskTASK_NOT_RUNNING;
pxCurrentTCBs[ 0 ] = &xTaskTCBs[ configNUMBER_OF_CORES ];
xTaskTCBs[ configNUMBER_OF_CORES ].xTaskRunState = 0;
/* Core 1 has yield pending. */
xYieldPendings[ 1 ] = pdTRUE;
/* Setup the affinity mask for TN and TN+1. */
xTaskTCBs[ configNUMBER_OF_CORES ].uxCoreAffinityMask = ( 1 << 0 ) | ( 1 << 1 );
xTaskTCBs[ configNUMBER_OF_CORES + 1 ].uxCoreAffinityMask = ( 1 << 0 );
/* The ready list has the following status.
* Ready list [ 0 ] : T0, T1(yielding), T2(2), ..., TN-1(N-1).
* Ready list [ 1 ] : TN(0), TN+1. */
/* API calls. Select task for core 0. Task TN+1 will be selected. Scheduler
* tries to find another core to yield for TN. The affinity mask limited the
* core for TN to run on core 1 only ( core 0 is running TN+1 ). Core 1 has yield
* pending. Therefore, no core will yield for TN. */
prvSelectHighestPriorityTask( 0 );
/* Validations.*/
/* T0 won't be selected to run after calling prvSelectHighestPriorityTask since
* it can only runs on core 0 and core 1. Core 1 has yield pending. */
TEST_ASSERT_NOT_EQUAL( &xTaskTCBs[ 0 ], pxCurrentTCBs[ 0 ] );
/* T1 is still running on core 1 since it has yield pending. */
TEST_ASSERT_EQUAL( &xTaskTCBs[ 1 ], pxCurrentTCBs[ 1 ] );
/* TN+1 is selected to run on core 0. */
TEST_ASSERT_EQUAL( 0, xTaskTCBs[ configNUMBER_OF_CORES + 1 ].xTaskRunState );
}

View file

@ -0,0 +1,32 @@
:cmock:
:mock_prefix: mock_
:when_no_prototypes: :warn
:treat_externs: :include
:enforce_strict_ordering: TRUE
:plugins:
- :ignore
- :ignore_arg
- :expect_any_args
- :array
- :callback
- :return_thru_ptr
- :cexception
:callback_include_count: true # include a count arg when calling the callback
:callback_after_arg_check: false # check arguments before calling the callback
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
:includes: # This will add these includes to each mock.
- <stdbool.h>
- "FreeRTOS.h"
:weak: __attribute__((weak))
:verbosity: 3
:attributes:
- PRIVILEGED_FUNCTION
:strippables:
- PRIVILEGED_FUNCTION
- portDONT_DISCARD

View file

@ -0,0 +1,449 @@
/*
* FreeRTOS V202212.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 smp_utest_common.c */
#include "smp_utest_common.h"
/* C runtime includes. */
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
/* Test includes */
#include "task.h"
#include "global_vars.h"
/* Unity includes. */
#include "unity.h"
#include "unity_memory.h"
/* Mock includes. */
#include "mock_fake_assert.h"
#include "mock_fake_port.h"
#include "mock_timers.h"
/* =========================== EXTERN VARIABLES =========================== */
extern List_t pxReadyTasksLists[ configMAX_PRIORITIES ];
extern List_t xDelayedTaskList1;
extern List_t xDelayedTaskList2;
extern volatile UBaseType_t uxDeletedTasksWaitingCleanUp;
extern volatile UBaseType_t uxCurrentNumberOfTasks;
extern volatile TickType_t xTickCount;
extern volatile UBaseType_t uxTopReadyPriority;
extern volatile BaseType_t xSchedulerRunning;
extern volatile TickType_t xPendedTicks;
extern volatile BaseType_t xNumOfOverflows;
extern volatile TickType_t xNextTaskUnblockTime;
extern UBaseType_t uxTaskNumber;
extern TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ];
extern volatile UBaseType_t uxSchedulerSuspended;
extern volatile UBaseType_t uxDeletedTasksWaitingCleanUp;
extern List_t * volatile pxDelayedTaskList;
extern volatile TCB_t * pxCurrentTCBs[ configNUMBER_OF_CORES ];
extern volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES ];
static BaseType_t xCoreYields[ configNUMBER_OF_CORES ] = { 0 };
/* portGET_CORE_ID() returns the xCurrentCoreId. The task choose order is dependent on
* which core calls the FreeRTOS APIs. Setup xCurrentCoreId is required before calling
* FreeRTOS APIs. The default core is 0. */
static BaseType_t xCurrentCoreId = 0;
/* Each core maintains it's lock count. However, only one core has lock count value > 0.
* In real world case, this value is read when interrupt disabled while increased when
* lock is acquired. */
static BaseType_t xIsrLockCount[ configNUMBER_OF_CORES ] = { 0 };
static BaseType_t xTaskLockCount[ configNUMBER_OF_CORES ] = { 0 };
/* ========================== EXTERN FUNCTIONS ========================== */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
extern UBaseType_t vTaskEnterCriticalFromISR( void );
extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus );
/* ========================== CALLBACK FUNCTIONS ========================== */
void * pvPortMalloc( size_t xSize )
{
return unity_malloc( xSize );
}
void vPortFree( void * pv )
{
return unity_free( pv );
}
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{
return pxTopOfStack;
}
BaseType_t xPortStartScheduler( void )
{
uint8_t i;
/* Initialize each core with a task */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
vTaskSwitchContext( i );
}
return pdTRUE;
}
void vPortEndScheduler( void )
{
}
void vFakePortYieldCoreStubCallback( int xCoreID,
int cmock_num_calls )
{
BaseType_t xCoreInCritical = pdFALSE;
BaseType_t xPreviousCoreId = xCurrentCoreId;
int i;
/* Check if the lock is acquired by any core. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
if( ( xIsrLockCount[ i ] > 0 ) || ( xTaskLockCount[ i ] > 0 ) )
{
xCoreInCritical = pdTRUE;
break;
}
}
if( xCoreInCritical == pdTRUE )
{
/* If a is in the critical section, pend the core yield until the
* task spinlock is released. */
xCoreYields[ xCoreID ] = pdTRUE;
}
else
{
/* No task is in the critical section. We can yield this core. */
xCurrentCoreId = xCoreID;
vTaskSwitchContext( xCurrentCoreId );
xCurrentCoreId = xPreviousCoreId;
}
}
void vFakePortYieldStubCallback( int cmock_num_calls )
{
vTaskSwitchContext( xCurrentCoreId );
}
void vFakePortEnterCriticalSectionCallback( int cmock_num_calls )
{
vTaskEnterCritical();
}
/* vTaskExitCritical release the lock then check if this task is requested to yield.
* The mock implementation assumes all the cores can be requested to yield immediately.
* If the core is requested to yield, it will yield in the following order.
* 1. core ID in accsending order if the core is requested to yield and is not xCurrentCoreId.
* 2. core ID which is requested to yield and the core ID equals xCurrentCoreId.
* core i : Core ID requested to yield in critical section in acesending order.
* ....
* core xCurrentCoreId : Core ID equals to xCurrentCoreId and is requested to yield in critical section. */
void vFakePortExitCriticalSectionCallback( int cmock_num_calls )
{
vTaskExitCritical();
}
void vSetCurrentCore( BaseType_t xCoreID )
{
xCurrentCoreId = xCoreID;
}
static void vYieldCores( void )
{
BaseType_t i;
BaseType_t xPreviousCoreId = xCurrentCoreId;
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
if( xCoreYields[ i ] == pdTRUE )
{
xCurrentCoreId = i;
xCoreYields[ i ] = pdFALSE;
vTaskSwitchContext( i );
}
}
xCurrentCoreId = xPreviousCoreId;
}
unsigned int vFakePortGetCoreIDCallback( int cmock_num_calls )
{
return ( unsigned int ) xCurrentCoreId;
}
void vFakePortGetISRLockCallback( int cmock_num_calls )
{
int i;
( void ) cmock_num_calls;
/* Ensure that no other core is in the critical section. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
if( i != xCurrentCoreId )
{
TEST_ASSERT_MESSAGE( xIsrLockCount[ i ] == 0, "vFakePortGetISRLock xIsrLockCount[ i ] > 0" );
TEST_ASSERT_MESSAGE( xTaskLockCount[ i ] == 0, "vFakePortGetISRLock xTaskLockCount[ i ] > 0" );
}
}
xIsrLockCount[ xCurrentCoreId ]++;
}
void vFakePortReleaseISRLockCallback( int cmock_num_calls )
{
( void ) cmock_num_calls;
TEST_ASSERT_MESSAGE( xIsrLockCount[ xCurrentCoreId ] > 0, "xIsrLockCount[ xCurrentCoreId ] <= 0" );
xIsrLockCount[ xCurrentCoreId ]--;
}
void vFakePortGetTaskLockCallback( int cmock_num_calls )
{
int i;
( void ) cmock_num_calls;
/* Ensure that no other core is in the critical section. */
for( i = 0; i < configNUMBER_OF_CORES; i++ )
{
if( i != xCurrentCoreId )
{
TEST_ASSERT_MESSAGE( xIsrLockCount[ i ] == 0, "vFakePortGetTaskLock xIsrLockCount[ i ] > 0" );
TEST_ASSERT_MESSAGE( xTaskLockCount[ i ] == 0, "vFakePortGetTaskLock xTaskLockCount[ i ] > 0" );
}
}
xTaskLockCount[ xCurrentCoreId ]++;
}
void vFakePortReleaseTaskLockCallback( int cmock_num_calls )
{
( void ) cmock_num_calls;
TEST_ASSERT_MESSAGE( xTaskLockCount[ xCurrentCoreId ] > 0, "xTaskLockCount[ xCurrentCoreId ] <= 0" );
xTaskLockCount[ xCurrentCoreId ]--;
/* When releasing the ISR lock, check if any core is waiting to yield. */
if( xTaskLockCount[ xCurrentCoreId ] == 0 )
{
vYieldCores();
}
}
portBASE_TYPE vFakePortEnterCriticalFromISRCallback( int cmock_num_calls )
{
portBASE_TYPE xSavedInterruptState;
xSavedInterruptState = vTaskEnterCriticalFromISR();
return xSavedInterruptState;
}
void vFakePortExitCriticalFromISRCallback( portBASE_TYPE xSavedInterruptState,
int cmock_num_calls )
{
vTaskExitCriticalFromISR( xSavedInterruptState );
/* Simulate yield cores when leaving the critical section. */
vYieldCores();
}
/* ============================= Unity Fixtures ============================= */
void commonSetUp( void )
{
vFakePortYieldCore_StubWithCallback( vFakePortYieldCoreStubCallback );
vFakePortYield_StubWithCallback( vFakePortYieldStubCallback );
vFakePortEnterCriticalSection_StubWithCallback( vFakePortEnterCriticalSectionCallback );
vFakePortExitCriticalSection_StubWithCallback( vFakePortExitCriticalSectionCallback );
vFakePortEnterCriticalFromISR_StubWithCallback( vFakePortEnterCriticalFromISRCallback );
vFakePortExitCriticalFromISR_StubWithCallback( vFakePortExitCriticalFromISRCallback );
vFakePortGetCoreID_StubWithCallback( vFakePortGetCoreIDCallback );
vFakePortGetISRLock_StubWithCallback( vFakePortGetISRLockCallback );
vFakePortGetTaskLock_StubWithCallback( vFakePortGetTaskLockCallback );
vFakePortReleaseISRLock_StubWithCallback( vFakePortReleaseISRLockCallback );
vFakePortReleaseTaskLock_StubWithCallback( vFakePortReleaseTaskLockCallback );
vFakeAssert_Ignore();
vFakePortAssertIfISR_Ignore();
vFakePortEnableInterrupts_Ignore();
ulFakePortSetInterruptMaskFromISR_IgnoreAndReturn( 0 );
vFakePortClearInterruptMaskFromISR_Ignore();
vFakePortDisableInterrupts_IgnoreAndReturn( 1 );
vFakePortRestoreInterrupts_Ignore();
xTimerCreateTimerTask_IgnoreAndReturn( 1 );
vFakePortCheckIfInISR_IgnoreAndReturn( 0 );
vPortCurrentTaskDying_Ignore();
portSetupTCB_CB_Ignore();
ulFakePortSetInterruptMask_IgnoreAndReturn( 0 );
vFakePortClearInterruptMask_Ignore();
memset( &pxReadyTasksLists, 0x00, configMAX_PRIORITIES * sizeof( List_t ) );
memset( &xDelayedTaskList1, 0x00, sizeof( List_t ) );
memset( &xDelayedTaskList2, 0x00, sizeof( List_t ) );
memset( &xIdleTaskHandles, 0x00, ( configNUMBER_OF_CORES * sizeof( TaskHandle_t ) ) );
memset( &pxCurrentTCBs, 0x00, ( configNUMBER_OF_CORES * sizeof( TCB_t * ) ) );
memset( ( void * ) &xYieldPendings, 0x00, ( configNUMBER_OF_CORES * sizeof( BaseType_t ) ) );
uxDeletedTasksWaitingCleanUp = 0;
uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;
xTickCount = ( TickType_t ) 500; /* configINITIAL_TICK_COUNT */
uxTopReadyPriority = tskIDLE_PRIORITY;
xSchedulerRunning = pdFALSE;
xPendedTicks = ( TickType_t ) 0U;
xNumOfOverflows = ( BaseType_t ) 0;
uxTaskNumber = ( UBaseType_t ) 0U;
xNextTaskUnblockTime = ( TickType_t ) 0U;
uxSchedulerSuspended = ( UBaseType_t ) 0;
uxDeletedTasksWaitingCleanUp = 0;
pxDelayedTaskList = NULL;
xCurrentCoreId = 0;
memset( xTaskLockCount, 0x00, sizeof( xTaskLockCount ) );
memset( xIsrLockCount, 0x00, sizeof( xIsrLockCount ) );
}
void commonTearDown( void )
{
}
/* ========================== Helper functions =========================== */
void vSmpTestTask( void * pvParameters )
{
}
void verifySmpTask( TaskHandle_t * xTaskHandle,
eTaskState eCurrentState,
TaskRunning_t xTaskRunState )
{
TaskStatus_t xTaskDetails;
vTaskGetInfo( *xTaskHandle, &xTaskDetails, pdTRUE, eInvalid );
TEST_ASSERT_EQUAL_INT_MESSAGE( xTaskRunState, xTaskDetails.xHandle->xTaskRunState, "Task Verification Failed: Incorrect xTaskRunState" );
TEST_ASSERT_EQUAL_INT_MESSAGE( eCurrentState, xTaskDetails.eCurrentState, "Task Verification Failed: Incorrect eCurrentState" );
}
void verifyIdleTask( BaseType_t index,
TaskRunning_t xTaskRunState )
{
TaskStatus_t xTaskDetails;
int ret;
vTaskGetInfo( xIdleTaskHandles[ index ], &xTaskDetails, pdTRUE, eInvalid );
#ifdef configIDLE_TASK_NAME
ret = strncmp( xTaskDetails.xHandle->pcTaskName, configIDLE_TASK_NAME, strlen( configIDLE_TASK_NAME ) );
#else
ret = strncmp( xTaskDetails.xHandle->pcTaskName, "IDLE", 4 );
#endif
TEST_ASSERT_EQUAL_INT_MESSAGE( 0, ret, "Idle Task Verification Failed: Incorrect task name" );
TEST_ASSERT_EQUAL_INT_MESSAGE( pdTRUE, xTaskDetails.xHandle->uxTaskAttributes, "Idle Task Verification Failed: Incorrect xIsIdle" );
TEST_ASSERT_EQUAL_INT_MESSAGE( xTaskRunState, xTaskDetails.xHandle->xTaskRunState, "Idle Task Verification Failed: Incorrect xTaskRunState" );
TEST_ASSERT_EQUAL_INT_MESSAGE( eRunning, xTaskDetails.eCurrentState, "Idle Task Verification Failed: Incorrect eCurrentState" );
}
/* Helper function to simulate calling xTaskIncrementTick in critical section. */
void xTaskIncrementTick_helper( void )
{
BaseType_t xSwitchRequired;
UBaseType_t uxSavedInterruptState;
/* xTaskIncrementTick is called in ISR context. Use taskENTER/EXIT_CRITICAL_FROM_ISR
* here. */
uxSavedInterruptState = taskENTER_CRITICAL_FROM_ISR();
xSwitchRequired = xTaskIncrementTick();
/* Simulate context switch on the core which calls xTaskIncrementTick. */
if( xSwitchRequired == pdTRUE )
{
portYIELD_CORE( configTICK_CORE );
}
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptState );
}
void vCreateStaticTestTask( TaskHandle_t xTaskHandle,
UBaseType_t uxPriority,
BaseType_t xTaskRunState,
BaseType_t xTaskIsIdle )
{
TCB_t * pxTaskTCB = ( TCB_t * ) xTaskHandle;
pxTaskTCB->xStateListItem.pvOwner = pxTaskTCB;
pxTaskTCB->uxPriority = uxPriority;
/* Also assign pxCurrentTCBs to the created task. */
if( ( xTaskRunState >= 0 ) && ( xTaskRunState < configNUMBER_OF_CORES ) )
{
pxCurrentTCBs[ xTaskRunState ] = pxTaskTCB;
}
pxTaskTCB->xTaskRunState = xTaskRunState;
/* Set idle task attribute. */
if( xTaskIsIdle == pdTRUE )
{
pxTaskTCB->uxTaskAttributes = taskATTRIBUTE_IS_IDLE;
}
else
{
pxTaskTCB->uxTaskAttributes = 0;
}
/* Increase the uxCurrentNumberOfTasks. */
uxCurrentNumberOfTasks = uxCurrentNumberOfTasks + 1;
}
#if ( configUSE_CORE_AFFINITY == 1 )
void vCreateStaticTestTaskAffinity( TaskHandle_t xTaskHandle,
UBaseType_t uxCoreAffinityMask,
UBaseType_t uxPriority,
BaseType_t xTaskRunState,
BaseType_t xTaskIsIdle )
{
TCB_t * pxTaskTCB = ( TCB_t * ) xTaskHandle;
vCreateStaticTestTask( xTaskHandle, uxPriority, xTaskRunState, xTaskIsIdle );
pxTaskTCB->uxCoreAffinityMask = uxCoreAffinityMask;
}
#endif /* if ( configUSE_CORE_AFFINITY == 1 ) */

View file

@ -0,0 +1,118 @@
/*
* FreeRTOS V202212.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 smp_utest_common.h */
#ifndef SMP_UTEST_COMMON_H
#define SMP_UTEST_COMMON_H
/* C runtime includes. */
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
/* Test includes. */
#include "unity.h"
#include "unity_memory.h"
/* FreeRTOS includes */
#include "FreeRTOS.h"
#include "task.h"
#include "global_vars.h"
/* ========================== CALLBACK FUNCTIONS =========================== */
/**
* @brief defines malloc() for this test and redirects it to unity_malloc
* @param xSize size of memory block to be allocated
* @return pointer to the allocated memory on success.
* @return NULL if the memory could not be allocated.
*/
void * pvPortMalloc( size_t xSize );
/**
* @brief defines free() for this test and redirects it to unity_free
* @param pv pointer to the block to be freed
*/
void vPortFree( void * pv );
/* ========================== Helper functions =========================== */
/**
* @brief Common test case setup function for SMP tests.
*/
void commonSetUp( void );
/**
* @brief Common test case teardown function for SMP tests.
*/
void commonTearDown( void );
/**
* @brief Verify task current and run states
*/
void verifySmpTask( TaskHandle_t * xTaskHandle,
eTaskState eCurrentState,
TaskRunning_t xTaskRunState );
/**
* @brief Verify the Idle task is executing on a specific core
*/
void verifyIdleTask( BaseType_t index,
TaskRunning_t xTaskRunState );
/**
* @brief Dummy task for test execution
*/
void vSmpTestTask( void * pvParameters );
/**
* @brief Helper function to simulate calling xTaskIncrementTick in critical section.
*/
void xTaskIncrementTick_helper( void );
/**
* @brief Set the core ID returned by portGET_CORE_ID()
*/
void vSetCurrentCore( BaseType_t xCoreID );
/**
* @brief Helper function to create static test task.
*/
void vCreateStaticTestTask( TaskHandle_t xTaskHandle,
UBaseType_t uxPriority,
BaseType_t xTaskRunState,
BaseType_t xTaskIsIdle );
#if ( configUSE_CORE_AFFINITY == 1 )
void vCreateStaticTestTaskAffinity( TaskHandle_t xTaskHandle,
UBaseType_t uxCoreAffinityMask,
UBaseType_t uxPriority,
BaseType_t xTaskRunState,
BaseType_t xTaskIsIdle );
#endif
#endif /* SMP_UTEST_COMMON_H */

View file

@ -128,8 +128,6 @@ void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that in
} \ } \
} while( 0 ) } while( 0 )
#define mtCOVERAGE_TEST_MARKER() __asm volatile ( "NOP" )
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0 #define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 ) #if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer ); extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );

View file

@ -129,8 +129,6 @@ void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that in
} \ } \
} while( 0 ) } while( 0 )
#define mtCOVERAGE_TEST_MARKER() __asm volatile ( "NOP" )
extern void vDefaultSendCompletedStub( void * xStreamBuffer ); extern void vDefaultSendCompletedStub( void * xStreamBuffer );
#define sbSEND_COMPLETED( pxStreamBuffer ) vDefaultSendCompletedStub( pxStreamBuffer ) #define sbSEND_COMPLETED( pxStreamBuffer ) vDefaultSendCompletedStub( pxStreamBuffer )

View file

@ -27,6 +27,9 @@
#ifndef FREERTOS_CONFIG_H #ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H
#include "fake_assert.h"
#include "fake_infiniteloop.h"
/* XXX: this file will be processed by unifdef to generate new header files /* XXX: this file will be processed by unifdef to generate new header files
* that can be mocked according to the configurations desired * that can be mocked according to the configurations desired
* it has a few limitations on the format of this file such as: * it has a few limitations on the format of this file such as:
@ -131,10 +134,18 @@ void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that in
/* It is a good idea to define configASSERT() while developing. configASSERT() /* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */ * uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) /* *INDENT-OFF* */
#define configASSERT( x ) do { if( x ) { vFakeAssert( true, __FILE__, __LINE__ ); } else { vFakeAssert( false, __FILE__, __LINE__ ); } } while( 0 )
/* *INDENT-ON* */
#define portREMOVE_STATIC_QUALIFIER 1 #define portREMOVE_STATIC_QUALIFIER 1
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0 #define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
#define portALLOCATE_SECURE_CONTEXT vFakePortAllocateSecureContext
#define configCONTROL_INFINITE_LOOP vFakeInfiniteLoop
#endif /* FREERTOS_CONFIG_H */ #endif /* FREERTOS_CONFIG_H */

View file

@ -27,6 +27,8 @@
#ifndef FREERTOS_CONFIG_H #ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H
#include "fake_assert.h"
/* XXX: this file will be processed by unifdef to generate new header files /* XXX: this file will be processed by unifdef to generate new header files
* that can be mocked according to the configurations desired * that can be mocked according to the configurations desired
* it has a few limitations on the format of this file such as: * it has a few limitations on the format of this file such as:
@ -126,7 +128,10 @@ void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that in
/* It is a good idea to define configASSERT() while developing. configASSERT() /* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */ * uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) /* *INDENT-OFF* */
#define configASSERT( x ) do { if( x ) { vFakeAssert( true, __FILE__, __LINE__ ); } else { vFakeAssert( false, __FILE__, __LINE__ ); } } while( 0 )
/* *INDENT-ON* */
#define portREMOVE_STATIC_QUALIFIER 1 #define portREMOVE_STATIC_QUALIFIER 1
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0

View file

@ -0,0 +1,144 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "fake_assert.h"
/* XXX: this file will be processed by unifdef to generate new header files
* that can be mocked according to the configurations desired
* it has a few limitations on the format of this file such as:
* no config that spans more than one line
* no strings in config names
* for more info please check the man file with $ man unifdef
*/
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configUSE_TICKLESS_IDLE 1
#define configUSE_TIME_SLICING 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 1
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) /* For test. */
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 /* As there are a lot of tasks running. */
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 9 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 0
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define configENABLE_MPU 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define portSTACK_GROWTH ( -1 )
#define configRECORD_STACK_HIGH_ADDRESS 1
/* This demo makes use of one or more example stats formatting functions. These
* format the raw data provided by the uxTaskGetSystemState() function in to human
* readable ASCII form. See the notes in the implementation of vTaskList() within
* FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
/* Set the following definitions to 1 to include the API function, or zero
* to exclude the API function. In most cases the linker will remove unused
* functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
/* *INDENT-OFF* */
#define configASSERT( x ) do { if( x ) { vFakeAssert( true, __FILE__, __LINE__ ); } else { vFakeAssert( false, __FILE__, __LINE__ ); } } while( 0 )
/* *INDENT-ON* */
#define portREMOVE_STATIC_QUALIFIER 1
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
#endif /* FREERTOS_CONFIG_H */

View file

@ -6,17 +6,20 @@
include ../makefile.in include ../makefile.in
PROJECT := tasks PROJECT := tasks
# SUITES lists the suites contained in subdirectories of this directory
# #
# Test/CMock/tasks # Test/CMock/tasks
PROJECT_DIR := $(abspath .) PROJECT_DIR := $(abspath .)
PROJ_DIR := $(abspath .) PROJ_DIR := $(abspath .)
# List the dependency files you wish to mock # List the dependency files you wish to mock
MOCK_FILES_FP := $(KERNEL_DIR)/include/timers.h MOCK_FILES_FP := $(KERNEL_DIR)/include/timers.h
MOCK_FILES_FP += $(KERNEL_DIR)/include/list.h MOCK_FILES_FP += $(KERNEL_DIR)/include/list.h
MOCK_FILES_FP += $(KERNEL_DIR)/include/portable.h MOCK_FILES_FP += $(KERNEL_DIR)/include/portable.h
MOCK_FILES_FP += $(PROJECT_DIR)/list_macros.h MOCK_FILES_FP += $(PROJECT_DIR)/list_macros.h
MOCK_FILES_FP += $(PROJECT_DIR)/../config/fake_assert.h
MOCK_FILES_FP += $(PROJECT_DIR)/../config/fake_infiniteloop.h
UNDEF_MOCKED_HEADER_MACROS := -UlistLIST_IS_EMPTY -UlistGET_OWNER_OF_HEAD_ENTRY\ UNDEF_MOCKED_HEADER_MACROS := -UlistLIST_IS_EMPTY -UlistGET_OWNER_OF_HEAD_ENTRY\
-UlistIS_CONTAINED_WITHIN -UlistGET_LIST_ITEM_VALUE \ -UlistIS_CONTAINED_WITHIN -UlistGET_LIST_ITEM_VALUE \
@ -24,7 +27,7 @@ UNDEF_MOCKED_HEADER_MACROS := -UlistLIST_IS_EMPTY -UlistGET_OWNER_OF_HEAD_ENTRY\
-UlistLIST_ITEM_CONTAINER -UlistCURRENT_LIST_LENGTH -UlistLIST_ITEM_CONTAINER -UlistCURRENT_LIST_LENGTH
# List special compilation flags for this module # List special compilation flags for this module
CFLAGS += -Wno-unused-function CFLAGS += -Wno-unused-function
# List special preprocessing flags for this module # List special preprocessing flags for this module
CPPFLAGS += CPPFLAGS +=
@ -37,7 +40,7 @@ LDFLAGS +=
# Try not to edit beyond this line # Try not to edit beyond this line
COVERAGE_OPTS := -fprofile-arcs -ftest-coverage -fprofile-generate COVERAGE_OPTS := -fprofile-arcs -ftest-coverage -fprofile-generate
# build/generated/queue # build/generated/queue
SCRATCH_DIR := $(GENERATED_DIR)/$(PROJECT) SCRATCH_DIR := $(GENERATED_DIR)/$(PROJECT)
@ -66,10 +69,13 @@ DISCRIMINATOR := $(subst _utest,,$(subst .c,,$(subst $(PROJECT)_,,$(PROJ_SR
# tasks/1/mocks tasks/2/mocks # tasks/1/mocks tasks/2/mocks
MOCK_DIRS := $(addsuffix /mocks,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) MOCK_DIRS := $(addsuffix /mocks,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR)))
# queue/1/cpp queue/2/cpp # queue/1/cpp queue/2/cpp
CPP_DIRS := $(addsuffix /cpp,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) CPP_DIRS := $(addsuffix /cpp,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR)))
# tasks/1/include tasks/2/include # tasks/1/include tasks/2/include
INCLUDE_DIRS := $(addsuffix /include,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) INCLUDE_DIRS := $(addsuffix /include,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR)))
#list/1 list/2 .... #list/1 list/2 ....
CONFIG_DIRS := $(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR)) CONFIG_DIRS := $(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))
@ -84,8 +90,7 @@ PROJ_OBJ_LIST := $(EXEC_LIST)
.PHONY: all Makefile directories .PHONY: all Makefile directories
.SECONDARY: all : directories $(EXEC_LIST) run
all : directories $(EXEC_LIST)
# Build the executables 1 per configuration # Build the executables 1 per configuration
$(EXEC_PATH) : $(MOCK_OBJS) \ $(EXEC_PATH) : $(MOCK_OBJS) \
@ -112,6 +117,7 @@ $(CPP_FILES) : | directories
sed -i '/#ifndef FREERTOS_CONFIG_H/d' $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def sed -i '/#ifndef FREERTOS_CONFIG_H/d' $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def
sed -i '/#define FREERTOS_CONFIG_H/d' $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def sed -i '/#define FREERTOS_CONFIG_H/d' $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def
sed -i '/#endif/d' $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def sed -i '/#endif/d' $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def
sed -i '/#include/d' $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def
for h_file in $(MOCK_FILES_FP) ; do \ for h_file in $(MOCK_FILES_FP) ; do \
unifdef -f $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def $$h_file \ unifdef -f $(SCRATCH_DIR)/$*/include/FreeRTOSConfig.def $$h_file \
> $(SCRATCH_DIR)/$*/cpp/$$(basename $$h_file) ; \ > $(SCRATCH_DIR)/$*/cpp/$$(basename $$h_file) ; \
@ -179,3 +185,18 @@ directories :
EXEC_PREFIX := $(PROJECT) EXEC_PREFIX := $(PROJECT)
include ../coverage.mk include ../coverage.mk
# Indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
SUITES += tasks_freertos
# run each suite and leave gcda / gcov files in place
run:
$(foreach suite,$(SUITES),make -C $(suite) run;)
#bin: $(EXEC_LIST)
#include ../subdir.mk

View file

@ -32,13 +32,17 @@
#include "fake_port.h" #include "fake_port.h"
#include "task.h" #include "task.h"
/* Mock includes. */
#include "mock_list.h" #include "mock_list.h"
#include "mock_list_macros.h" #include "mock_list_macros.h"
#include "mock_timers.h" #include "mock_timers.h"
#include "mock_portable.h" #include "mock_portable.h"
#include "mock_fake_assert.h"
#include "mock_fake_infiniteloop.h"
/* Test includes. */ /* Test includes. */
#include "unity.h" #include "unity.h"
#include "CException.h"
#include "global_vars.h" #include "global_vars.h"
/* C runtime includes. */ /* C runtime includes. */
@ -65,7 +69,6 @@ extern volatile TickType_t xTickCount;
extern volatile UBaseType_t uxTopReadyPriority; extern volatile UBaseType_t uxTopReadyPriority;
extern volatile BaseType_t xSchedulerRunning; extern volatile BaseType_t xSchedulerRunning;
extern volatile TickType_t xPendedTicks; extern volatile TickType_t xPendedTicks;
#ifdef configNUMBER_OF_CORES #ifdef configNUMBER_OF_CORES
extern volatile BaseType_t xYieldPendings[]; extern volatile BaseType_t xYieldPendings[];
#define xYieldPending xYieldPendings[ 0 ] #define xYieldPending xYieldPendings[ 0 ]
@ -75,7 +78,6 @@ extern volatile TickType_t xPendedTicks;
extern volatile BaseType_t xNumOfOverflows; extern volatile BaseType_t xNumOfOverflows;
extern UBaseType_t uxTaskNumber; extern UBaseType_t uxTaskNumber;
extern volatile TickType_t xNextTaskUnblockTime; extern volatile TickType_t xNextTaskUnblockTime;
#ifdef configNUMBER_OF_CORES #ifdef configNUMBER_OF_CORES
extern TaskHandle_t xIdleTaskHandles[]; extern TaskHandle_t xIdleTaskHandles[];
#define xIdleTaskHandle xIdleTaskHandles[ 0 ] #define xIdleTaskHandle xIdleTaskHandles[ 0 ]
@ -118,6 +120,11 @@ extern volatile UBaseType_t uxSchedulerSuspended;
#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 ) #define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 )
#define TCB_ARRAY 10 /* simulate up to 10 tasks: add more if needed */ #define TCB_ARRAY 10 /* simulate up to 10 tasks: add more if needed */
/**
* @brief CException code for when a configASSERT should be intercepted.
*/
#define configASSERT_E 0xAA101
/* =========================== GLOBAL VARIABLES =========================== */ /* =========================== GLOBAL VARIABLES =========================== */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
@ -151,6 +158,18 @@ static bool port_allocate_secure_context_called = false;
static bool port_assert_if_in_isr_called = false; static bool port_assert_if_in_isr_called = false;
static bool vApplicationMallocFailedHook_called = false; static bool vApplicationMallocFailedHook_called = false;
/**
* @brief Global counter for the number of assertions in code.
*/
static int assertionFailed = 0;
/**
* @brief Flag which denotes if test need to abort on assertion.
*/
static BaseType_t shouldAbortOnAssertion = pdFALSE;
/* ============================ EXTERN FUNCTIONS ========================== */
extern void prvCheckTasksWaitingTermination( void );
/* ============================ HOOK FUNCTIONS ============================ */ /* ============================ HOOK FUNCTIONS ============================ */
static void dummy_operation() static void dummy_operation()
@ -163,7 +182,7 @@ void vFakePortAssertIfISR( void )
HOOK_DIAG(); HOOK_DIAG();
} }
void port_allocate_secure_context( BaseType_t stackSize ) void vFakePortAllocateSecureContext( BaseType_t stackSize )
{ {
HOOK_DIAG(); HOOK_DIAG();
port_allocate_secure_context_called = true; port_allocate_secure_context_called = true;
@ -259,10 +278,11 @@ void vFakePortYieldFromISR()
HOOK_DIAG(); HOOK_DIAG();
} }
void vFakePortDisableInterrupts() uint32_t vFakePortDisableInterrupts()
{ {
port_disable_interrupts_called = true; port_disable_interrupts_called = true;
HOOK_DIAG(); HOOK_DIAG();
return 0;
} }
void vFakePortEnableInterrupts() void vFakePortEnableInterrupts()
@ -323,10 +343,53 @@ void vApplicationStackOverflowHook( TaskHandle_t xTask,
vApplicationStackOverflowHook_called = true; vApplicationStackOverflowHook_called = true;
} }
unsigned int vFakePortGetCoreID( void )
{
HOOK_DIAG();
return 0;
}
void vFakePortReleaseTaskLock( void )
{
HOOK_DIAG();
}
void vFakePortGetTaskLock( void )
{
HOOK_DIAG();
}
void vFakePortGetISRLock( void )
{
HOOK_DIAG();
}
void vFakePortReleaseISRLock( void )
{
HOOK_DIAG();
}
static void vFakeAssertStub( bool x,
char * file,
int line,
int cmock_num_calls )
{
if( !x )
{
assertionFailed++;
if( shouldAbortOnAssertion == pdTRUE )
{
Throw( configASSERT_E );
}
}
}
/* ============================ Unity Fixtures ============================ */ /* ============================ Unity Fixtures ============================ */
/*! called before each testcase */ /*! called before each testcase */
void setUp( void ) void setUp( void )
{ {
vFakeAssert_StubWithCallback( vFakeAssertStub );
RESET_ALL_HOOKS(); RESET_ALL_HOOKS();
pxCurrentTCB = NULL; pxCurrentTCB = NULL;
memset( &tcb, 0x00, sizeof( TCB_t ) * TCB_ARRAY ); memset( &tcb, 0x00, sizeof( TCB_t ) * TCB_ARRAY );
@ -335,10 +398,6 @@ void setUp( void )
memset( &xDelayedTaskList1, 0x00, sizeof( List_t ) ); memset( &xDelayedTaskList1, 0x00, sizeof( List_t ) );
memset( &xDelayedTaskList2, 0x00, sizeof( List_t ) ); memset( &xDelayedTaskList2, 0x00, sizeof( List_t ) );
/*
* pxDelayedTaskList = NULL;
* pxOverflowDelayedTaskList = NULL;
*/
memset( &xPendingReadyList, 0x00, sizeof( List_t ) ); memset( &xPendingReadyList, 0x00, sizeof( List_t ) );
memset( &xTasksWaitingTermination, 0x00, sizeof( List_t ) ); memset( &xTasksWaitingTermination, 0x00, sizeof( List_t ) );
@ -944,6 +1003,71 @@ void test_vTaskDelete_success_not_current_task_no_yield( void )
ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED();
} }
/**
* @brief prvCheckTasksWaitingTermination - no waiting task.
*
* No task is waiting to be deleted. This test show it's result in the coverage
* report.
*
* <b>Coverage</b>
* @code{c}
* while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
* {
* ...
* }
* @endcode
* ( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) is false.
*/
void test_prvCheckTasksWaitingTermination_no_waiting_task( void )
{
/* Setup the variables and structure. */
uxDeletedTasksWaitingCleanUp = 0;
/* API Call. */
prvCheckTasksWaitingTermination();
/* Validation. */
/* No task is waiting to be cleaned up. Nothing will be updated in this API. This
* test case shows its result in the coverage report. */
}
/**
* @brief prvCheckTasksWaitingTermination - delete waiting task.
*
* A task is waiting to be deleted. The number of tasks and number of tasks waiting to
* be deleted are verified in this test case.
*
* <b>Coverage</b>
* @code{c}
* while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
* {
* ...
* }
* @endcode
* ( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) is true.
*/
void test_prvCheckTasksWaitingTermination_delete_waiting_task( void )
{
ptcb = ( TCB_t * ) create_task();
/* Setup the variables and structure. */
uxDeletedTasksWaitingCleanUp = 1;
uxCurrentNumberOfTasks = 1;
/* Expectations. */
listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( ptcb );
uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 0 );
vPortFree_Expect( stack );
vPortFree_Expect( ptcb );
/* API Call. */
prvCheckTasksWaitingTermination();
/* Validation. */
TEST_ASSERT_EQUAL( uxDeletedTasksWaitingCleanUp, 0 );
TEST_ASSERT_EQUAL( uxCurrentNumberOfTasks, 0 );
}
void test_vTaskStartScheduler_success( void ) void test_vTaskStartScheduler_success( void )
{ {
@ -2934,6 +3058,7 @@ void test_pcTaskGetName_success_null_handle( void )
ret_task_name = pcTaskGetName( NULL ); ret_task_name = pcTaskGetName( NULL );
TEST_ASSERT_EQUAL_STRING( "create_task", ret_task_name ); TEST_ASSERT_EQUAL_STRING( "create_task", ret_task_name );
} }
void test_xTaskCatchUpTicks( void ) void test_xTaskCatchUpTicks( void )
{ {
BaseType_t ret_taskCatchUpTicks; BaseType_t ret_taskCatchUpTicks;
@ -2941,11 +3066,18 @@ void test_xTaskCatchUpTicks( void )
task_handle = create_task(); task_handle = create_task();
ptcb = task_handle; ptcb = task_handle;
uxSchedulerSuspended = pdTRUE; uxSchedulerSuspended = pdFALSE;
listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE );
listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE );
listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 0 );
/* API Call */ /* API Call */
ret_taskCatchUpTicks = xTaskCatchUpTicks( 500 ); ret_taskCatchUpTicks = xTaskCatchUpTicks( 1 );
/* Validations */ /* Validations */
TEST_ASSERT_EQUAL( pdFALSE, ret_taskCatchUpTicks ); TEST_ASSERT_EQUAL( pdFALSE, ret_taskCatchUpTicks );
/*TEST_ASSERT_EQUAL( pdTRUE, ret_taskCatchUpTicks ); */
uxSchedulerSuspended = pdTRUE;
} }
void test_xTaskIncrementTick_success_sched_suspended_no_switch( void ) void test_xTaskIncrementTick_success_sched_suspended_no_switch( void )
@ -2975,11 +3107,11 @@ void test_xTaskIncrementTick_success_tickCount_overlow( void )
overflow = pxOverflowDelayedTaskList; overflow = pxOverflowDelayedTaskList;
xTickCount = UINT32_MAX; /* overflowed */ xTickCount = UINT32_MAX; /* overflowed */
create_task(); create_task();
/* Expectations */ /* Expectations */
/* prvResetNextTaskUnblockTime */ /* taskSWITCH_DELAYED_LISTS */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
/* back */ /* back */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ],
2 ); 2 );
/* API Call */ /* API Call */
@ -3030,6 +3162,8 @@ void test_xTaskIncrementTick_success_switch( void )
xTickCount = UINT32_MAX; xTickCount = UINT32_MAX;
/* Expectations */ /* Expectations */
/* taskSWITCH_DELAYED_LISTS(); */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ],
3 ); 3 );
@ -3167,6 +3301,71 @@ void test_xTaskIncrementTick_success_unblock_tasks2( void )
TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime );
} }
/**
* @brief xTaskIncrementTick - Ready a higher priority delayed task.
*
* Ready a higher priority delayed task. Verify the return value is pdTRUE.
*
* <b>Coverage</b>
* @code{c}
* if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
* {
* xSwitchRequired = pdTRUE;
* }
* else
* {
* mtCOVERAGE_TEST_MARKER();
* }
* @endcode
* ( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) is true.
*/
void test_xTaskIncrementTick_success_unblock_higher_prio_task( void )
{
BaseType_t ret_task_incrementtick;
TaskHandle_t task_handle;
TaskHandle_t task_handle2;
/* setup */
create_task_priority = 2;
task_handle = create_task();
create_task_priority = 1;
task_handle2 = create_task();
/* task_handle 2 will be added to pxDelayedTaskList later. To wakeup a higher priority
* task, uxPriority is set higher than current task, which is 2. */
task_handle2->uxPriority = 3;
ptcb = task_handle;
xPendedTicks = 0;
xTickCount = 50;
xNextTaskUnblockTime = 49; /* tasks due unblocking */
uxSchedulerSuspended = pdFALSE;
/* Expectations */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdFALSE );
listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( pxDelayedTaskList, task_handle2 );
listGET_LIST_ITEM_VALUE_ExpectAndReturn( &task_handle2->xStateListItem,
xTickCount - 5 );
listREMOVE_ITEM_Expect( &( task_handle2->xStateListItem ) );
listLIST_ITEM_CONTAINER_ExpectAndReturn( &task_handle2->xEventListItem,
&xPendingReadyList );
listREMOVE_ITEM_Expect( &( task_handle2->xEventListItem ) );
/* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ task_handle2->uxPriority ],
&task_handle2->xStateListItem );
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
/* back */
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ],
1 );
/* API Call */
ret_task_incrementtick = xTaskIncrementTick();
/* Validations */
TEST_ASSERT_EQUAL( pdTRUE, ret_task_incrementtick );
ASSERT_APP_TICK_HOOK_CALLED();
TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime );
}
/* Tests the scenario when a task with priority higher than the /* Tests the scenario when a task with priority higher than the
* currently executing task is unblocked as a result of the * currently executing task is unblocked as a result of the
* xTaskIncrementTick call. Also, xPendedTicks is set to * xTaskIncrementTick call. Also, xPendedTicks is set to
@ -3483,6 +3682,7 @@ void test_vTaskSwitchContext( void )
pxCurrentTCB->pxTopOfStack = pxCurrentTCB->pxStack + 4; \ pxCurrentTCB->pxTopOfStack = pxCurrentTCB->pxStack + 4; \
/* Expectations */ /* Expectations */
listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 0 );
/* API Call */ /* API Call */
vTaskSwitchContext(); vTaskSwitchContext();
@ -3517,6 +3717,7 @@ void test_vTaskSwitchContext_detect_overflow( void )
uxSchedulerSuspended = pdFALSE; uxSchedulerSuspended = pdFALSE;
pxCurrentTCB->pxTopOfStack = pxCurrentTCB->pxStack; pxCurrentTCB->pxTopOfStack = pxCurrentTCB->pxStack;
/* Expectations */ /* Expectations */
listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 0 );
/* API Call */ /* API Call */
vTaskSwitchContext(); vTaskSwitchContext();
@ -3558,6 +3759,8 @@ void test_vTaskPlaceOnUnorderedEventList( void )
ptcb = task_handle; ptcb = task_handle;
xNextTaskUnblockTime = 600; xNextTaskUnblockTime = 600;
uxSchedulerSuspended = pdTRUE;
/* Expectations */ /* Expectations */
listSET_LIST_ITEM_VALUE_Expect( &ptcb->xEventListItem, 32 | 0x80000000UL ); listSET_LIST_ITEM_VALUE_Expect( &ptcb->xEventListItem, 32 | 0x80000000UL );
listINSERT_END_Expect( &eventList, &ptcb->xEventListItem ); listINSERT_END_Expect( &eventList, &ptcb->xEventListItem );
@ -3886,8 +4089,30 @@ void test_vTaskMissedYield( void )
TEST_ASSERT_TRUE( xYieldPending ); TEST_ASSERT_TRUE( xYieldPending );
} }
/* TODO: find a way to fix the idle task UnitTest as it is an infinite loop */ /**
void ignore_test_prvIdleTask_yield( void ) * @brief prvIdleTask - yield
*
* Test prvIdleTask yield for other idle level priority task.
*
* <b>Coverage</b>
* @code{c}
* #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
* {
* ...
* if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES )
* {
* taskYIELD();
* }
* else
* {
* mtCOVERAGE_TEST_MARKER();
* }
* }
* #endif
* @endcode
* ( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUMBER_OF_CORES ) is true.
*/
void test_prvIdleTask_yield( void )
{ {
int i = 8; int i = 8;
void * args = &i; void * args = &i;
@ -3895,25 +4120,92 @@ void ignore_test_prvIdleTask_yield( void )
create_task_priority = 3; create_task_priority = 3;
create_task(); create_task();
/* Setup */ /* Setup. */
uxDeletedTasksWaitingCleanUp = 0; uxDeletedTasksWaitingCleanUp = 0;
portTASK_FUNCTION( prvIdleTask, args ); portTASK_FUNCTION( prvIdleTask, args );
( void ) fool_static2; ( void ) fool_static2;
/* Expectations */
/* Expectations. */
/* INFINITE_LOOP in prvIdleTask. */
vFakeInfiniteLoop_ExpectAndReturn( 1 );
/* List function in prvIdleTask. */
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 2 ); listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 2 );
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 );
/* prvGetExpectedIdleTime */ /* INFINITE_LOOP in prvIdleTask. */
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 ); vFakeInfiniteLoop_ExpectAndReturn( 0 );
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 );
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 ); /* API Call. */
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 );
/* API Call */
prvIdleTask( args ); prvIdleTask( args );
/* Validations */
/* Validations. */
ASSERT_PORT_ALLOCATE_SECURE_CONTEXT_CALLED(); ASSERT_PORT_ALLOCATE_SECURE_CONTEXT_CALLED();
ASSERT_PORT_YIELD_CALLED(); ASSERT_PORT_YIELD_CALLED();
ASSERT_APPLICATION_IDLE_HOOK_CALLED(); ASSERT_APPLICATION_IDLE_HOOK_CALLED();
} }
/**
* @brief prvIdleTask - tickless expected idle time
*
* Test prvIdleTask expected idle time condition.
*
* <b>Coverage</b>
* @code{c}
* #if ( configUSE_TICKLESS_IDLE != 0 )
* {
* TickType_t xExpectedIdleTime;
* ...
* xExpectedIdleTime = prvGetExpectedIdleTime();
*
* if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
* {
* vTaskSuspendAll();
* {
* #endif
* @endcode
* ( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) is true.
*/
void test_prvIdleTask_tickless_expected_idle_time( void )
{
int i = 8;
void * args = &i;
create_task_priority = 0;
create_task();
/* Setup. */
uxTopReadyPriority = 0;
xTickCount = 0;
xNextTaskUnblockTime = configEXPECTED_IDLE_TIME_BEFORE_SLEEP + 1;
uxDeletedTasksWaitingCleanUp = 0;
portTASK_FUNCTION( prvIdleTask, args );
( void ) fool_static2;
/* Expectations. */
/* INFINITE_LOOP in prvIdleTask. */
vFakeInfiniteLoop_ExpectAndReturn( 1 );
/* List function in prvIdleTask. */
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 1 );
/* List functions in prvGetExpectedIdleTime. */
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 1 );
listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 1 );
/* List functions in xTaskResumeAll */
listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE );
/* INFINITE_LOOP in prvIdleTask. */
vFakeInfiniteLoop_ExpectAndReturn( 0 );
/* API Call. */
prvIdleTask( args );
/* Validations. */
ASSERT_PORT_ALLOCATE_SECURE_CONTEXT_CALLED();
ASSERT_APPLICATION_IDLE_HOOK_CALLED();
}
/* implement */ /* implement */
/*configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime ); */ /*configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime ); */
@ -4683,8 +4975,11 @@ void test_xTaskGenericNotify_success_null_pull( void )
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
&ptcb->xStateListItem ); &ptcb->xStateListItem );
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
/* prvResetNextTaskUnblockTime */ /* prvResetNextTaskUnblockTime */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
/* API Call */ /* API Call */
ret_task_notify = xTaskGenericNotify( ptcb, ret_task_notify = xTaskGenericNotify( ptcb,
uxIndexToNotify, uxIndexToNotify,
@ -4715,6 +5010,8 @@ void test_xTaskGenericNotify_success_eIncrement( void )
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
&ptcb->xStateListItem ); &ptcb->xStateListItem );
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
/* prvResetNextTaskUnblockTime */ /* prvResetNextTaskUnblockTime */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
/* API Call */ /* API Call */
@ -4747,6 +5044,8 @@ void test_xTaskGenericNotify_success_eSetValueWithOverwrite( void )
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
&ptcb->xStateListItem ); &ptcb->xStateListItem );
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
/* prvResetNextTaskUnblockTime */ /* prvResetNextTaskUnblockTime */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
/* API Call */ /* API Call */
@ -4779,6 +5078,8 @@ void test_xTaskGenericNotify_success_eSetValueWithoutOverwrite( void )
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
&ptcb->xStateListItem ); &ptcb->xStateListItem );
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
/* prvResetNextTaskUnblockTime */ /* prvResetNextTaskUnblockTime */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
/* API Call */ /* API Call */
@ -4869,6 +5170,8 @@ void test_xTaskGenericNotify_success_default( void )
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
&ptcb->xStateListItem ); &ptcb->xStateListItem );
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
/* prvResetNextTaskUnblockTime */ /* prvResetNextTaskUnblockTime */
listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE );
/* API Call */ /* API Call */
@ -4931,7 +5234,10 @@ void test_xTaskGenericNotify_success_null_pull_ISR( void )
ptcb = task_to_notify; ptcb = task_to_notify;
vTaskSuspendAll(); vTaskSuspendAll();
/* Expectations */ /* Expectations */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listINSERT_END_Expect( &xPendingReadyList, &ptcb->xEventListItem ); listINSERT_END_Expect( &xPendingReadyList, &ptcb->xEventListItem );
/* API Call */ /* API Call */
ret_task_notify = xTaskGenericNotifyFromISR( ptcb, ret_task_notify = xTaskGenericNotifyFromISR( ptcb,
uxIndexToNotify, uxIndexToNotify,
@ -4963,10 +5269,14 @@ void test_xTaskGenericNotify_success_eIncrement_ISR( void )
task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION;
ptcb = task_to_notify; ptcb = task_to_notify;
/* Expectations */ /* Expectations */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) );
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
&ptcb->xStateListItem ); &ptcb->xStateListItem );
/* API Call */ /* API Call */
ret_task_notify = xTaskGenericNotifyFromISR( ptcb, ret_task_notify = xTaskGenericNotifyFromISR( ptcb,
uxIndexToNotify, uxIndexToNotify,
@ -4998,6 +5308,8 @@ void test_xTaskGenericNotify_success_eSetValueWithOverwrite_ISR( void )
task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION;
ptcb = task_to_notify; ptcb = task_to_notify;
/* Expectations */ /* Expectations */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) );
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
@ -5033,6 +5345,8 @@ void test_xTaskGenericNotify_success_eSetValueWithoutOverwrite_ISR( void )
task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION;
ptcb = task_to_notify; ptcb = task_to_notify;
/* Expectations */ /* Expectations */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) );
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
@ -5140,6 +5454,8 @@ void test_xTaskGenericNotify_success_default_ISR( void )
task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION;
ptcb = task_to_notify; ptcb = task_to_notify;
/* Expectations */ /* Expectations */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) );
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
@ -5183,6 +5499,8 @@ void test_xTaskGenericNotify_success_default_ISR_task_woken_null( void )
task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION;
ptcb = task_to_notify; ptcb = task_to_notify;
/* Expectations */ /* Expectations */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) );
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ],
@ -5365,11 +5683,16 @@ void test_vTaskGenericNotifyGiveFromISR_success( void )
/* Setup */ /* Setup */
task_to_notify = create_task(); task_to_notify = create_task();
task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION;
ptcb = task_to_notify;
/* Expectations */ /* Expectations */
/* configASSERT statement */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
/*uxListRemove_ExpectAndReturn( &task_to_notify->xStateListItem, pdTRUE ); */ /*uxListRemove_ExpectAndReturn( &task_to_notify->xStateListItem, pdTRUE ); */
listREMOVE_ITEM_Expect( &( task_to_notify->xStateListItem ) ); listREMOVE_ITEM_Expect( &( task_to_notify->xStateListItem ) );
/* prvAddTaskToReadyList */ /* prvAddTaskToReadyList */
listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem ); listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem );
/* API Call */ /* API Call */
vTaskGenericNotifyGiveFromISR( task_to_notify, vTaskGenericNotifyGiveFromISR( task_to_notify,
uxIndexToNotify, uxIndexToNotify,
@ -5391,8 +5714,12 @@ void test_vTaskGenericNotifyGiveFromISR_success_scheduler_suspended( void )
/* Setup */ /* Setup */
task_to_notify = create_task(); task_to_notify = create_task();
task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION;
ptcb = task_to_notify;
vTaskSuspendAll(); vTaskSuspendAll();
/* Expectations */ /* Expectations */
/* configASSERT statement */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem ); listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem );
/* API Call */ /* API Call */
@ -5425,7 +5752,11 @@ void test_vTaskGenericNotifyGiveFromISR_success_yield_pending( void )
task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION;
ptcb = task_to_notify; ptcb = task_to_notify;
vTaskSuspendAll(); vTaskSuspendAll();
/* Expectations */ /* Expectations */
/* configASSERT statement */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem ); listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem );
/* API Call */ /* API Call */
@ -5458,6 +5789,9 @@ void test_vTaskGenericNotifyGiveFromISR_success_null_higherpriority_task( void )
ptcb = task_to_notify; ptcb = task_to_notify;
vTaskSuspendAll(); vTaskSuspendAll();
/* Expectations */ /* Expectations */
/* configASSERT statement */
listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem,
&xSuspendedTaskList );
listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem ); listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem );
/* API Call */ /* API Call */

View file

@ -35,9 +35,11 @@
#include "mock_list_macros.h" #include "mock_list_macros.h"
#include "mock_timers.h" #include "mock_timers.h"
#include "mock_portable.h" #include "mock_portable.h"
#include "mock_fake_assert.h"
/* Test includes. */ /* Test includes. */
#include "unity.h" #include "unity.h"
#include "CException.h"
#include "global_vars.h" #include "global_vars.h"
/* C runtime includes. */ /* C runtime includes. */
@ -64,7 +66,6 @@ extern volatile TickType_t xTickCount;
extern volatile UBaseType_t uxTopReadyPriority; extern volatile UBaseType_t uxTopReadyPriority;
extern volatile BaseType_t xSchedulerRunning; extern volatile BaseType_t xSchedulerRunning;
extern volatile TickType_t xPendedTicks; extern volatile TickType_t xPendedTicks;
#ifdef configNUMBER_OF_CORES #ifdef configNUMBER_OF_CORES
extern volatile BaseType_t xYieldPendings[]; extern volatile BaseType_t xYieldPendings[];
#define xYieldPending xYieldPendings[ 0 ] #define xYieldPending xYieldPendings[ 0 ]
@ -75,16 +76,19 @@ extern volatile TickType_t xPendedTicks;
extern volatile BaseType_t xNumOfOverflows; extern volatile BaseType_t xNumOfOverflows;
extern UBaseType_t uxTaskNumber; extern UBaseType_t uxTaskNumber;
extern volatile TickType_t xNextTaskUnblockTime; extern volatile TickType_t xNextTaskUnblockTime;
#ifdef configNUMBER_OF_CORES #ifdef configNUMBER_OF_CORES
extern TaskHandle_t xIdleTaskHandles[]; extern TaskHandle_t xIdleTaskHandles[];
#define xIdleTaskHandle xIdleTaskHandles[ 0 ] #define xIdleTaskHandle xIdleTaskHandles[ 0 ]
#else #else
extern TaskHandle_t xIdleTaskHandle; extern TaskHandle_t xIdleTaskHandle;
#endif #endif
extern volatile UBaseType_t uxSchedulerSuspended; extern volatile UBaseType_t uxSchedulerSuspended;
/**
* @brief CException code for when a configASSERT should be intercepted.
*/
#define configASSERT_E 0xAA101
/* =========================== GLOBAL VARIABLES =========================== */ /* =========================== GLOBAL VARIABLES =========================== */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
@ -119,6 +123,16 @@ static bool port_assert_if_in_isr_called = false;
static bool vApplicationMallocFailedHook_called = false; static bool vApplicationMallocFailedHook_called = false;
/**
* @brief Global counter for the number of assertions in code.
*/
static int assertionFailed = 0;
/**
* @brief Flag which denotes if test need to abort on assertion.
*/
static BaseType_t shouldAbortOnAssertion = pdFALSE;
/* =========================== Static Functions =========================== */ /* =========================== Static Functions =========================== */
static void start_scheduler() static void start_scheduler()
{ {
@ -325,10 +339,11 @@ void vFakePortYieldFromISR()
HOOK_DIAG(); HOOK_DIAG();
} }
void vFakePortDisableInterrupts() uint32_t vFakePortDisableInterrupts()
{ {
port_disable_interrupts_called = true; port_disable_interrupts_called = true;
HOOK_DIAG(); HOOK_DIAG();
return 0;
} }
void vFakePortEnableInterrupts() void vFakePortEnableInterrupts()
@ -389,6 +404,48 @@ void vApplicationStackOverflowHook( TaskHandle_t xTask,
vApplicationStackOverflowHook_called = true; vApplicationStackOverflowHook_called = true;
} }
unsigned int vFakePortGetCoreID( void )
{
HOOK_DIAG();
return 0;
}
void vFakePortReleaseTaskLock( void )
{
HOOK_DIAG();
}
void vFakePortGetTaskLock( void )
{
HOOK_DIAG();
}
void vFakePortGetISRLock( void )
{
HOOK_DIAG();
}
void vFakePortReleaseISRLock( void )
{
HOOK_DIAG();
}
static void vFakeAssertStub( bool x,
char * file,
int line,
int cmock_num_calls )
{
if( !x )
{
assertionFailed++;
if( shouldAbortOnAssertion == pdTRUE )
{
Throw( configASSERT_E );
}
}
}
/* ============================ Unity Fixtures ============================ */ /* ============================ Unity Fixtures ============================ */
/*! called before each testcase */ /*! called before each testcase */
void setUp( void ) void setUp( void )
@ -427,8 +484,9 @@ void setUp( void )
/*ulTotalRunTime = 0UL; */ /*ulTotalRunTime = 0UL; */
is_first_task = true; is_first_task = true;
created_tasks = 0; created_tasks = 0;
py_operation = dummy_operation; py_operation = dummy_operation;
vFakeAssert_StubWithCallback( vFakeAssertStub );
} }
/*! called after each testcase */ /*! called after each testcase */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,144 @@
/*
* FreeRTOS V202212.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
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "fake_assert.h"
/* XXX: this file will be processed by unifdef to generate new header files
* that can be mocked according to the configurations desired
* it has a few limitations on the format of this file such as:
* no config that spans more than one line
* no strings in config names
* for more info please check the man file with $ man unifdef
*/
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configUSE_TICKLESS_IDLE 1
#define configUSE_TIME_SLICING 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 1
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) /* For test. */
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 /* As there are a lot of tasks running. */
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 9 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 0
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define configENABLE_MPU 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define portSTACK_GROWTH ( -1 )
#define configRECORD_STACK_HIGH_ADDRESS 1
/* This demo makes use of one or more example stats formatting functions. These
* format the raw data provided by the uxTaskGetSystemState() function in to human
* readable ASCII form. See the notes in the implementation of vTaskList() within
* FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
/* Set the following definitions to 1 to include the API function, or zero
* to exclude the API function. In most cases the linker will remove unused
* functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
/* *INDENT-OFF* */
#define configASSERT( x ) do { if( x ) { vFakeAssert( true, __FILE__, __LINE__ ); } else { vFakeAssert( false, __FILE__, __LINE__ ); } } while( 0 )
/* *INDENT-ON* */
#define portREMOVE_STATIC_QUALIFIER 1
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,77 @@
SHELL += -x
# Indent with spaces
.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX)
# Do not move this line below the include
MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
#PROJECT := tasks
# Project / Suite are determined based on path: $(UT_ROOT_DIR)/$(PROJECT)/$(SUITE)
PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)/../))))
SUITE := $(lastword $(subst /, ,$(dir $(MAKEFILE_ABSPATH))))
SCRATCH_DIR := $(GENERATED_DIR)/$(PROJECT)/$(SUITE)
include ../../makefile.in
# PROJECT_SRC lists the .c files under test
PROJECT_SRC += tasks.c
PROJECT_DIR := $(abspath ../)
LOCAL_DIR := $(abspath .)
# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files
# Files in PROJECT_DEPS_SRC are excluded from coverage measurements
PROJECT_DEPS_SRC +=
# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements.
PROJECT_HEADER_DEPS += FreeRTOS.h
# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c)
SUITE_UT_SRC := tasks_utest.c
# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases.
# Paths are relative to PROJECT_DIR
SUITE_SUPPORT_SRC +=
# List the headers used by PROJECT_SRC that you would like to mock
MOCK_FILES_ORIG := $(KERNEL_DIR)/include/timers.h
MOCK_FILES_ORIG += $(KERNEL_DIR)/include/list.h
MOCK_FILES_ORIG += $(KERNEL_DIR)/include/portable.h
MOCK_FILES_ORIG += $(PROJECT_DIR)/list_macros.h
MOCK_FILES_ORIG += $(PROJECT_DIR)/../config/fake_assert.h
MOCK_FILES_FP := $(GENERATED_DIR)/$(PROJECT)/tasks_freertos/timers.h
MOCK_FILES_FP += $(GENERATED_DIR)/$(PROJECT)/tasks_freertos/list.h
MOCK_FILES_FP += $(GENERATED_DIR)/$(PROJECT)/tasks_freertos/portable.h
MOCK_FILES_FP += $(GENERATED_DIR)/$(PROJECT)/tasks_freertos/list_macros.h
MOCK_FILES_FP += $(GENERATED_DIR)/$(PROJECT)/tasks_freertos/fake_assert.h
# List any addiitonal flags needed by the preprocessor
CPPFLAGS := -I $(GENERATED_DIR)/$(PROJECT)/tasks_freertos/include $(CPPFLAGS)
CPPFLAGS += -I .
CPPFLAGS += -I ../
# List any addiitonal flags needed by the compiler
CFLAGS +=
export
# Make variables available to included makefile
include ../../testdir.mk
$(MOCK_FILES_FP) :
-mkdir -p $(SCRATCH_DIR)/include
-mkdir -p $(SCRATCH_DIR)/cpp
cp $(LOCAL_DIR)/FreeRTOSConfig.h $(SCRATCH_DIR)/include/FreeRTOSConfig.h
cp $(LOCAL_DIR)/FreeRTOSConfig.h $(SCRATCH_DIR)/include/FreeRTOSConfig.def
cp $(LOCAL_DIR)/FreeRTOS.h $(SCRATCH_DIR)/include/
sed -i '/#ifndef FREERTOS_CONFIG_H/d' $(SCRATCH_DIR)/include/FreeRTOSConfig.def
sed -i '/#define FREERTOS_CONFIG_H/d' $(SCRATCH_DIR)/include/FreeRTOSConfig.def
sed -i '/#endif/d' $(SCRATCH_DIR)/include/FreeRTOSConfig.def
sed -i '/#include/d' $(SCRATCH_DIR)/include/FreeRTOSConfig.def
for h_file in $(MOCK_FILES_ORIG) ; do \
unifdef -f $(SCRATCH_DIR)/include/FreeRTOSConfig.def $$h_file \
> $(SCRATCH_DIR)/$$(basename $$h_file) ; \
done

View file

@ -0,0 +1,359 @@
/*
* FreeRTOS V202212.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 tasks_assert_utest.c */
/* =============================== INCLUDES =============================== */
/* Tasks includes */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "fake_port.h"
#include "task.h"
#include "portmacro.h"
/* C runtime includes. */
#include <stdlib.h>
#include <stdbool.h>
/* Test includes. */
#include "unity.h"
#include "unity_memory.h"
#include "CException.h"
#include "global_vars.h"
/* Mock includes. */
#include "mock_fake_assert.h"
#include "mock_portable.h"
/* ================================= MACROS =============================== */
/**
* @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 Flag which denotes if test need to abort on assertion.
*/
static BaseType_t shouldAbortOnAssertion;
/**
* @brief counts entries to critical sections then subtracts from the variable
* when exiting, value should be zero at the end
*/
static uint32_t critical_section_counter = 0;
static bool port_yield_within_api_called = false;
static port_yield_operation py_operation;
static bool port_disable_interrupts_called = false;
static bool port_enable_interrupts_called = false;
static bool port_yield_called = false;
static bool port_setup_tcb_called = false;
static bool portClear_Interrupt_called = false;
static bool portSet_Interrupt_called = false;
static bool portClear_Interrupt_from_isr_called = false;
static bool portSet_Interrupt_from_isr_called = false;
static bool port_invalid_interrupt_called = false;
static bool vApplicationStackOverflowHook_called = false;
static bool getIdleTaskMemoryValid = false;
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
static bool getIdleTaskMemory_called = false;
static bool vTaskDeletePre_called = false;
static bool vApplicationIdleHook_called = false;
static bool vApplicationTickHook_called = false;
/* ========================== CALLBACK FUNCTIONS ========================== */
static void vFakeAssertStub( bool x,
char * file,
int line,
int cmock_num_calls )
{
if( !x )
{
assertionFailed++;
if( shouldAbortOnAssertion == pdTRUE )
{
Throw( configASSERT_E );
}
}
}
/* ========================== STATIC FUNCTIONS ============================ */
static void validate_and_clear_assertions( void )
{
TEST_ASSERT_EQUAL( 1, assertionFailed );
assertionFailed = 0;
}
/* ======================== HOOK FUNCTIONS =================================*/
void vApplicationTickHook()
{
HOOK_DIAG();
vApplicationTickHook_called = true;
}
void vApplicationIdleHook( void )
{
HOOK_DIAG();
vApplicationIdleHook_called = true;
}
void vConfigureTimerForRunTimeStats( void )
{
HOOK_DIAG();
}
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{
HOOK_DIAG();
if( getIdleTaskMemoryValid == true )
{
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
* state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
else
{
*ppxIdleTaskTCBBuffer = NULL;
*ppxIdleTaskStackBuffer = NULL;
*pulIdleTaskStackSize = 0;
}
getIdleTaskMemory_called = true;
}
void vPortCurrentTaskDying( void * pvTaskToDelete,
volatile BaseType_t * pxPendYield )
{
HOOK_DIAG();
vTaskDeletePre_called = true;
}
void vFakePortEnterCriticalSection( void )
{
HOOK_DIAG();
critical_section_counter++;
}
void vFakePortExitCriticalSection( void )
{
HOOK_DIAG();
critical_section_counter--;
}
void vFakePortYieldWithinAPI()
{
HOOK_DIAG();
port_yield_within_api_called = true;
py_operation();
}
void vFakePortYieldFromISR()
{
HOOK_DIAG();
}
uint32_t vFakePortDisableInterrupts()
{
port_disable_interrupts_called = true;
HOOK_DIAG();
return 0;
}
void vFakePortEnableInterrupts()
{
port_enable_interrupts_called = true;
HOOK_DIAG();
}
void vFakePortYield()
{
HOOK_DIAG();
port_yield_called = true;
py_operation();
}
void portSetupTCB_CB( void * tcb )
{
HOOK_DIAG();
port_setup_tcb_called = true;
}
void vFakePortClearInterruptMask( UBaseType_t bt )
{
HOOK_DIAG();
portClear_Interrupt_called = true;
}
UBaseType_t ulFakePortSetInterruptMask( void )
{
HOOK_DIAG();
portSet_Interrupt_called = true;
return 1;
}
void vFakePortClearInterruptMaskFromISR( UBaseType_t bt )
{
HOOK_DIAG();
portClear_Interrupt_from_isr_called = true;
}
UBaseType_t ulFakePortSetInterruptMaskFromISR( void )
{
HOOK_DIAG();
portSet_Interrupt_from_isr_called = true;
return 1;
}
void vFakePortAssertIfInterruptPriorityInvalid( void )
{
HOOK_DIAG();
port_invalid_interrupt_called = true;
}
void vApplicationStackOverflowHook( TaskHandle_t xTask,
char * stack )
{
HOOK_DIAG();
vApplicationStackOverflowHook_called = true;
}
unsigned int vFakePortGetCoreID( void )
{
HOOK_DIAG();
return 0;
}
void vFakePortReleaseTaskLock( void )
{
HOOK_DIAG();
}
void vFakePortGetTaskLock( void )
{
HOOK_DIAG();
}
void vFakePortGetISRLock( void )
{
HOOK_DIAG();
}
void vFakePortReleaseISRLock( void )
{
HOOK_DIAG();
}
/* =========================== UNITY FIXTURES ============================= */
/*! called before each test case */
void setUp( void )
{
assertionFailed = 0;
shouldAbortOnAssertion = pdTRUE;
vFakeAssert_StubWithCallback( vFakeAssertStub );
}
/*! called after each test case */
void tearDown( void )
{
TEST_ASSERT_EQUAL_MESSAGE( 0, assertionFailed, "Assertion check failed in code." );
mock_fake_assert_Verify();
mock_fake_assert_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;
}
/* ======================== TEST CASES ===================================== */
void test_xTaskCreateStatic_assert_static_task_eq_tcb_t( void )
{
TaskFunction_t xTFunc = NULL;
StaticTask_t xTaskBuffer[ 200 ];
StackType_t xStackBuffer[ 200 ];
EXPECT_ASSERT_BREAK( xTaskCreateStatic( xTFunc,
NULL,
120,
NULL,
3,
xStackBuffer,
xTaskBuffer ) );
validate_and_clear_assertions();
}

View file

@ -219,6 +219,19 @@ static void xCallback_Test_2_end( TimerHandle_t xTimer )
* pthread_exit( &i ); * pthread_exit( &i );
* } * }
*/ */
/**
* @brief Callback for vTaskYieldTaskWithinAPI used by tests for yield counts
*
* NumCalls is checked in the test assert.
*/
static void vTaskYieldWithinAPI_Callback( int NumCalls )
{
( void ) NumCalls;
portYIELD_WITHIN_API();
}
/* ============================= STATIC FUNCTIONS ========================= */ /* ============================= STATIC FUNCTIONS ========================= */
static void * timer_thread_function( void * args ) static void * timer_thread_function( void * args )
{ {
@ -823,6 +836,7 @@ void test_timer_function_success3( void )
vQueueWaitForMessageRestricted_ExpectAnyArgs(); vQueueWaitForMessageRestricted_ExpectAnyArgs();
xTaskResumeAll_ExpectAndReturn( pdFALSE ); /* no context switch.. yield */ xTaskResumeAll_ExpectAndReturn( pdFALSE ); /* no context switch.. yield */
/* yield called */ /* yield called */
vTaskYieldWithinAPI_Stub( vTaskYieldWithinAPI_Callback );
/* API Call */ /* API Call */
pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); pthread_create( &thread_id, NULL, &timer_thread_function, NULL );

View file

@ -5,7 +5,7 @@ license: "MIT"
dependencies: dependencies:
- name: "FreeRTOS-Kernel" - name: "FreeRTOS-Kernel"
version: "4ada1d7d5" version: "5281427a9"
repository: repository:
type: "git" type: "git"
url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git" url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"