From c011734cfed371d79b8aa1ce0c523b1c1ea89435 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Tue, 29 Nov 2022 07:23:27 +0000 Subject: [PATCH 001/109] Fix compile warnings and MISRA 2012 C Rule 1.1. --- tasks.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tasks.c b/tasks.c index ae37b89d275..043edd805f9 100644 --- a/tasks.c +++ b/tasks.c @@ -1650,7 +1650,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, pxNewTCB->xTaskRunState = taskTASK_NOT_RUNNING; /* Is this an idle task? */ - if( ( pxTaskCode == prvIdleTask ) || ( pxTaskCode == prvMinimalIdleTask ) ) + if( ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) prvIdleTask ) || ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) prvMinimalIdleTask ) ) { pxNewTCB->uxTaskAttributes |= taskATTRIBUTE_IS_IDLE; } @@ -2179,7 +2179,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * suspended. */ eReturn = eSuspended; - for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) + for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) { if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION ) { @@ -7272,8 +7272,9 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) { configRUN_TIME_COUNTER_TYPE ulReturn = 0; + BaseType_t i = 0; - for( BaseType_t i = 0; i < configNUMBER_OF_CORES; i++ ) + for( i = ( BaseType_t ) 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) { ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; } @@ -7290,6 +7291,7 @@ TickType_t uxTaskResetEventItemValue( void ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; + BaseType_t i = 0; ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES; @@ -7299,7 +7301,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - for( BaseType_t i = 0; i < configNUMBER_OF_CORES; i++ ) + for( i = ( BaseType_t ) 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) { ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; } From abc85d32017d58d6f004161dea9b747fd0ab5201 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Tue, 29 Nov 2022 08:08:05 +0000 Subject: [PATCH 002/109] Fix MISRA C 2012 Directive 4.6. --- MISRA.md | 18 ++++++++++++++++++ tasks.c | 3 +++ 2 files changed, 21 insertions(+) create mode 100644 MISRA.md diff --git a/MISRA.md b/MISRA.md new file mode 100644 index 00000000000..000c53adc53 --- /dev/null +++ b/MISRA.md @@ -0,0 +1,18 @@ +# MISRA Compliance + +For now, FreeRTOS-Kernel only conforms [MISRA C:2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx) guidelines in SMP part (configNUM_CORES > 1), +with the deviations listed below. Compliance is checked with Coverity static analysis. + +### Suppressed with Coverity Comments +To find the violation references in the source files run grep on the source code +with ( Assuming rule 4.6 violation; with justification in point 1 ): +``` +grep 'MISRA Ref 4.6.1' . -rI +``` +#### Directive 4.6 + +_Ref 4.6.1_ + +- MISRA C:2012 Directive 4.6: typedef that indicate size and signedness should be used in place of the basic numerical types. + MISRA warns against the use of basic numerical types. FreeRTOS-Kerenl + uses BaseType_t/UBaseType_t to represent signed/unsigned variables no matter it's 16 or 32 bits. diff --git a/tasks.c b/tasks.c index 043edd805f9..ab8204c4ba6 100644 --- a/tasks.c +++ b/tasks.c @@ -679,6 +679,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * core is no longer running, then vTaskSwitchContext() probably should * be run before returning, but we don't have a way to force that to happen * from here. */ + /* MISRA Ref 4.6.1 [typedef indicates size and signedness] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#directive-46 */ + /* coverity[misra_c_2012_directive_4_6_violation] */ if( portCHECK_IF_IN_ISR() == pdFALSE ) { /* This function is always called with interrupts disabled From 3b05ababe67463952d15a2c22a5b8a1221a28026 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Tue, 29 Nov 2022 08:18:12 +0000 Subject: [PATCH 003/109] Fix MISRA C 2012 Rule 1.1. --- include/task.h | 2 +- tasks.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/task.h b/include/task.h index 458c46503d9..ff5b4cb3ffe 100644 --- a/include/task.h +++ b/include/task.h @@ -271,7 +271,7 @@ typedef enum #define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) /* Checks if core ID is valid. */ -#define taskVALID_CORE_ID( xCoreID ) ( ( BaseType_t ) ( ( 0 <= xCoreID ) && ( xCoreID < configNUMBER_OF_CORES ) ) ) +#define taskVALID_CORE_ID( xCoreID ) ( ( ( ( BaseType_t ) 0 <= xCoreID ) && ( xCoreID < ( BaseType_t ) configNUMBER_OF_CORES ) ) ) /*----------------------------------------------------------- * TASK CREATION API diff --git a/tasks.c b/tasks.c index ab8204c4ba6..65446fd2dfe 100644 --- a/tasks.c +++ b/tasks.c @@ -1787,7 +1787,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, BaseType_t xCoreID; /* Check if a core is free. */ - for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ ) + for( xCoreID = ( BaseType_t ) 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) { if( pxCurrentTCBs[ xCoreID ] == NULL ) { @@ -2702,7 +2702,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { BaseType_t x; - for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) + for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) { if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION ) { @@ -3140,7 +3140,7 @@ static BaseType_t prvCreateIdleTasks( void ) cIdleName[ x++ ] = ( char ) xCoreID + '0'; /* And append a null character if there is space. */ - if( x < configMAX_TASK_NAME_LEN ) + if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) { cIdleName[ x ] = '\0'; } From cb1733588ecc5ca265bc7b019c44102d61a82641 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Tue, 29 Nov 2022 09:27:42 +0000 Subject: [PATCH 004/109] Fix MISRA C 2012 Rule 17.3. --- MISRA.md | 14 ++++++++++++++ tasks.c | 23 +++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/MISRA.md b/MISRA.md index 000c53adc53..541499c2906 100644 --- a/MISRA.md +++ b/MISRA.md @@ -16,3 +16,17 @@ _Ref 4.6.1_ - MISRA C:2012 Directive 4.6: typedef that indicate size and signedness should be used in place of the basic numerical types. MISRA warns against the use of basic numerical types. FreeRTOS-Kerenl uses BaseType_t/UBaseType_t to represent signed/unsigned variables no matter it's 16 or 32 bits. + +#### Rule 17.3 + +_Ref 17.3.1_ + +- MISRA C:2012 Rule 17.3: A function shall not be declared implicitly. + MISRA warns against the function declared implicitly. It's a false alarm that + portCHECK_IF_IN_ISR() is declared in portmacro.h correctly. + +_Ref 17.3.2_ + +- MISRA C:2012 Rule 17.3: A function shall not be declared implicitly. + MISRA warns against the function declared implicitly. It's a false alarm that + portGET_RUN_TIME_COUNTER_VALUE() is declared in portmacro.h correctly. diff --git a/tasks.c b/tasks.c index 65446fd2dfe..70724eb5dd9 100644 --- a/tasks.c +++ b/tasks.c @@ -381,7 +381,12 @@ typedef tskTCB TCB_t; #if ( configNUMBER_OF_CORES == 1 ) portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; #else -portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { NULL }; + /* MISRA Ref 8.4.1 [Declaration shall be visible] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* coverity[misra_c_2012_rule_8_4_violation] */ + portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { + [0 ... configNUMBER_OF_CORES-1] = NULL, + }; #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif @@ -425,7 +430,9 @@ PRIVILEGED_DATA static volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ -PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = { NULL }; /*< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = { /*< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ + [0 ... configNUMBER_OF_CORES-1] = NULL, +}; /* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. * For tracking the state of remote threads, OpenOCD uses uxTopUsedPriority @@ -681,7 +688,10 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * from here. */ /* MISRA Ref 4.6.1 [typedef indicates size and signedness] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#directive-46 */ + /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ /* coverity[misra_c_2012_directive_4_6_violation] */ + /* coverity[misra_c_2012_rule_17_3_violation] */ if( portCHECK_IF_IN_ISR() == pdFALSE ) { /* This function is always called with interrupts disabled @@ -753,6 +763,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; static void prvYieldCore( BaseType_t xCoreID ) { /* This must be called from a critical section and xCoreID must be valid. */ + /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ + /* coverity[misra_c_2012_rule_17_3_violation] */ if( portCHECK_IF_IN_ISR() && ( xCoreID == portGET_CORE_ID() ) ) { xYieldPendings[ xCoreID ] = pdTRUE; @@ -4532,6 +4545,9 @@ BaseType_t xTaskIncrementTick( void ) #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); #else + /* MISRA Ref 17.3.2 [Function shall not be declared implicitly] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ + /* coverity[misra_c_2012_rule_17_3_violation] */ ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); #endif @@ -7296,6 +7312,9 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; BaseType_t i = 0; + /* MISRA Ref 17.3.2 [Function shall not be declared implicitly] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ + /* coverity[misra_c_2012_rule_17_3_violation] */ ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES; /* For percentage calculations. */ From 516fc6febfd936e1a911ce863d0f177ee517df18 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Tue, 29 Nov 2022 09:59:59 +0000 Subject: [PATCH 005/109] Fix MISRA C 2012 Rule 8.3. --- MISRA.md | 7 +++++++ include/task.h | 2 +- tasks.c | 9 ++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/MISRA.md b/MISRA.md index 541499c2906..d4e5105645e 100644 --- a/MISRA.md +++ b/MISRA.md @@ -17,6 +17,13 @@ _Ref 4.6.1_ MISRA warns against the use of basic numerical types. FreeRTOS-Kerenl uses BaseType_t/UBaseType_t to represent signed/unsigned variables no matter it's 16 or 32 bits. +#### Rule 8.3 + +_Ref 8.3.1_ + +- MISRA C:2012 Rule 8.3: All declarations of an object or functionn shall use the same names and type qualifiers. + It's a false alarm that portCHECK_IF_IN_ISR() is only declared in portmacro.h. + #### Rule 17.3 _Ref 17.3.1_ diff --git a/include/task.h b/include/task.h index ff5b4cb3ffe..b7b039ae0eb 100644 --- a/include/task.h +++ b/include/task.h @@ -271,7 +271,7 @@ typedef enum #define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) /* Checks if core ID is valid. */ -#define taskVALID_CORE_ID( xCoreID ) ( ( ( ( BaseType_t ) 0 <= xCoreID ) && ( xCoreID < ( BaseType_t ) configNUMBER_OF_CORES ) ) ) +#define taskVALID_CORE_ID( xCoreID ) ( ( ( ( BaseType_t ) 0 <= ( xCoreID ) ) && ( ( xCoreID ) < ( BaseType_t ) configNUMBER_OF_CORES ) ) ) /*----------------------------------------------------------- * TASK CREATION API diff --git a/tasks.c b/tasks.c index 70724eb5dd9..e5976dc545b 100644 --- a/tasks.c +++ b/tasks.c @@ -270,11 +270,11 @@ typedef BaseType_t TaskRunning_t; * but scheduled to yield. */ #if ( configNUMBER_OF_CORES == 1 ) - #define taskTASK_IS_RUNNING( pxTCB ) ( pxTCB == pxCurrentTCB ) + #define taskTASK_IS_RUNNING( pxTCB ) ( ( pxTCB ) == pxCurrentTCB ) #define taskTASK_IS_YIELDING( pxTCB ) ( pdFALSE ) #else - #define taskTASK_IS_RUNNING( pxTCB ) ( ( pxTCB->xTaskRunState >= 0 ) && ( pxTCB->xTaskRunState < configNUMBER_OF_CORES ) ) - #define taskTASK_IS_YIELDING( pxTCB ) ( pxTCB->xTaskRunState == taskTASK_YIELDING ) + #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( pxTCB )->xTaskRunState >= 0 ) && ( ( pxTCB )->xTaskRunState < configNUMBER_OF_CORES ) ) + #define taskTASK_IS_YIELDING( pxTCB ) ( ( pxTCB )->xTaskRunState == taskTASK_YIELDING ) #endif /* Indicates that the task is an Idle task. */ @@ -688,9 +688,12 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * from here. */ /* MISRA Ref 4.6.1 [typedef indicates size and signedness] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#directive-46 */ + /* MISRA Ref 8.3.1 [Declarations shall be same] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-83 */ /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ /* coverity[misra_c_2012_directive_4_6_violation] */ + /* coverity[misra_c_2012_rule_8_3_violation] */ /* coverity[misra_c_2012_rule_17_3_violation] */ if( portCHECK_IF_IN_ISR() == pdFALSE ) { From 3466371e0504ddf14359b42566fbc8ac8cb1e13a Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Tue, 29 Nov 2022 10:04:05 +0000 Subject: [PATCH 006/109] Fix MISRA C 2012 Rule 8.4. --- MISRA.md | 7 +++++++ tasks.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/MISRA.md b/MISRA.md index d4e5105645e..3cce53fa567 100644 --- a/MISRA.md +++ b/MISRA.md @@ -24,6 +24,13 @@ _Ref 8.3.1_ - MISRA C:2012 Rule 8.3: All declarations of an object or functionn shall use the same names and type qualifiers. It's a false alarm that portCHECK_IF_IN_ISR() is only declared in portmacro.h. +#### Rule 8.4 + +_Ref 8.4.1_ + +- MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an object or function with external linkage is defined. + vTaskEnterCriticalFromISR()/vTaskExitCriticalFromISR are used at some ports. + #### Rule 17.3 _Ref 17.3.1_ diff --git a/tasks.c b/tasks.c index e5976dc545b..1bfb028891d 100644 --- a/tasks.c +++ b/tasks.c @@ -6189,6 +6189,9 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) + /* MISRA Ref 8.4.1 [Declaration shall be visible] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* coverity[misra_c_2012_rule_8_4_violation] */ UBaseType_t vTaskEnterCriticalFromISR( void ) { UBaseType_t uxSavedInterruptStatus = 0; @@ -6315,6 +6318,9 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) + /* MISRA Ref 8.4.1 [Declaration shall be visible] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* coverity[misra_c_2012_rule_8_4_violation] */ void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ) { BaseType_t xYieldCurrentTask; From 80785f9c97c1d3c5b6e516ff0bcaba25ffc65e10 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 03:01:45 +0000 Subject: [PATCH 007/109] Fix CHECKED_RETURN. --- tasks.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasks.c b/tasks.c index 1bfb028891d..5f58102dd9c 100644 --- a/tasks.c +++ b/tasks.c @@ -673,6 +673,10 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #endif +#if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) + extern void vApplicationMinimalIdleHook( void ); +#endif /* ( configUSE_MINIMAL_IDLE_HOOK == 1 ) */ + /*-----------------------------------------------------------*/ #if ( configNUMBER_OF_CORES > 1 ) @@ -991,7 +995,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; { /* Once a task has been selected to run on this core, * move it to the end of the ready task list. */ - uxListRemove( pxIterator ); + ( void ) uxListRemove( pxIterator ); vListInsertEnd( pxReadyList, pxIterator ); break; } @@ -5039,8 +5043,6 @@ void vTaskMissedYield( void ) #if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) { - extern void vApplicationMinimalIdleHook( void ); - /* Call the user defined function from within the idle task. This * allows the application designer to add background functionality * without the overhead of a separate task. @@ -5192,8 +5194,6 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_MINIMAL_IDLE_HOOK == 1 ) ) { - extern void vApplicationMinimalIdleHook( void ); - /* Call the user defined function from within the idle task. This * allows the application designer to add background functionality * without the overhead of a separate task. From 65fa1bb7dd7acf8b60f4c178dafafff4bc3e7985 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 03:15:10 +0000 Subject: [PATCH 008/109] Fix MISRA C 2012 Rule 10.1. --- include/task.h | 2 +- tasks.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/task.h b/include/task.h index b7b039ae0eb..8744676ab8d 100644 --- a/include/task.h +++ b/include/task.h @@ -193,7 +193,7 @@ typedef enum * * \ingroup TaskUtils */ -#define tskNO_AFFINITY ( ( UBaseType_t ) -1U ) +#define tskNO_AFFINITY ( ( UBaseType_t ) -1 ) /** * task. h diff --git a/tasks.c b/tasks.c index 5f58102dd9c..7e9bc3f09b3 100644 --- a/tasks.c +++ b/tasks.c @@ -773,7 +773,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ /* coverity[misra_c_2012_rule_17_3_violation] */ - if( portCHECK_IF_IN_ISR() && ( xCoreID == portGET_CORE_ID() ) ) + if( portCHECK_IF_IN_ISR() == pdTRUE && ( xCoreID == portGET_CORE_ID() ) ) { xYieldPendings[ xCoreID ] = pdTRUE; } @@ -840,7 +840,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( xCurrentCoreTaskPriority <= xLowestPriorityToPreempt ) { #if ( configUSE_CORE_AFFINITY == 1 ) - if( ( pxTCB->uxCoreAffinityMask & ( 1 << xCoreID ) ) != 0 ) + if( ( pxTCB->uxCoreAffinityMask & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) #endif { #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) @@ -959,7 +959,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( pxTCB->xTaskRunState == taskTASK_NOT_RUNNING ) { #if ( configUSE_CORE_AFFINITY == 1 ) - if( ( pxTCB->uxCoreAffinityMask & ( 1 << xCoreID ) ) != 0 ) + if( ( pxTCB->uxCoreAffinityMask & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) #endif { /* If the task is not being executed by any core swap it in. */ @@ -977,7 +977,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; configASSERT( ( pxTCB->xTaskRunState == xCoreID ) || ( pxTCB->xTaskRunState == taskTASK_YIELDING ) ); #if ( configUSE_CORE_AFFINITY == 1 ) - if( ( pxTCB->uxCoreAffinityMask & ( 1 << xCoreID ) ) != 0 ) + if( ( pxTCB->uxCoreAffinityMask & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) #endif { /* The task is already running on this core, mark it as scheduled. */ @@ -1066,7 +1066,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; xLowestPriority = xLowestPriority - 1; } - if( ( uxCoreMap & ( 1 << xCoreID ) ) != 0 ) + if( ( uxCoreMap & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0 ) { /* The ready task that was removed from this core is not excluded from it. * Only look at the intersection of the cores the removed task is allowed to run @@ -1080,7 +1080,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* The ready task that was removed from this core is excluded from it. */ } - uxCoreMap &= ( ( 1 << configNUMBER_OF_CORES ) - 1 ); + uxCoreMap &= ( ( 1U << configNUMBER_OF_CORES ) - 1U ); for( x = ( configNUMBER_OF_CORES - 1 ); x >= 0; x-- ) { @@ -1096,7 +1096,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; xTaskPriority = xTaskPriority - ( BaseType_t ) 1; } - uxCoreMap &= ~( 1 << uxCore ); + uxCoreMap &= ~( 1U << uxCore ); if( ( xTaskPriority < xLowestPriority ) && ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) && @@ -2574,7 +2574,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If the task can no longer run on the core it was running, * request the core to yield. */ - if( ( uxCoreAffinityMask & ( 1 << xCoreID ) ) == 0 ) + if( ( uxCoreAffinityMask & ( 1U << ( UBaseType_t ) xCoreID ) ) == 0U ) { prvYieldCore( xCoreID ); } From a9cbaa123a54c12a286d8d4ac68cc9a3fb5b5c29 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 03:17:12 +0000 Subject: [PATCH 009/109] Fix MISRA C 2012 Rule 10.2. --- tasks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks.c b/tasks.c index 7e9bc3f09b3..8fdb5a7ca1e 100644 --- a/tasks.c +++ b/tasks.c @@ -3155,9 +3155,9 @@ static BaseType_t prvCreateIdleTasks( void ) } /* Append the idle task number to the end of the name if there is space. */ - if( x < configMAX_TASK_NAME_LEN ) + if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) { - cIdleName[ x++ ] = ( char ) xCoreID + '0'; + cIdleName[ x++ ] = ( char ) ( xCoreID + '0' ); /* And append a null character if there is space. */ if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) From 1e14c659877b99900e94f38b0f95774c3dbb2d7e Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 03:28:37 +0000 Subject: [PATCH 010/109] Fix MISRA C 2012 Rule 10.3. --- tasks.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks.c b/tasks.c index 8fdb5a7ca1e..45687b26b33 100644 --- a/tasks.c +++ b/tasks.c @@ -1057,7 +1057,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* A ready task was just evicted from this core. See if it can be * scheduled on any other core. */ UBaseType_t uxCoreMap = pxPreviousTCB->uxCoreAffinityMask; - BaseType_t xLowestPriority = pxPreviousTCB->uxPriority; + BaseType_t xLowestPriority = ( BaseType_t ) pxPreviousTCB->uxPriority; BaseType_t xLowestPriorityCore = -1; BaseType_t x; @@ -1107,7 +1107,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #endif { xLowestPriority = xTaskPriority; - xLowestPriorityCore = uxCore; + xLowestPriorityCore = ( BaseType_t) uxCore; } } } @@ -4297,7 +4297,7 @@ BaseType_t xTaskIncrementTick( void ) } else { - prvYieldCore( x ); + prvYieldCore( ( BaseType_t ) x ); } } else From 7857976d3bd78e97906a7d324357d59adbaad415 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 03:40:31 +0000 Subject: [PATCH 011/109] Fix MISRA C 2012 Rule 10.4. --- tasks.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tasks.c b/tasks.c index 45687b26b33..baa6732ff12 100644 --- a/tasks.c +++ b/tasks.c @@ -273,7 +273,7 @@ typedef BaseType_t TaskRunning_t; #define taskTASK_IS_RUNNING( pxTCB ) ( ( pxTCB ) == pxCurrentTCB ) #define taskTASK_IS_YIELDING( pxTCB ) ( pdFALSE ) #else - #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( pxTCB )->xTaskRunState >= 0 ) && ( ( pxTCB )->xTaskRunState < configNUMBER_OF_CORES ) ) + #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( pxTCB )->xTaskRunState >= ( BaseType_t ) 0 ) && ( ( pxTCB )->xTaskRunState < ( BaseType_t ) configNUMBER_OF_CORES ) ) #define taskTASK_IS_YIELDING( pxTCB ) ( ( pxTCB )->xTaskRunState == taskTASK_YIELDING ) #endif @@ -830,12 +830,12 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; xCurrentCoreTaskPriority = ( BaseType_t ) pxCurrentTCBs[ xCoreID ]->uxPriority; /* System idle tasks are being assigned a priority of tskIDLE_PRIORITY - 1 here. */ - if( ( pxCurrentTCBs[ xCoreID ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0 ) + if( ( pxCurrentTCBs[ xCoreID ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) { xCurrentCoreTaskPriority = xCurrentCoreTaskPriority - 1; } - if( ( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCoreID ] ) != pdFALSE ) && ( xYieldPendings[ xCoreID ] == pdFALSE ) ) + if( ( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCoreID ] ) ) && ( xYieldPendings[ xCoreID ] == pdFALSE ) ) { if( xCurrentCoreTaskPriority <= xLowestPriorityToPreempt ) { @@ -1061,12 +1061,12 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; BaseType_t xLowestPriorityCore = -1; BaseType_t x; - if( ( pxPreviousTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0 ) + if( ( pxPreviousTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) { xLowestPriority = xLowestPriority - 1; } - if( ( uxCoreMap & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0 ) + if( ( uxCoreMap & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) { /* The ready task that was removed from this core is not excluded from it. * Only look at the intersection of the cores the removed task is allowed to run @@ -1082,7 +1082,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; uxCoreMap &= ( ( 1U << configNUMBER_OF_CORES ) - 1U ); - for( x = ( configNUMBER_OF_CORES - 1 ); x >= 0; x-- ) + for( x = ( ( BaseType_t ) configNUMBER_OF_CORES - 1 ); x >= ( BaseType_t ) 0; x-- ) { UBaseType_t uxCore = ( UBaseType_t ) x; BaseType_t xTaskPriority; @@ -1091,7 +1091,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; { xTaskPriority = ( BaseType_t ) pxCurrentTCBs[ uxCore ]->uxPriority; - if( ( pxCurrentTCBs[ uxCore ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0 ) + if( ( pxCurrentTCBs[ uxCore ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) { xTaskPriority = xTaskPriority - ( BaseType_t ) 1; } @@ -1099,7 +1099,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; uxCoreMap &= ~( 1U << uxCore ); if( ( xTaskPriority < xLowestPriority ) && - ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) && + ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) ) && ( xYieldPendings[ uxCore ] == pdFALSE ) ) { #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) @@ -1802,7 +1802,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, mtCOVERAGE_TEST_MARKER(); } - if( ( pxNewTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0 ) + if( ( pxNewTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) { BaseType_t xCoreID; @@ -5766,7 +5766,7 @@ static void prvResetNextTaskUnblockTime( void ) { TaskHandle_t xReturn = NULL; - if( taskVALID_CORE_ID( xCoreID ) != pdFALSE ) + if( taskVALID_CORE_ID( xCoreID ) ) { xReturn = pxCurrentTCBs[ xCoreID ]; } From e9d6e22bded12bee3eec5b05b5a1e6833bff23b6 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 03:59:57 +0000 Subject: [PATCH 012/109] Fix MISRA C 2012 Rule 10.7. --- tasks.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasks.c b/tasks.c index baa6732ff12..746ab5771b2 100644 --- a/tasks.c +++ b/tasks.c @@ -840,7 +840,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( xCurrentCoreTaskPriority <= xLowestPriorityToPreempt ) { #if ( configUSE_CORE_AFFINITY == 1 ) - if( ( pxTCB->uxCoreAffinityMask & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) + if( ( pxTCB->uxCoreAffinityMask & ( ( UBaseType_t ) 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) #endif { #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) @@ -959,7 +959,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( pxTCB->xTaskRunState == taskTASK_NOT_RUNNING ) { #if ( configUSE_CORE_AFFINITY == 1 ) - if( ( pxTCB->uxCoreAffinityMask & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) + if( ( pxTCB->uxCoreAffinityMask & ( UBaseType_t ) ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) #endif { /* If the task is not being executed by any core swap it in. */ @@ -977,7 +977,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; configASSERT( ( pxTCB->xTaskRunState == xCoreID ) || ( pxTCB->xTaskRunState == taskTASK_YIELDING ) ); #if ( configUSE_CORE_AFFINITY == 1 ) - if( ( pxTCB->uxCoreAffinityMask & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) + if( ( pxTCB->uxCoreAffinityMask & ( ( UBaseType_t ) 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) #endif { /* The task is already running on this core, mark it as scheduled. */ @@ -1066,7 +1066,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; xLowestPriority = xLowestPriority - 1; } - if( ( uxCoreMap & ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) + if( ( uxCoreMap & ( ( UBaseType_t ) 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) { /* The ready task that was removed from this core is not excluded from it. * Only look at the intersection of the cores the removed task is allowed to run @@ -1096,7 +1096,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; xTaskPriority = xTaskPriority - ( BaseType_t ) 1; } - uxCoreMap &= ~( 1U << uxCore ); + uxCoreMap &= ( UBaseType_t ) ~( 1U << uxCore ); if( ( xTaskPriority < xLowestPriority ) && ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) ) && @@ -2574,7 +2574,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If the task can no longer run on the core it was running, * request the core to yield. */ - if( ( uxCoreAffinityMask & ( 1U << ( UBaseType_t ) xCoreID ) ) == 0U ) + if( ( uxCoreAffinityMask & ( ( UBaseType_t ) 1U << ( UBaseType_t ) xCoreID ) ) == 0U ) { prvYieldCore( xCoreID ); } From d656d1d1635f13b2c61e2f9511a6cc849b352a6a Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 04:01:49 +0000 Subject: [PATCH 013/109] Fix MISRA C 2012 Rule 10.8. --- tasks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks.c b/tasks.c index 746ab5771b2..2390bdc86d8 100644 --- a/tasks.c +++ b/tasks.c @@ -959,7 +959,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( pxTCB->xTaskRunState == taskTASK_NOT_RUNNING ) { #if ( configUSE_CORE_AFFINITY == 1 ) - if( ( pxTCB->uxCoreAffinityMask & ( UBaseType_t ) ( 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) + if( ( pxTCB->uxCoreAffinityMask & ( ( UBaseType_t ) 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) #endif { /* If the task is not being executed by any core swap it in. */ @@ -1096,7 +1096,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; xTaskPriority = xTaskPriority - ( BaseType_t ) 1; } - uxCoreMap &= ( UBaseType_t ) ~( 1U << uxCore ); + uxCoreMap &= ~( ( UBaseType_t ) 1U << uxCore ); if( ( xTaskPriority < xLowestPriority ) && ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) ) && From 32295e72aa762e21735d5c12335538e8e77ac3bf Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 04:10:24 +0000 Subject: [PATCH 014/109] Fix MISRA C 2012 Rule 11.3. --- MISRA.md | 12 ++++++++++++ tasks.c | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/MISRA.md b/MISRA.md index 3cce53fa567..51bcef10c13 100644 --- a/MISRA.md +++ b/MISRA.md @@ -31,6 +31,18 @@ _Ref 8.4.1_ - MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an object or function with external linkage is defined. vTaskEnterCriticalFromISR()/vTaskExitCriticalFromISR are used at some ports. +#### Rule 11.3 + +_Ref 11.3.1_ + +- MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to object type and a pointer to a different object type. + Unusual cast is ok as the structures are designed to have the same alignment, this is checked by an assert. + +_Ref 11.3.2_ + +- MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to object type and a pointer to a different object type. + The mini list structure is used as the list end to save RAM. This is checked and valid. + #### Rule 17.3 _Ref 17.3.1_ diff --git a/tasks.c b/tasks.c index 2390bdc86d8..c06b074b207 100644 --- a/tasks.c +++ b/tasks.c @@ -930,6 +930,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxCurrentPriority ] ) ) == pdFALSE ) { List_t * const pxReadyList = &( pxReadyTasksLists[ uxCurrentPriority ] ); + /* MISRA Ref 11.3.2 [Cast to different type] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ + /* coverity[misra_c_2012_rule_11_3_violation] */ const ListItem_t * pxEndMarker = listGET_END_MARKER( pxReadyList ); ListItem_t * pxIterator; @@ -1174,6 +1177,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; { /* The memory used for the task's TCB and stack are passed into this * function - use them. */ + /* MISRA Ref 11.3.1 [Cast to different type] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ + /* coverity[misra_c_2012_rule_11_3_violation] */ pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; @@ -1233,6 +1239,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* Allocate space for the TCB. Where the memory comes from depends * on the implementation of the port malloc function and whether or * not static allocation is being used. */ + /* MISRA Ref 11.3.1 [Cast to different type] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ + /* coverity[misra_c_2012_rule_11_3_violation] */ pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer; memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); From ee9a882aae38256c61b0aaf00a6f6ff390e5ba59 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 04:17:18 +0000 Subject: [PATCH 015/109] Fix MISRA C 2012 Rule 11.5. --- MISRA.md | 7 +++++++ tasks.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/MISRA.md b/MISRA.md index 51bcef10c13..f9b85a39c10 100644 --- a/MISRA.md +++ b/MISRA.md @@ -42,6 +42,13 @@ _Ref 11.3.2_ - MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to object type and a pointer to a different object type. The mini list structure is used as the list end to save RAM. This is checked and valid. + +#### Rule 11.5 + +_Ref 11.5.1_ + +- MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to void into pointer to object. + void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. #### Rule 17.3 diff --git a/tasks.c b/tasks.c index c06b074b207..72a5f744575 100644 --- a/tasks.c +++ b/tasks.c @@ -942,6 +942,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; for( pxIterator = listGET_HEAD_ENTRY( pxReadyList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) ) { + /* MISRA Ref 11.5.1 [Cast to different type] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ + /* coverity[misra_c_2012_rule_11_5_violation] */ TCB_t * pxTCB = listGET_LIST_ITEM_OWNER( pxIterator ); #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) @@ -1305,6 +1308,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* Allocate space for the TCB. Where the memory comes from depends * on the implementation of the port malloc function and whether or * not static allocation is being used. */ + /* MISRA Ref 11.5.1 [Cast to different type] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ + /* coverity[misra_c_2012_rule_11_5_violation] */ pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ) From e1a1db9ac78c5c7a5d62a0515ea4852cae2c60ed Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 04:18:08 +0000 Subject: [PATCH 016/109] Fix MISRA C 2012 Rule 12.1. --- tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks.c b/tasks.c index 72a5f744575..e4d0c41f0d3 100644 --- a/tasks.c +++ b/tasks.c @@ -773,7 +773,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ /* coverity[misra_c_2012_rule_17_3_violation] */ - if( portCHECK_IF_IN_ISR() == pdTRUE && ( xCoreID == portGET_CORE_ID() ) ) + if( portCHECK_IF_IN_ISR() && ( xCoreID == portGET_CORE_ID() ) ) { xYieldPendings[ xCoreID ] = pdTRUE; } From 7036d9dc8b90decd9a667e14d66577bf1dd97016 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 04:25:09 +0000 Subject: [PATCH 017/109] Fix MISRA C 2012 Rule 13.3. --- tasks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks.c b/tasks.c index e4d0c41f0d3..d70cc2052b6 100644 --- a/tasks.c +++ b/tasks.c @@ -3172,7 +3172,8 @@ static BaseType_t prvCreateIdleTasks( void ) /* Append the idle task number to the end of the name if there is space. */ if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) { - cIdleName[ x++ ] = ( char ) ( xCoreID + '0' ); + cIdleName[ x ] = ( char ) ( xCoreID + '0' ); + x++; /* And append a null character if there is space. */ if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) From bc39734f6b6f8b46c41fe419ade4489c216cbfbd Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 04:27:57 +0000 Subject: [PATCH 018/109] Fix MISRA C 2012 Rule 14.3. --- MISRA.md | 7 +++++++ tasks.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/MISRA.md b/MISRA.md index f9b85a39c10..204597594ca 100644 --- a/MISRA.md +++ b/MISRA.md @@ -49,6 +49,13 @@ _Ref 11.5.1_ - MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to void into pointer to object. void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. + +#### Rule 14.3 + +_Ref 14.3.1_ + +- MISRA C:2012 Rule 14.3: Controlling expressions shall not be invariant. + The expression is variant with other configuration enabled. #### Rule 17.3 diff --git a/tasks.c b/tasks.c index d70cc2052b6..48cdcdbbdba 100644 --- a/tasks.c +++ b/tasks.c @@ -880,6 +880,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; } } + /* MISRA Ref 14.3.1 [Expression shall not be invariant] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-143 */ + /* coverity[misra_c_2012_rule_14_3_violation] */ if( ( xYieldCount == 0 ) && taskVALID_CORE_ID( xLowestPriorityCore ) ) { prvYieldCore( xLowestPriorityCore ); From 213e8f95086a9714393693c2065dd678c0469d98 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 05:53:33 +0000 Subject: [PATCH 019/109] Fix MISRA C 2012 Rule 17.7. --- tasks.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks.c b/tasks.c index 48cdcdbbdba..65e562348e0 100644 --- a/tasks.c +++ b/tasks.c @@ -1187,7 +1187,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ /* coverity[misra_c_2012_rule_11_3_violation] */ pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ - memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + ( void ) memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ @@ -1249,7 +1249,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ /* coverity[misra_c_2012_rule_11_3_violation] */ pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer; - memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + ( void ) memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Store the stack location in the TCB. */ pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; @@ -1318,7 +1318,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( pxNewTCB != NULL ) { - memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + ( void ) memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Store the stack location in the TCB. */ pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; From b55b0741f8a05f2f91667af232968be5b3c5bfaf Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 06:08:07 +0000 Subject: [PATCH 020/109] Fix MISRA C 2012 Rule 18.1. --- MISRA.md | 7 +++++++ tasks.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/MISRA.md b/MISRA.md index 204597594ca..7a0a94b177e 100644 --- a/MISRA.md +++ b/MISRA.md @@ -70,3 +70,10 @@ _Ref 17.3.2_ - MISRA C:2012 Rule 17.3: A function shall not be declared implicitly. MISRA warns against the function declared implicitly. It's a false alarm that portGET_RUN_TIME_COUNTER_VALUE() is declared in portmacro.h correctly. + +#### Rule 18.1 + +_Ref 18.1.1_ + +- MISRA C:2012 Rule 18.1: A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand. + Loop breaks before index overrun. diff --git a/tasks.c b/tasks.c index 65e562348e0..a775d4228c3 100644 --- a/tasks.c +++ b/tasks.c @@ -3157,6 +3157,9 @@ static BaseType_t prvCreateIdleTasks( void ) for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configMAX_TASK_NAME_LEN; x++ ) { + /* MISRA Ref 18.1.1 [Overrun] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-181 */ + /* coverity[misra_c_2012_rule_18_1_violation] */ cIdleName[ x ] = configIDLE_TASK_NAME[ x ]; /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than From 178f9b924e2f4f6fc681645d9419218b7fe604e2 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 06:40:17 +0000 Subject: [PATCH 021/109] Fix MISRA C 2012 Rule 8.13. --- include/task.h | 3 ++- tasks.c | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/task.h b/include/task.h index 8744676ab8d..c94007aa07a 100644 --- a/include/task.h +++ b/include/task.h @@ -85,6 +85,7 @@ */ struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ typedef struct tskTaskControlBlock * TaskHandle_t; +typedef const struct tskTaskControlBlock * ConstTaskHandle_t; /* * Defines the prototype to which the application task hook function must @@ -1363,7 +1364,7 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; * } * } */ - UBaseType_t vTaskCoreAffinityGet( const TaskHandle_t xTask ); + UBaseType_t vTaskCoreAffinityGet( ConstTaskHandle_t xTask ); #endif #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) diff --git a/tasks.c b/tasks.c index a775d4228c3..80cc274945f 100644 --- a/tasks.c +++ b/tasks.c @@ -496,7 +496,7 @@ static BaseType_t prvCreateIdleTasks( void ); * Yields a core, or cores if multiple priorities are not allowed to run * simultaneously, to allow the task pxTCB to run. */ - static void prvYieldForTask( TCB_t * pxTCB, + static void prvYieldForTask( const TCB_t * pxTCB, const BaseType_t xPreemptEqualPriority ); #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ @@ -797,7 +797,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ #if ( configNUMBER_OF_CORES > 1 ) - static void prvYieldForTask( TCB_t * pxTCB, + static void prvYieldForTask( const TCB_t * pxTCB, const BaseType_t xPreemptEqualPriority ) { BaseType_t xLowestPriorityToPreempt; @@ -910,7 +910,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; BaseType_t xDecrementTopPriority = pdTRUE; #if ( configUSE_CORE_AFFINITY == 1 ) - TCB_t * pxPreviousTCB = NULL; + const TCB_t * pxPreviousTCB = NULL; #endif #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) BaseType_t xPriorityDropped = pdFALSE; @@ -2627,9 +2627,9 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /*-----------------------------------------------------------*/ #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) - UBaseType_t vTaskCoreAffinityGet( const TaskHandle_t xTask ) + UBaseType_t vTaskCoreAffinityGet( ConstTaskHandle_t xTask ) { - TCB_t * pxTCB; + const TCB_t * pxTCB; UBaseType_t uxCoreAffinityMask; taskENTER_CRITICAL(); From 66665d208b0c83085b5da3ea6610036614d101bc Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 06:59:12 +0000 Subject: [PATCH 022/109] Fix MISRA C 2012 Rule 8.5. --- MISRA.md | 7 +++++++ tasks.c | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/MISRA.md b/MISRA.md index 7a0a94b177e..bb213157518 100644 --- a/MISRA.md +++ b/MISRA.md @@ -31,6 +31,13 @@ _Ref 8.4.1_ - MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an object or function with external linkage is defined. vTaskEnterCriticalFromISR()/vTaskExitCriticalFromISR are used at some ports. +#### Rule 8.5 + +_Ref 8.5.1_ + +- MISRA C:2012 Rule 8.5: An external object or function shall be declared once in one and only one file. + This is false alarm, function is declared in header file correctly. + #### Rule 11.3 _Ref 11.3.1_ diff --git a/tasks.c b/tasks.c index 80cc274945f..6c7a7016238 100644 --- a/tasks.c +++ b/tasks.c @@ -694,10 +694,13 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#directive-46 */ /* MISRA Ref 8.3.1 [Declarations shall be same] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-83 */ + /* MISRA Ref 8.5.1 [External function shall be declared once.] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ /* coverity[misra_c_2012_directive_4_6_violation] */ /* coverity[misra_c_2012_rule_8_3_violation] */ + /* coverity[misra_c_2012_rule_8_5_violation] */ /* coverity[misra_c_2012_rule_17_3_violation] */ if( portCHECK_IF_IN_ISR() == pdFALSE ) { @@ -5770,6 +5773,9 @@ static void prvResetNextTaskUnblockTime( void ) return xReturn; } #else /* #if ( configNUMBER_OF_CORES == 1 ) */ + /* MISRA Ref 8.5.1 [External function shall be declared once.] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* coverity[misra_c_2012_rule_8_5_violation] */ TaskHandle_t xTaskGetCurrentTaskHandle( void ) { TaskHandle_t xReturn; @@ -6118,6 +6124,9 @@ static void prvResetNextTaskUnblockTime( void ) * Otherwise set xYieldPendings to true to wait to * yield until exiting the critical section. */ +/* MISRA Ref 8.5.1 [External function shall be declared once.] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ +/* coverity[misra_c_2012_rule_8_5_violation] */ void vTaskYieldWithinAPI( void ) { if( portGET_CRITICAL_NESTING_COUNT() == 0U ) From 611cff67bb038c3deb5843f5f25712d2d4cf7b04 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 07:06:05 +0000 Subject: [PATCH 023/109] Fix MISRA C 2012 Rule 8.6. --- MISRA.md | 7 +++++++ tasks.c | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/MISRA.md b/MISRA.md index bb213157518..3189959cc33 100644 --- a/MISRA.md +++ b/MISRA.md @@ -38,6 +38,13 @@ _Ref 8.5.1_ - MISRA C:2012 Rule 8.5: An external object or function shall be declared once in one and only one file. This is false alarm, function is declared in header file correctly. +#### Rule 8.6 + +_Ref 8.6.1_ + +- MISRA C:2012 Rule 8.6: An identifier with external linkage shall have exactly one external definition. + This is false alarm, function is declared in header file correctly. + #### Rule 11.3 _Ref 11.3.1_ diff --git a/tasks.c b/tasks.c index 6c7a7016238..c6ecb750ce7 100644 --- a/tasks.c +++ b/tasks.c @@ -695,12 +695,15 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* MISRA Ref 8.3.1 [Declarations shall be same] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-83 */ /* MISRA Ref 8.5.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ + /* MISRA Ref 8.6.1 [External function shall be declared once.] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ /* coverity[misra_c_2012_directive_4_6_violation] */ /* coverity[misra_c_2012_rule_8_3_violation] */ /* coverity[misra_c_2012_rule_8_5_violation] */ + /* coverity[misra_c_2012_rule_8_6_violation] */ /* coverity[misra_c_2012_rule_17_3_violation] */ if( portCHECK_IF_IN_ISR() == pdFALSE ) { @@ -5774,8 +5777,11 @@ static void prvResetNextTaskUnblockTime( void ) } #else /* #if ( configNUMBER_OF_CORES == 1 ) */ /* MISRA Ref 8.5.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ + /* MISRA Ref 8.6.1 [External function shall be declared once.] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ /* coverity[misra_c_2012_rule_8_5_violation] */ + /* coverity[misra_c_2012_rule_8_6_violation] */ TaskHandle_t xTaskGetCurrentTaskHandle( void ) { TaskHandle_t xReturn; @@ -6125,8 +6131,11 @@ static void prvResetNextTaskUnblockTime( void ) * yield until exiting the critical section. */ /* MISRA Ref 8.5.1 [External function shall be declared once.] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ +/* MISRA Ref 8.6.1 [External function shall be declared once.] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ /* coverity[misra_c_2012_rule_8_5_violation] */ +/* coverity[misra_c_2012_rule_8_6_violation] */ void vTaskYieldWithinAPI( void ) { if( portGET_CRITICAL_NESTING_COUNT() == 0U ) From 70903a382998c72fd13d72b6ce370ae42e18334d Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 07:10:28 +0000 Subject: [PATCH 024/109] Fix MISRA C 2012 Rule 8.9. --- MISRA.md | 7 +++++++ tasks.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/MISRA.md b/MISRA.md index 3189959cc33..ef1c120a805 100644 --- a/MISRA.md +++ b/MISRA.md @@ -45,6 +45,13 @@ _Ref 8.6.1_ - MISRA C:2012 Rule 8.6: An identifier with external linkage shall have exactly one external definition. This is false alarm, function is declared in header file correctly. +#### Rule 8.9 + +_Ref 8.9.1_ + +- MISRA C:2012 Rule 8.9: An object should be defined at block scope if its identifier only appears in a single function. + Maintain static variables at global view. + #### Rule 11.3 _Ref 11.3.1_ diff --git a/tasks.c b/tasks.c index c6ecb750ce7..2752a65b79f 100644 --- a/tasks.c +++ b/tasks.c @@ -430,6 +430,9 @@ PRIVILEGED_DATA static volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ +/* MISRA Ref 8.9.1 [Object in block scope] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-89 */ +/* coverity[misra_c_2012_rule_8_9_violation] */ PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = { /*< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ [0 ... configNUMBER_OF_CORES-1] = NULL, }; From 257c3e0800f1b06f54ca61a36da1800d7c150486 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 09:00:13 +0000 Subject: [PATCH 025/109] Fix MISRA C 2012 Rule 8.4. --- tasks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tasks.c b/tasks.c index 2752a65b79f..081f9f23a2a 100644 --- a/tasks.c +++ b/tasks.c @@ -6186,6 +6186,9 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) + /* MISRA Ref 8.4.1 [Declaration shall be visible] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* coverity[misra_c_2012_rule_8_4_violation] */ void vTaskEnterCritical( void ) { portDISABLE_INTERRUPTS(); @@ -6304,6 +6307,9 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) + /* MISRA Ref 8.4.1 [Declaration shall be visible] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* coverity[misra_c_2012_rule_8_4_violation] */ void vTaskExitCritical( void ) { if( xSchedulerRunning != pdFALSE ) From f1ece17b0746e46ed0eaa49a48d5b13a6bf7e7af Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 09:02:13 +0000 Subject: [PATCH 026/109] Fix MISRA C 2012 Rule 8.5. --- tasks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasks.c b/tasks.c index 081f9f23a2a..9ff5029dfa8 100644 --- a/tasks.c +++ b/tasks.c @@ -6188,7 +6188,10 @@ static void prvResetNextTaskUnblockTime( void ) /* MISRA Ref 8.4.1 [Declaration shall be visible] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* MISRA Ref 8.5.1 [External function shall be declared once.] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ /* coverity[misra_c_2012_rule_8_4_violation] */ + /* coverity[misra_c_2012_rule_8_5_violation] */ void vTaskEnterCritical( void ) { portDISABLE_INTERRUPTS(); From b73bf11d90070a6c196b9789285455a70539adbc Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 09:04:06 +0000 Subject: [PATCH 027/109] Fix MISRA C 2012 Rule 8.6. --- tasks.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tasks.c b/tasks.c index 9ff5029dfa8..76d6cb2c475 100644 --- a/tasks.c +++ b/tasks.c @@ -6190,8 +6190,11 @@ static void prvResetNextTaskUnblockTime( void ) /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ /* MISRA Ref 8.5.1 [External function shall be declared once.] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ + /* MISRA Ref 8.6.1 [External function shall be declared once.] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ /* coverity[misra_c_2012_rule_8_4_violation] */ /* coverity[misra_c_2012_rule_8_5_violation] */ + /* coverity[misra_c_2012_rule_8_6_violation] */ void vTaskEnterCritical( void ) { portDISABLE_INTERRUPTS(); @@ -6312,7 +6315,13 @@ static void prvResetNextTaskUnblockTime( void ) /* MISRA Ref 8.4.1 [Declaration shall be visible] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* MISRA Ref 8.5.1 [External function shall be declared once.] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ + /* MISRA Ref 8.6.1 [External function shall be declared once.] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ /* coverity[misra_c_2012_rule_8_4_violation] */ + /* coverity[misra_c_2012_rule_8_5_violation] */ + /* coverity[misra_c_2012_rule_8_6_violation] */ void vTaskExitCritical( void ) { if( xSchedulerRunning != pdFALSE ) From 59cf3f65e65d29b6b34c0b7c2761a01d0295bac0 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 09:37:23 +0000 Subject: [PATCH 028/109] Revert unnecessary suppression. --- tasks.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/tasks.c b/tasks.c index 76d6cb2c475..ca027ef0f75 100644 --- a/tasks.c +++ b/tasks.c @@ -695,18 +695,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * from here. */ /* MISRA Ref 4.6.1 [typedef indicates size and signedness] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#directive-46 */ - /* MISRA Ref 8.3.1 [Declarations shall be same] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-83 */ - /* MISRA Ref 8.5.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ - /* MISRA Ref 8.6.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ /* coverity[misra_c_2012_directive_4_6_violation] */ - /* coverity[misra_c_2012_rule_8_3_violation] */ - /* coverity[misra_c_2012_rule_8_5_violation] */ - /* coverity[misra_c_2012_rule_8_6_violation] */ /* coverity[misra_c_2012_rule_17_3_violation] */ if( portCHECK_IF_IN_ISR() == pdFALSE ) { @@ -6133,12 +6124,6 @@ static void prvResetNextTaskUnblockTime( void ) * Otherwise set xYieldPendings to true to wait to * yield until exiting the critical section. */ -/* MISRA Ref 8.5.1 [External function shall be declared once.] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ -/* MISRA Ref 8.6.1 [External function shall be declared once.] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ -/* coverity[misra_c_2012_rule_8_5_violation] */ -/* coverity[misra_c_2012_rule_8_6_violation] */ void vTaskYieldWithinAPI( void ) { if( portGET_CRITICAL_NESTING_COUNT() == 0U ) @@ -6188,13 +6173,7 @@ static void prvResetNextTaskUnblockTime( void ) /* MISRA Ref 8.4.1 [Declaration shall be visible] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ - /* MISRA Ref 8.5.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ - /* MISRA Ref 8.6.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ /* coverity[misra_c_2012_rule_8_4_violation] */ - /* coverity[misra_c_2012_rule_8_5_violation] */ - /* coverity[misra_c_2012_rule_8_6_violation] */ void vTaskEnterCritical( void ) { portDISABLE_INTERRUPTS(); @@ -6315,13 +6294,7 @@ static void prvResetNextTaskUnblockTime( void ) /* MISRA Ref 8.4.1 [Declaration shall be visible] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ - /* MISRA Ref 8.5.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ - /* MISRA Ref 8.6.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ /* coverity[misra_c_2012_rule_8_4_violation] */ - /* coverity[misra_c_2012_rule_8_5_violation] */ - /* coverity[misra_c_2012_rule_8_6_violation] */ void vTaskExitCritical( void ) { if( xSchedulerRunning != pdFALSE ) From 5c6d77bbc036a4e828d77bfb9b7f931fc285d344 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 09:45:51 +0000 Subject: [PATCH 029/109] Add more description in MISRA.md --- MISRA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MISRA.md b/MISRA.md index ef1c120a805..de6e7832d2d 100644 --- a/MISRA.md +++ b/MISRA.md @@ -1,6 +1,6 @@ # MISRA Compliance -For now, FreeRTOS-Kernel only conforms [MISRA C:2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx) guidelines in SMP part (configNUM_CORES > 1), +For now, FreeRTOS-Kernel only conforms [MISRA C:2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx) guidelines in SMP part (configNUMBER_OF_CORES > 1), with the deviations listed below. Compliance is checked with Coverity static analysis. ### Suppressed with Coverity Comments From b2783413c49d7a1eb18133ae27e5a8c2bcf4760a Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 09:55:54 +0000 Subject: [PATCH 030/109] Fix formatting. --- include/task.h | 4 ++-- tasks.c | 38 ++++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/task.h b/include/task.h index c94007aa07a..a4f95b10fb3 100644 --- a/include/task.h +++ b/include/task.h @@ -84,8 +84,8 @@ * \ingroup Tasks */ struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ -typedef struct tskTaskControlBlock * TaskHandle_t; -typedef const struct tskTaskControlBlock * ConstTaskHandle_t; +typedef struct tskTaskControlBlock * TaskHandle_t; +typedef const struct tskTaskControlBlock * ConstTaskHandle_t; /* * Defines the prototype to which the application task hook function must diff --git a/tasks.c b/tasks.c index ca027ef0f75..103994a4bcc 100644 --- a/tasks.c +++ b/tasks.c @@ -384,8 +384,9 @@ typedef tskTCB TCB_t; /* MISRA Ref 8.4.1 [Declaration shall be visible] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ /* coverity[misra_c_2012_rule_8_4_violation] */ - portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { - [0 ... configNUMBER_OF_CORES-1] = NULL, + portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = + { + [ 0 ... configNUMBER_OF_CORES - 1 ] = NULL, }; #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif @@ -429,12 +430,13 @@ PRIVILEGED_DATA static volatile TickType_t xPendedTicks = ( TickType_t ) 0U; PRIVILEGED_DATA static volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES ] = { pdFALSE }; PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; -PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ +PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ /* MISRA Ref 8.9.1 [Object in block scope] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-89 */ /* coverity[misra_c_2012_rule_8_9_violation] */ -PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = { /*< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ - [0 ... configNUMBER_OF_CORES-1] = NULL, +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = /*< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ +{ + [ 0 ... configNUMBER_OF_CORES - 1 ] = NULL, }; /* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. @@ -1116,7 +1118,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #endif { xLowestPriority = xTaskPriority; - xLowestPriorityCore = ( BaseType_t) uxCore; + xLowestPriorityCore = ( BaseType_t ) uxCore; } } } @@ -6171,9 +6173,9 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) - /* MISRA Ref 8.4.1 [Declaration shall be visible] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ - /* coverity[misra_c_2012_rule_8_4_violation] */ +/* MISRA Ref 8.4.1 [Declaration shall be visible] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ +/* coverity[misra_c_2012_rule_8_4_violation] */ void vTaskEnterCritical( void ) { portDISABLE_INTERRUPTS(); @@ -6220,9 +6222,9 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) - /* MISRA Ref 8.4.1 [Declaration shall be visible] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ - /* coverity[misra_c_2012_rule_8_4_violation] */ +/* MISRA Ref 8.4.1 [Declaration shall be visible] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ +/* coverity[misra_c_2012_rule_8_4_violation] */ UBaseType_t vTaskEnterCriticalFromISR( void ) { UBaseType_t uxSavedInterruptStatus = 0; @@ -6292,9 +6294,9 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) - /* MISRA Ref 8.4.1 [Declaration shall be visible] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ - /* coverity[misra_c_2012_rule_8_4_violation] */ +/* MISRA Ref 8.4.1 [Declaration shall be visible] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ +/* coverity[misra_c_2012_rule_8_4_violation] */ void vTaskExitCritical( void ) { if( xSchedulerRunning != pdFALSE ) @@ -6352,9 +6354,9 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) - /* MISRA Ref 8.4.1 [Declaration shall be visible] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ - /* coverity[misra_c_2012_rule_8_4_violation] */ +/* MISRA Ref 8.4.1 [Declaration shall be visible] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ +/* coverity[misra_c_2012_rule_8_4_violation] */ void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ) { BaseType_t xYieldCurrentTask; From ef65fda2840638d88fca173230e7759fe4fa79e4 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 30 Nov 2022 09:56:07 +0000 Subject: [PATCH 031/109] Fix MISRA.md --- MISRA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MISRA.md b/MISRA.md index de6e7832d2d..12b2aad1874 100644 --- a/MISRA.md +++ b/MISRA.md @@ -1,4 +1,4 @@ -# MISRA Compliance +# MISRA Compliance (for configNUMBER_OF_CORES > 1) For now, FreeRTOS-Kernel only conforms [MISRA C:2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx) guidelines in SMP part (configNUMBER_OF_CORES > 1), with the deviations listed below. Compliance is checked with Coverity static analysis. From b99857264d132dae19fa57b05ae35616dc14cdf7 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Mon, 5 Dec 2022 03:51:32 +0000 Subject: [PATCH 032/109] Fix comments. --- tasks.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/tasks.c b/tasks.c index 103994a4bcc..155fe4316e5 100644 --- a/tasks.c +++ b/tasks.c @@ -386,7 +386,7 @@ typedef tskTCB TCB_t; /* coverity[misra_c_2012_rule_8_4_violation] */ portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { - [ 0 ... configNUMBER_OF_CORES - 1 ] = NULL, + [ 0 ... ( configNUMBER_OF_CORES - 1 ) ] = NULL, }; #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif @@ -436,7 +436,7 @@ PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) /* coverity[misra_c_2012_rule_8_9_violation] */ PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = /*< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ { - [ 0 ... configNUMBER_OF_CORES - 1 ] = NULL, + [ 0 ... ( configNUMBER_OF_CORES - 1 ) ] = NULL, }; /* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. @@ -680,7 +680,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) extern void vApplicationMinimalIdleHook( void ); -#endif /* ( configUSE_MINIMAL_IDLE_HOOK == 1 ) */ +#endif /* #if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) */ /*-----------------------------------------------------------*/ @@ -695,12 +695,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * core is no longer running, then vTaskSwitchContext() probably should * be run before returning, but we don't have a way to force that to happen * from here. */ - /* MISRA Ref 4.6.1 [typedef indicates size and signedness] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#directive-46 */ - /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ - /* coverity[misra_c_2012_directive_4_6_violation] */ - /* coverity[misra_c_2012_rule_17_3_violation] */ if( portCHECK_IF_IN_ISR() == pdFALSE ) { /* This function is always called with interrupts disabled @@ -772,9 +766,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; static void prvYieldCore( BaseType_t xCoreID ) { /* This must be called from a critical section and xCoreID must be valid. */ - /* MISRA Ref 17.3.1 [Function shall not be declared implicitly] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ - /* coverity[misra_c_2012_rule_17_3_violation] */ if( portCHECK_IF_IN_ISR() && ( xCoreID == portGET_CORE_ID() ) ) { xYieldPendings[ xCoreID ] = pdTRUE; @@ -837,7 +828,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; xCurrentCoreTaskPriority = xCurrentCoreTaskPriority - 1; } - if( ( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCoreID ] ) ) && ( xYieldPendings[ xCoreID ] == pdFALSE ) ) + if( ( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCoreID ] ) != pdFALSE ) && ( xYieldPendings[ xCoreID ] == pdFALSE ) ) { if( xCurrentCoreTaskPriority <= xLowestPriorityToPreempt ) { @@ -885,7 +876,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* MISRA Ref 14.3.1 [Expression shall not be invariant] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-143 */ /* coverity[misra_c_2012_rule_14_3_violation] */ - if( ( xYieldCount == 0 ) && taskVALID_CORE_ID( xLowestPriorityCore ) ) + if( ( xYieldCount == 0 ) && ( taskVALID_CORE_ID( xLowestPriorityCore ) != pdFALSE ) ) { prvYieldCore( xLowestPriorityCore ); } @@ -1110,7 +1101,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; uxCoreMap &= ~( ( UBaseType_t ) 1U << uxCore ); if( ( xTaskPriority < xLowestPriority ) && - ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) ) && + ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) && ( xYieldPendings[ uxCore ] == pdFALSE ) ) { #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) @@ -1124,7 +1115,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; } } - if( taskVALID_CORE_ID( xLowestPriorityCore ) ) + if( taskVALID_CORE_ID( xLowestPriorityCore ) != pdFALSE ) { prvYieldCore( xLowestPriorityCore ); } @@ -4576,9 +4567,6 @@ BaseType_t xTaskIncrementTick( void ) #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); #else - /* MISRA Ref 17.3.2 [Function shall not be declared implicitly] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ - /* coverity[misra_c_2012_rule_17_3_violation] */ ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); #endif @@ -5796,7 +5784,7 @@ static void prvResetNextTaskUnblockTime( void ) { TaskHandle_t xReturn = NULL; - if( taskVALID_CORE_ID( xCoreID ) ) + if( taskVALID_CORE_ID( xCoreID ) != pdFALSE ) { xReturn = pxCurrentTCBs[ xCoreID ]; } @@ -7357,9 +7345,6 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; BaseType_t i = 0; - /* MISRA Ref 17.3.2 [Function shall not be declared implicitly] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-173 */ - /* coverity[misra_c_2012_rule_17_3_violation] */ ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES; /* For percentage calculations. */ From 646698d36d1b966b2b77cd154abd38daf170a318 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Mon, 5 Dec 2022 04:02:23 +0000 Subject: [PATCH 033/109] Update MISRA.md for rule 8.9. --- MISRA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MISRA.md b/MISRA.md index 12b2aad1874..63df2ae4e26 100644 --- a/MISRA.md +++ b/MISRA.md @@ -50,7 +50,7 @@ _Ref 8.6.1_ _Ref 8.9.1_ - MISRA C:2012 Rule 8.9: An object should be defined at block scope if its identifier only appears in a single function. - Maintain static variables at global view. + False alarm. This variable is actually used by several different functions. #### Rule 11.3 From d29d3e229a13d18f4c72c3ead59a1196b570a147 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Mon, 5 Dec 2022 04:29:13 +0000 Subject: [PATCH 034/109] Update MISRA.md for rule 8.5/8.6. --- MISRA.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MISRA.md b/MISRA.md index 63df2ae4e26..429af546c01 100644 --- a/MISRA.md +++ b/MISRA.md @@ -36,14 +36,14 @@ _Ref 8.4.1_ _Ref 8.5.1_ - MISRA C:2012 Rule 8.5: An external object or function shall be declared once in one and only one file. - This is false alarm, function is declared in header file correctly. + Function is declared in header file correctly. But the function name in task.h/tasks.c is different if portUSING_MPU_WRAPPERS enabled. #### Rule 8.6 _Ref 8.6.1_ - MISRA C:2012 Rule 8.6: An identifier with external linkage shall have exactly one external definition. - This is false alarm, function is declared in header file correctly. + Function is declared in header file correctly. But the function name in task.h/tasks.c is different if portUSING_MPU_WRAPPERS enabled. #### Rule 8.9 From a244764c265856e9d70f842c1e337efe80601fa6 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Mon, 5 Dec 2022 04:37:41 +0000 Subject: [PATCH 035/109] Wrap xYieldCount with configRUN_MULTIPLE_PRIORITIES. Fix comments. --- MISRA.md | 28 ---------------------------- tasks.c | 13 ++++++++----- 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/MISRA.md b/MISRA.md index 429af546c01..bdfae0787c2 100644 --- a/MISRA.md +++ b/MISRA.md @@ -17,13 +17,6 @@ _Ref 4.6.1_ MISRA warns against the use of basic numerical types. FreeRTOS-Kerenl uses BaseType_t/UBaseType_t to represent signed/unsigned variables no matter it's 16 or 32 bits. -#### Rule 8.3 - -_Ref 8.3.1_ - -- MISRA C:2012 Rule 8.3: All declarations of an object or functionn shall use the same names and type qualifiers. - It's a false alarm that portCHECK_IF_IN_ISR() is only declared in portmacro.h. - #### Rule 8.4 _Ref 8.4.1_ @@ -70,27 +63,6 @@ _Ref 11.5.1_ - MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to void into pointer to object. void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. - -#### Rule 14.3 - -_Ref 14.3.1_ - -- MISRA C:2012 Rule 14.3: Controlling expressions shall not be invariant. - The expression is variant with other configuration enabled. - -#### Rule 17.3 - -_Ref 17.3.1_ - -- MISRA C:2012 Rule 17.3: A function shall not be declared implicitly. - MISRA warns against the function declared implicitly. It's a false alarm that - portCHECK_IF_IN_ISR() is declared in portmacro.h correctly. - -_Ref 17.3.2_ - -- MISRA C:2012 Rule 17.3: A function shall not be declared implicitly. - MISRA warns against the function declared implicitly. It's a false alarm that - portGET_RUN_TIME_COUNTER_VALUE() is declared in portmacro.h correctly. #### Rule 18.1 diff --git a/tasks.c b/tasks.c index 155fe4316e5..b7cbe54c996 100644 --- a/tasks.c +++ b/tasks.c @@ -796,8 +796,10 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; BaseType_t xLowestPriorityToPreempt; BaseType_t xCurrentCoreTaskPriority; BaseType_t xLowestPriorityCore = ( BaseType_t ) -1; - BaseType_t xYieldCount = 0; BaseType_t xCoreID; + #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) + BaseType_t xYieldCount = 0; + #endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */ /* This must be called from a critical section. */ configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U ); @@ -873,10 +875,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; } } - /* MISRA Ref 14.3.1 [Expression shall not be invariant] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-143 */ - /* coverity[misra_c_2012_rule_14_3_violation] */ - if( ( xYieldCount == 0 ) && ( taskVALID_CORE_ID( xLowestPriorityCore ) != pdFALSE ) ) + #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) + if( ( xYieldCount == 0 ) && ( taskVALID_CORE_ID( xLowestPriorityCore ) != pdFALSE ) ) + #else /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */ + if( taskVALID_CORE_ID( xLowestPriorityCore ) != pdFALSE ) + #endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */ { prvYieldCore( xLowestPriorityCore ); } From 99d3d54ac4d17474a81c94ec5bab36f55f470359 Mon Sep 17 00:00:00 2001 From: Archit Gupta <71798289+archigup@users.noreply.github.com> Date: Thu, 15 Dec 2022 21:46:32 +0000 Subject: [PATCH 036/109] Fix array-bounds compiler warning on gcc11+ in list.h (#580) listGET_OWNER_OF_NEXT_ENTRY computes `( pxConstList )->pxIndex->pxNext` after verifying that `( pxConstList )->pxIndex` points to `xListEnd`, which due to being a MiniListItem_t, can be shorter than a ListItem_t. Thus, `( pxConstList )->pxIndex` is a `ListItem_t *` that extends past the end of the `List_t` whose `xListEnd` it points to. This is fixed by accessing `pxNext` through a `MiniListItem_t` instead. --- include/list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/list.h b/include/list.h index 11241b68687..248212260a1 100644 --- a/include/list.h +++ b/include/list.h @@ -290,7 +290,7 @@ typedef struct xLIST ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ { \ - ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + ( pxConstList )->pxIndex = ( pxConstList )->xListEnd.pxNext; \ } \ ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ } From 6d65558ba01141d7c50ff6f93a4054cc5f16940e Mon Sep 17 00:00:00 2001 From: tcpluess Date: Mon, 19 Dec 2022 10:48:07 +0100 Subject: [PATCH 037/109] move the prototype for vApplicationIdleHook to task.h. (#600) Co-authored-by: pluess Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- include/task.h | 18 ++++++++++++++++++ tasks.c | 8 +------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/include/task.h b/include/task.h index a3548296b97..b01551d5366 100644 --- a/include/task.h +++ b/include/task.h @@ -1649,6 +1649,24 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL #endif +#if ( configUSE_IDLE_HOOK == 1 ) + +/** + * task.h + * @code{c} + * void vApplicationIdleHook( void ); + * @endcode + * + * The application idle hook is called by the idle task. + * This allows the application designer to add background functionality without + * the overhead of a separate task. + * NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. + */ + void vApplicationIdleHook( void ); + +#endif + + #if ( configUSE_TICK_HOOK > 0 ) /** diff --git a/tasks.c b/tasks.c index c9cf459829d..d4d8fb06f2d 100644 --- a/tasks.c +++ b/tasks.c @@ -3477,13 +3477,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) #if ( configUSE_IDLE_HOOK == 1 ) { - extern void vApplicationIdleHook( void ); - - /* Call the user defined function from within the idle task. This - * allows the application designer to add background functionality - * without the overhead of a separate task. - * NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, - * CALL A FUNCTION THAT MIGHT BLOCK. */ + /* Call the user defined function from within the idle task. */ vApplicationIdleHook(); } #endif /* configUSE_IDLE_HOOK */ From aab4812aa7be2b367d06a228989a25bc1bc63faa Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Mon, 26 Dec 2022 04:02:57 +0000 Subject: [PATCH 038/109] Update MISRA.md. --- MISRA.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/MISRA.md b/MISRA.md index bdfae0787c2..2f57e189e07 100644 --- a/MISRA.md +++ b/MISRA.md @@ -1,7 +1,7 @@ # MISRA Compliance (for configNUMBER_OF_CORES > 1) -For now, FreeRTOS-Kernel only conforms [MISRA C:2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx) guidelines in SMP part (configNUMBER_OF_CORES > 1), -with the deviations listed below. Compliance is checked with Coverity static analysis. +For now, FreeRTOS-Kernel only conforms [MISRA C:2012](https://www.misra.org.uk/misra-c) guidelines in SMP part (configNUMBER_OF_CORES > 1), +with the deviations listed below. Compliance is checked with Coverity static analysis. Refer to [configuration](#misra-configuration) to build an application for the tool to analyze. ### Suppressed with Coverity Comments To find the violation references in the source files run grep on the source code @@ -70,3 +70,51 @@ _Ref 18.1.1_ - MISRA C:2012 Rule 18.1: A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand. Loop breaks before index overrun. + +### MISRA configuration + +Copy below content as misra.conf to run coverity on FreeRTOS-Kernel. + +``` +// MISRA C-2012 Rules +{ + version : "2.0", + standard : "c2012", + title: "Coverity MISRA Configuration", + deviations : [ + // Disable the following rules. + { + deviation: "Directive 4.8", + reason: "We include lots of header files from other sources such as the kernel which defines structures that violate that Dir" + }, + { + deviation: "Directive 4.9", + reason: "It is important the FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, macros are being used." + }, + { + deviation: "Rule 1.2", + reason: "Allow FreeRTOS-Kernel to use attributes." + }, + { + deviation: "Rule 2.3", + reason: "The way we declare structures are conformant with the FreeRTOS libraries, which leaves somes types unused." + }, + { + deviation: "Rule 2.4", + reason: "Structures are always declared with both a struct tag and typedef alias. Some of these structs are always referred to by their typedef alias and thus the corresponding tags are unused." + }, + { + deviation: "Rule 2.5", + reason: "We use unused macros for backward compatibility in addition to macros comming from FreeRTOS" + }, + { + deviation: "Rule 3.1", + reason: "We post links which contain // inside comments blocks" + }, + { + deviation: "Rule 21.2", + reason: "Allow use of all names." + } + ] +} +``` \ No newline at end of file From 953f32e0e005b7c4816b5307f53945b9054394c0 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 28 Dec 2022 01:51:49 +0000 Subject: [PATCH 039/109] Remove Dir 4.6 in MISRA.md. --- MISRA.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/MISRA.md b/MISRA.md index 2f57e189e07..12b41e160a6 100644 --- a/MISRA.md +++ b/MISRA.md @@ -7,15 +7,8 @@ with the deviations listed below. Compliance is checked with Coverity static ana To find the violation references in the source files run grep on the source code with ( Assuming rule 4.6 violation; with justification in point 1 ): ``` -grep 'MISRA Ref 4.6.1' . -rI +grep 'MISRA Ref 8.4.1' . -rI ``` -#### Directive 4.6 - -_Ref 4.6.1_ - -- MISRA C:2012 Directive 4.6: typedef that indicate size and signedness should be used in place of the basic numerical types. - MISRA warns against the use of basic numerical types. FreeRTOS-Kerenl - uses BaseType_t/UBaseType_t to represent signed/unsigned variables no matter it's 16 or 32 bits. #### Rule 8.4 From bb6071e1df3168a64dc2ce79de8aa91b7995ba23 Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Fri, 6 Jan 2023 10:42:13 +0800 Subject: [PATCH 040/109] Update equal priority task preemption (#603) * vTaskResume and vTaskPrioritySet don't preempt equal priority task * Update vTaskResumeAll not to preempt task with equal priority * Fix in xTaskResumeFromISR --- tasks.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasks.c b/tasks.c index d4d8fb06f2d..3a0f0470e78 100644 --- a/tasks.c +++ b/tasks.c @@ -1552,7 +1552,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) /* The priority of a task other than the currently * running task is being raised. Is the priority being * raised above that of the running task? */ - if( uxNewPriority >= pxCurrentTCB->uxPriority ) + if( uxNewPriority > pxCurrentTCB->uxPriority ) { xYieldRequired = pdTRUE; } @@ -1845,7 +1845,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) prvAddTaskToReadyList( pxTCB ); /* A higher priority task may have just been resumed. */ - if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) { /* This yield may not cause the task just resumed to run, * but will leave the lists in the correct state for the @@ -1913,7 +1913,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) { /* Ready lists can be accessed so move the task from the * suspended list to the ready list directly. */ - if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) { xYieldRequired = pdTRUE; @@ -2203,9 +2203,9 @@ BaseType_t xTaskResumeAll( void ) listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); - /* If the moved task has a priority higher than or equal to - * the current task then a yield must be performed. */ - if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + /* If the moved task has a priority higher than the current + * task then a yield must be performed. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) { xYieldPending = pdTRUE; } From 8592fd23f4fbc1a2fa821a9b89b61ef1f5652a09 Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Mon, 16 Jan 2023 15:06:18 +0530 Subject: [PATCH 041/109] Update FreeRTOS/FreeRTOS build checks (#613) This is needed to be compatible with the refactoring done in this PR - https://github.com/FreeRTOS/FreeRTOS/pull/889 Signed-off-by: Gaurav Aggarwal Signed-off-by: Gaurav Aggarwal --- .github/workflows/kernel-checks.yml | 25 ---- .github/workflows/kernel-demos.yml | 173 ++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/kernel-demos.yml diff --git a/.github/workflows/kernel-checks.yml b/.github/workflows/kernel-checks.yml index 889a53e6c22..b295033d28a 100644 --- a/.github/workflows/kernel-checks.yml +++ b/.github/workflows/kernel-checks.yml @@ -45,28 +45,3 @@ jobs: cd inspect .github/scripts/kernel_checker.py --json ${HOME}/files_modified.json ${HOME}/files_added.json ${HOME}/files_renamed.json exit $? - build-checker: - name: FreeRTOS Posix Build Check - runs-on: ubuntu-latest - steps: - - name: Checkout the parent repository - uses: actions/checkout@v2 - with: - ref: main - repository: FreeRTOS/FreeRTOS - submodules: 'recursive' - fetch-depth: 1 - path: ./workspace - - name: Checkout the current repository - uses: actions/checkout@v2 - with: - path: ./workspace/FreeRTOS/Source - - name: Posix Build Checker - run: | - bash workspace/.github/scripts/posix_build_checker.sh workspace - - name: Install lib pcap dev - run: | - sudo apt-get install libpcap-dev - - name: Posix Network Build Checker - run: | - bash workspace/.github/scripts/posix_network_build_checker.sh workspace diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml new file mode 100644 index 00000000000..d6eace575ae --- /dev/null +++ b/.github/workflows/kernel-demos.yml @@ -0,0 +1,173 @@ +name: FreeRTOS-Kernel Demos +on: [push, pull_request] + +jobs: + WIN32-MSVC: + name: WIN32 MSVC + runs-on: windows-latest + steps: + - name: Checkout the FreeRTOS/FreeRTOS Repository + uses: actions/checkout@v2 + with: + ref: main + repository: FreeRTOS/FreeRTOS + submodules: 'recursive' + fetch-depth: 1 + + - name: Fetch Kernel Submodule + shell: bash + run: | + git submodule update --checkout --init --depth 1 FreeRTOS/Source + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + + - name: Build WIN32-MSVC Demo + working-directory: FreeRTOS/Demo/WIN32-MSVC + run: msbuild WIN32.sln -t:rebuild + + - name: Build WIN32-MSVC-Static-Allocation-Only Demo + working-directory: FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only + run: msbuild WIN32.sln -t:rebuild + + WIN32-MingW: + name: WIN32 MingW + runs-on: windows-latest + steps: + - name: Checkout the FreeRTOS/FreeRTOS Repository + uses: actions/checkout@v2 + with: + ref: main + repository: FreeRTOS/FreeRTOS + submodules: 'recursive' + fetch-depth: 1 + + - name: Fetch Kernel Submodule + shell: bash + run: | + git submodule update --checkout --init --depth 1 FreeRTOS/Source + + - name: Build WIN32-MingW Demo + working-directory: FreeRTOS/Demo/WIN32-MingW + run: | + gcc --version + make --version + make + + POSIX-GCC: + name: Native GCC + runs-on: ubuntu-latest + steps: + - name: Checkout the FreeRTOS/FreeRTOS Repository + uses: actions/checkout@v2 + with: + ref: main + repository: FreeRTOS/FreeRTOS + submodules: 'recursive' + fetch-depth: 1 + + - name: Fetch Kernel Submodule + shell: bash + run: git submodule update --checkout --init --depth 1 FreeRTOS/Source + + - name: Install GCC + shell: bash + run: | + sudo apt-get -y update + sudo apt-get -y install build-essential + + - name: Build Posix_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/Posix_GCC + run: make -j + + MSP430-GCC: + name: GNU MSP430 Toolchain + runs-on: ubuntu-latest + steps: + - name: Checkout the FreeRTOS/FreeRTOS Repository + uses: actions/checkout@v2 + with: + ref: main + repository: FreeRTOS/FreeRTOS + submodules: 'recursive' + fetch-depth: 1 + + - name: Fetch Kernel Submodule + shell: bash + run: git submodule update --checkout --init --depth 1 FreeRTOS/Source + + - name: Install MSP430 Toolchain + shell: bash + run: | + sudo apt-get -y update + sudo apt-get -y install gcc-msp430 build-essential + + - name: Build msp430_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/msp430_GCC + run: make -j + + ARM-GCC: + name: GNU ARM Toolchain + runs-on: ubuntu-latest + steps: + - name: Checkout the FreeRTOS/FreeRTOS Repository + uses: actions/checkout@v2 + with: + ref: main + repository: FreeRTOS/FreeRTOS + submodules: 'recursive' + fetch-depth: 1 + + - name: Fetch Kernel Submodule + shell: bash + run: git submodule update --checkout --init --depth 1 FreeRTOS/Source + + - name: Install GNU ARM Toolchain + shell: bash + run: | + sudo apt-get -y update + sudo apt-get -y install gcc-arm-none-eabi build-essential cmake git ninja-build python3-minimal + + - name: Build CORTEX_MPU_M3_MPS2_QEMU_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_MPU_M3_MPS2_QEMU_GCC + run: make -j + + - name: Build CORTEX_LM3S102_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_LM3S102_GCC + run: make -j + + - name: Build CORTEX_M3_MPS2_QEMU_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC + run: | + make clean + make -j + + - name: Build CORTEX_M3_MPS2_QEMU_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC + run: | + make clean + make FULL_DEMO=1 -j + + - name: Build CORTEX_LM3S811_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_LM3S811_GCC + run: make -j + + - name: Build CORTEX_M0+_RP2040 Demos + shell: bash + working-directory: FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040 + run: | + git clone https://github.com/raspberrypi/pico-sdk.git + cmake -B build -DPICO_SDK_PATH=pico-sdk -GNinja + ninja -C build --verbose + + - name: Build CORTEX_MPS2_QEMU_IAR_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC + run: make -C build/gcc -j From 78319fd17ed8256b93ce91251d1bdd4907940b52 Mon Sep 17 00:00:00 2001 From: Chris Copeland Date: Thu, 19 Jan 2023 14:46:42 -0800 Subject: [PATCH 042/109] Add ulTaskGetRunTimeCounter and ulTaskGetRunTimePercent (#611) Allow ulTaskGetIdleRunTimeCounter and ulTaskGetIdleRunTimePercent to be used whenever configGENERATE_RUN_TIME_STATS is enabled, as this is the only requirement for these functions to work. --- .github/lexicon.txt | 2 ++ include/task.h | 49 ++++++++++++++++++++++++++++++++++++++------- tasks.c | 34 ++++++++++++++++++++++++------- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/.github/lexicon.txt b/.github/lexicon.txt index ac548204172..765b05c1eb5 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -2321,6 +2321,8 @@ ulstoppedtimercompensation ultablebase ultaskgetidleruntimecounter ultaskgetidleruntimepercent +ultaskgetruntimecounter +ultaskgetruntimepercent ultaskhasfpucontext ultasknotifystateclear ultasknotifytake diff --git a/include/task.h b/include/task.h index b01551d5366..f4e72c2c2f5 100644 --- a/include/task.h +++ b/include/task.h @@ -1934,6 +1934,42 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali */ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +/** + * task. h + * @code{c} + * configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ); + * configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ); + * @endcode + * + * configGENERATE_RUN_TIME_STATS must be defined as 1 for these functions to be + * available. The application must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE() to configure a peripheral timer/counter and + * return the timers current count value respectively. The counter should be + * at least 10 times the frequency of the tick count. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total + * execution time of each task into a buffer, ulTaskGetRunTimeCounter() + * returns the total execution time of just one task and + * ulTaskGetRunTimePercent() returns the percentage of the CPU time used by + * just one task. + * + * @return The total run time of the given task or the percentage of the total + * run time consumed by the given task. This is the amount of time the task + * has actually been executing. The unit of time is dependent on the frequency + * configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE() macros. + * + * \defgroup ulTaskGetRunTimeCounter ulTaskGetRunTimeCounter + * \ingroup TaskUtils + */ +configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + /** * task. h * @code{c} @@ -1941,13 +1977,12 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e * configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ); * @endcode * - * configGENERATE_RUN_TIME_STATS, configUSE_STATS_FORMATTING_FUNCTIONS and - * INCLUDE_xTaskGetIdleTaskHandle must all be defined as 1 for these functions - * to be available. The application must also then provide definitions for - * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() - * to configure a peripheral timer/counter and return the timers current count - * value respectively. The counter should be at least 10 times the frequency of - * the tick count. + * configGENERATE_RUN_TIME_STATS must be defined as 1 for these functions to be + * available. The application must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE() to configure a peripheral timer/counter and + * return the timers current count value respectively. The counter should be + * at least 10 times the frequency of the tick count. * * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total * accumulated execution time being stored for each task. The resolution diff --git a/tasks.c b/tasks.c index 3a0f0470e78..ac221afe739 100644 --- a/tasks.c +++ b/tasks.c @@ -5251,19 +5251,19 @@ TickType_t uxTaskResetEventItemValue( void ) #endif /* configUSE_TASK_NOTIFICATIONS */ /*-----------------------------------------------------------*/ -#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) +#if ( configGENERATE_RUN_TIME_STATS == 1 ) - configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) + configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) { - return xIdleTaskHandle->ulRunTimeCounter; + return xTask->ulRunTimeCounter; } #endif /*-----------------------------------------------------------*/ -#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) +#if ( configGENERATE_RUN_TIME_STATS == 1 ) - configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) + configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; @@ -5275,7 +5275,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - ulReturn = xIdleTaskHandle->ulRunTimeCounter / ulTotalTime; + ulReturn = xTask->ulRunTimeCounter / ulTotalTime; } else { @@ -5285,7 +5285,27 @@ TickType_t uxTaskResetEventItemValue( void ) return ulReturn; } -#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +#endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) + { + return ulTaskGetRunTimeCounter( xIdleTaskHandle ); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) + { + return ulTaskGetRunTimePercent( xIdleTaskHandle ); + } + +#endif /*-----------------------------------------------------------*/ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, From 260a37c082f4b70f9c6f361eadb0b29f1a448e3a Mon Sep 17 00:00:00 2001 From: "David J. Fiddes" <35607151+davefiddes@users.noreply.github.com> Date: Mon, 23 Jan 2023 17:16:24 +0000 Subject: [PATCH 043/109] Fix some CMake documentation typos (#616) The quick start instructions for CMake mention the "master" git branch which has been replaced by "main" in the current repo. The main CMakeLists.txt documents how to integrate a custom port. Fix a typo in the suggested CMake code. --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d4a7799f7c..09bd4bdb84d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,7 +217,7 @@ elseif((FREERTOS_PORT STREQUAL "A_CUSTOM_PORT") AND (NOT TARGET freertos_kernel_ " target_include_directories(freertos_kernel_port\n" " PUBLIC\n" " .)\n" - " taget_link_libraries(freertos_kernel_port\n" + " target_link_libraries(freertos_kernel_port\n" " PRIVATE\n" " freertos_kernel)") endif() diff --git a/README.md b/README.md index 5674872421c..025a135774f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Add the following into your project's main or a subdirectory's `CMakeLists.txt`: ```cmake FetchContent_Declare( freertos_kernel GIT_REPOSITORY https://github.com/FreeRTOS/FreeRTOS-Kernel.git - GIT_TAG master #Note: Best practice to use specific git-hash or tagged version + GIT_TAG main #Note: Best practice to use specific git-hash or tagged version ) ``` From 88674cb7a6b41ab6320f278935b11feb350cc3f9 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 30 Jan 2023 11:00:00 +0800 Subject: [PATCH 044/109] Update the uxSchedulerSuspended after prvCheckForRunStateChange * Update the uxSchedulerSuspended after the prvCheckForRunStateChange to prevent race condition in fromISR APIs --- tasks.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/tasks.c b/tasks.c index 91c0e6f937b..431097e1c01 100644 --- a/tasks.c +++ b/tasks.c @@ -671,7 +671,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; static void prvCheckForRunStateChange( void ) { UBaseType_t uxPrevCriticalNesting; - UBaseType_t uxPrevSchedulerSuspended; TCB_t * pxThisTCB; /* This should be skipped if called from an ISR. If the task on the current @@ -695,24 +694,19 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * and reacquire the correct locks. And then, do it all over again * if our state changed again during the reacquisition. */ uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT(); - uxPrevSchedulerSuspended = uxSchedulerSuspended; - - /* This must only be called the first time we enter into a critical - * section, otherwise it could context switch in the middle of a - * critical section. */ - configASSERT( ( uxPrevCriticalNesting + uxPrevSchedulerSuspended ) == 1U ); if( uxPrevCriticalNesting > 0U ) { portSET_CRITICAL_NESTING_COUNT( 0U ); + portRELEASE_ISR_LOCK(); } else { - portGET_ISR_LOCK(); - uxSchedulerSuspended = 0U; + /* The scheduler is suspended. uxSchedulerSuspended is updated + * only when the task is not requested to yield. */ + mtCOVERAGE_TEST_MARKER(); } - portRELEASE_ISR_LOCK(); portRELEASE_TASK_LOCK(); portMEMORY_BARRIER(); @@ -730,12 +724,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; portGET_ISR_LOCK(); portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting ); - uxSchedulerSuspended = uxPrevSchedulerSuspended; if( uxPrevCriticalNesting == 0U ) { - /* uxPrevSchedulerSuspended must be 1. */ - configASSERT( uxPrevSchedulerSuspended != ( UBaseType_t ) pdFALSE ); portRELEASE_ISR_LOCK(); } } @@ -3351,14 +3342,11 @@ void vTaskSuspendAll( void ) portSOFTWARE_BARRIER(); portGET_TASK_LOCK(); - portGET_ISR_LOCK(); - - /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment - * is used to allow calls to vTaskSuspendAll() to nest. */ - ++uxSchedulerSuspended; - portRELEASE_ISR_LOCK(); - if( uxSchedulerSuspended == 1U ) + /* uxSchedulerSuspended is increased after prvCheckForRunStateChange. The + * purpose is to prevent altering the variable when fromISR APIs are readying + * it. */ + if( uxSchedulerSuspended == 0U ) { if( portGET_CRITICAL_NESTING_COUNT() == 0U ) { @@ -3374,6 +3362,13 @@ void vTaskSuspendAll( void ) mtCOVERAGE_TEST_MARKER(); } + portGET_ISR_LOCK(); + + /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment + * is used to allow calls to vTaskSuspendAll() to nest. */ + ++uxSchedulerSuspended; + portRELEASE_ISR_LOCK(); + portCLEAR_INTERRUPT_MASK( ulState ); } else From 91c20f5f425b18b641765217586a82a62e1aa45a Mon Sep 17 00:00:00 2001 From: Dusan Cervenka Date: Fri, 3 Feb 2023 15:34:02 +0100 Subject: [PATCH 045/109] Added support of 64bit events. (#597) * Added support of 64bit even Signed-off-by: Cervenka Dusan * Added missing brackets Signed-off-by: Cervenka Dusan * Made proper name for tick macro. Signed-off-by: Cervenka Dusan * Improved macro evaluation Signed-off-by: Cervenka Dusan * Fixed missed port files + documentation Signed-off-by: Cervenka Dusan * Changes made on PR Signed-off-by: Cervenka Dusan * Fix macro definition. Signed-off-by: Cervenka Dusan * Formatted code with uncrustify Signed-off-by: Cervenka Dusan --------- Signed-off-by: Cervenka Dusan --- event_groups.c | 11 +++++-- include/FreeRTOS.h | 29 +++++++++++++++++-- include/event_groups.h | 26 +++++++++-------- include/projdefs.h | 8 +++-- portable/ARMv8M/non_secure/portmacrocommon.h | 6 ++-- portable/BCC/16BitDOS/Flsh186/prtmacro.h | 6 ++-- portable/BCC/16BitDOS/PC/prtmacro.h | 6 ++-- portable/CCS/ARM_CM3/portmacro.h | 6 ++-- portable/CCS/ARM_CM4F/portmacro.h | 6 ++-- portable/CCS/ARM_Cortex-R4/portmacro.h | 6 ++-- portable/CCS/MSP430X/portmacro.h | 8 +++-- portable/CodeWarrior/ColdFire_V1/portmacro.h | 8 +++-- portable/CodeWarrior/ColdFire_V2/portmacro.h | 8 +++-- portable/CodeWarrior/HCS12/portmacro.h | 8 +++-- portable/GCC/ARM7_AT91FR40008/portmacro.h | 8 +++-- portable/GCC/ARM7_AT91SAM7S/portmacro.h | 8 +++-- portable/GCC/ARM7_LPC2000/portmacro.h | 8 +++-- portable/GCC/ARM7_LPC23xx/portmacro.h | 8 +++-- portable/GCC/ARM_CM0/portmacro.h | 6 ++-- .../GCC/ARM_CM23/non_secure/portmacrocommon.h | 6 ++-- .../ARM_CM23_NTZ/non_secure/portmacrocommon.h | 6 ++-- portable/GCC/ARM_CM3/portmacro.h | 6 ++-- .../GCC/ARM_CM33/non_secure/portmacrocommon.h | 6 ++-- .../ARM_CM33_NTZ/non_secure/portmacrocommon.h | 6 ++-- portable/GCC/ARM_CM3_MPU/portmacro.h | 6 ++-- portable/GCC/ARM_CM4F/portmacro.h | 9 ++++-- portable/GCC/ARM_CM4_MPU/portmacro.h | 6 ++-- .../GCC/ARM_CM55/non_secure/portmacrocommon.h | 6 ++-- .../ARM_CM55_NTZ/non_secure/portmacrocommon.h | 6 ++-- portable/GCC/ARM_CM7/r0p1/portmacro.h | 6 ++-- .../GCC/ARM_CM85/non_secure/portmacrocommon.h | 6 ++-- .../ARM_CM85_NTZ/non_secure/portmacrocommon.h | 6 ++-- portable/GCC/ATMega323/portmacro.h | 8 +++-- portable/GCC/AVR32_UC3/portmacro.h | 8 +++-- portable/GCC/CORTUS_APS3/portmacro.h | 8 +++-- portable/GCC/ColdFire_V2/portmacro.h | 8 +++-- portable/GCC/H8S2329/portmacro.h | 8 +++-- portable/GCC/HCS12/portmacro.h | 8 +++-- portable/GCC/MSP430F449/portmacro.h | 8 +++-- portable/GCC/MicroBlaze/portmacro.h | 6 ++-- portable/GCC/MicroBlazeV8/portmacro.h | 6 ++-- portable/GCC/MicroBlazeV9/portmacro.h | 6 ++-- portable/GCC/NiosII/portmacro.h | 6 ++-- portable/GCC/PPC405_Xilinx/portmacro.h | 8 +++-- portable/GCC/PPC440_Xilinx/portmacro.h | 8 +++-- portable/GCC/RL78/portmacro.h | 8 +++-- portable/GCC/RX100/portmacro.h | 6 ++-- portable/GCC/RX200/portmacro.h | 6 ++-- portable/GCC/RX600/portmacro.h | 6 ++-- portable/GCC/RX600v2/portmacro.h | 6 ++-- portable/GCC/RX700v3_DPFPU/portmacro.h | 6 ++-- portable/GCC/STR75x/portmacro.h | 8 +++-- portable/GCC/TriCore_1782/portmacro.h | 6 ++-- portable/IAR/78K0R/portmacro.h | 8 +++-- portable/IAR/ARM_CM0/portmacro.h | 6 ++-- .../IAR/ARM_CM23/non_secure/portmacrocommon.h | 6 ++-- .../ARM_CM23_NTZ/non_secure/portmacrocommon.h | 6 ++-- portable/IAR/ARM_CM3/portmacro.h | 6 ++-- .../IAR/ARM_CM33/non_secure/portmacrocommon.h | 6 ++-- .../ARM_CM33_NTZ/non_secure/portmacrocommon.h | 6 ++-- portable/IAR/ARM_CM4F/portmacro.h | 6 ++-- portable/IAR/ARM_CM4F_MPU/portmacro.h | 6 ++-- .../IAR/ARM_CM55/non_secure/portmacrocommon.h | 6 ++-- .../ARM_CM55_NTZ/non_secure/portmacrocommon.h | 6 ++-- portable/IAR/ARM_CM7/r0p1/portmacro.h | 6 ++-- .../IAR/ARM_CM85/non_secure/portmacrocommon.h | 6 ++-- .../ARM_CM85_NTZ/non_secure/portmacrocommon.h | 6 ++-- portable/IAR/ATMega323/portmacro.h | 8 +++-- portable/IAR/AVR32_UC3/portmacro.h | 8 +++-- portable/IAR/AVR_AVRDx/portmacro.h | 8 +++-- portable/IAR/AVR_Mega0/portmacro.h | 8 +++-- portable/IAR/AtmelSAM7S64/portmacro.h | 8 +++-- portable/IAR/AtmelSAM9XE/portmacro.h | 8 +++-- portable/IAR/LPC2000/portmacro.h | 8 +++-- portable/IAR/MSP430/portmacro.h | 8 +++-- portable/IAR/MSP430X/portmacro.h | 8 +++-- portable/IAR/RL78/portmacro.h | 8 +++-- portable/IAR/RX100/portmacro.h | 6 ++-- portable/IAR/RX600/portmacro.h | 6 ++-- portable/IAR/RX700v3_DPFPU/portmacro.h | 6 ++-- portable/IAR/RXv2/portmacro.h | 6 ++-- portable/IAR/STR71x/portmacro.h | 8 +++-- portable/IAR/STR75x/portmacro.h | 8 +++-- portable/IAR/STR91x/portmacro.h | 8 +++-- portable/IAR/V850ES/portmacro.h | 8 +++-- portable/MPLAB/PIC18F/portmacro.h | 8 +++-- portable/MPLAB/PIC24_dsPIC/portmacro.h | 8 +++-- portable/MPLAB/PIC32MEC14xx/portmacro.h | 8 +++-- portable/MPLAB/PIC32MX/portmacro.h | 6 ++-- portable/MPLAB/PIC32MZ/portmacro.h | 6 ++-- portable/MSVC-MingW/portmacro.h | 6 ++-- portable/MikroC/ARM_CM4F/portmacro.h | 6 ++-- .../Tern_EE/large_untested/portmacro.h | 8 +++-- portable/Paradigm/Tern_EE/small/portmacro.h | 8 +++-- portable/RVDS/ARM7_LPC21xx/portmacro.h | 8 +++-- portable/RVDS/ARM_CA9/portmacro.h | 6 ++-- portable/RVDS/ARM_CM0/portmacro.h | 6 ++-- portable/RVDS/ARM_CM3/portmacro.h | 6 ++-- portable/RVDS/ARM_CM4F/portmacro.h | 6 ++-- portable/RVDS/ARM_CM4_MPU/portmacro.h | 6 ++-- portable/RVDS/ARM_CM7/r0p1/portmacro.h | 6 ++-- portable/Renesas/RX100/portmacro.h | 6 ++-- portable/Renesas/RX200/portmacro.h | 6 ++-- portable/Renesas/RX600/portmacro.h | 6 ++-- portable/Renesas/RX600v2/portmacro.h | 6 ++-- portable/Renesas/RX700v3_DPFPU/portmacro.h | 6 ++-- portable/Renesas/SH2A_FPU/portmacro.h | 4 +-- portable/Rowley/MSP430F449/portmacro.h | 8 +++-- portable/SDCC/Cygnal/portmacro.h | 8 +++-- portable/Softune/MB91460/portmacro.h | 8 +++-- portable/Softune/MB96340/portmacro.h | 8 +++-- portable/Tasking/ARM_CM4F/portmacro.h | 6 ++-- .../ThirdParty/CDK/T-HEAD_CK802/portmacro.h | 8 +++-- portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h | 8 +++-- portable/ThirdParty/GCC/ARC_v1/portmacro.h | 8 +++-- portable/ThirdParty/GCC/ATmega/portmacro.h | 8 +++-- .../ThirdParty/GCC/RP2040/include/portmacro.h | 6 ++-- portable/ThirdParty/GCC/RP2040/port.c | 12 ++++---- .../GCC/Xtensa_ESP32/include/portmacro.h | 6 ++-- portable/ThirdParty/XCC/Xtensa/portmacro.h | 6 ++-- portable/WizC/PIC18/portmacro.h | 6 ++-- portable/oWatcom/16BitDOS/Flsh186/portmacro.h | 8 +++-- portable/oWatcom/16BitDOS/PC/portmacro.h | 8 +++-- tasks.c | 6 ++-- 124 files changed, 588 insertions(+), 313 deletions(-) diff --git a/event_groups.c b/event_groups.c index c5a2aa080a5..a64c5ead34c 100644 --- a/event_groups.c +++ b/event_groups.c @@ -49,17 +49,22 @@ /* The following bit fields convey control information in a task's event list * item value. It is important they don't clash with the * taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ -#if configUSE_16_BIT_TICKS == 1 +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U #define eventWAIT_FOR_ALL_BITS 0x0400U #define eventEVENT_BITS_CONTROL_BYTES 0xff00U -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL #define eventWAIT_FOR_ALL_BITS 0x04000000UL #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL -#endif +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100000000000000ULL + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200000000000000ULL + #define eventWAIT_FOR_ALL_BITS 0x0400000000000000ULL + #define eventEVENT_BITS_CONTROL_BYTES 0xff00000000000000ULL +#endif /* if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) */ typedef struct EventGroupDef_t { diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index e7d779a7102..790a06db058 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -55,6 +55,11 @@ #endif /* *INDENT-ON* */ +/* Acceptable values for configTICK_TYPE_WIDTH_IN_BITS. */ +#define TICK_TYPE_WIDTH_16_BITS 0 +#define TICK_TYPE_WIDTH_32_BITS 1 +#define TICK_TYPE_WIDTH_64_BITS 2 + /* Application specific configuration options. */ #include "FreeRTOSConfig.h" @@ -155,8 +160,28 @@ #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif -#ifndef configUSE_16_BIT_TICKS - #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#if !defined( configUSE_16_BIT_TICKS ) && !defined( configTICK_TYPE_WIDTH_IN_BITS ) + #error Missing definition: One of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if defined( configUSE_16_BIT_TICKS ) && defined( configTICK_TYPE_WIDTH_IN_BITS ) + #error Only one of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +/* Define configTICK_TYPE_WIDTH_IN_BITS according to the + * value of configUSE_16_BIT_TICKS for backward compatibility. */ +#ifndef configTICK_TYPE_WIDTH_IN_BITS + #if ( configUSE_16_BIT_TICKS == 1 ) + #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_16_BITS + #else + #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS + #endif +#endif + +#if ( ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_16_BITS ) && \ + ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_32_BITS ) && \ + ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_64_BITS ) ) + #error Macro configTICK_TYPE_WIDTH_IN_BITS is defined to incorrect value. See the Configuration section of the FreeRTOS API documentation for details. #endif #ifndef INCLUDE_vTaskPrioritySet diff --git a/include/event_groups.h b/include/event_groups.h index 949ddd9143f..3f37d90be5d 100644 --- a/include/event_groups.h +++ b/include/event_groups.h @@ -84,8 +84,8 @@ typedef struct EventGroupDef_t * EventGroupHandle_t; /* * The type that holds event bits always matches TickType_t - therefore the - * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, - * 32 bits if set to 0. + * number of bits it holds is set by configTICK_TYPE_WIDTH_IN_BITS (16 bits if set to 0, + * 32 bits if set to 1, 64 bits if set to 2. * * \defgroup EventBits_t EventBits_t * \ingroup EventGroup @@ -112,11 +112,12 @@ typedef TickType_t EventBits_t; * * Although event groups are not related to ticks, for internal implementation * reasons the number of bits available for use in an event group is dependent - * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If - * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit - * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has - * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store - * event bits within an event group. + * on the configTICK_TYPE_WIDTH_IN_BITS setting in FreeRTOSConfig.h. If + * configTICK_TYPE_WIDTH_IN_BITS is 0 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configTICK_TYPE_WIDTH_IN_BITS is set to 1 then each event group has + * 24 usable bits (bit 0 to bit 23). If configTICK_TYPE_WIDTH_IN_BITS is set to 2 then + * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type + * is used to store event bits within an event group. * * @return If the event group was created then a handle to the event group is * returned. If there was insufficient FreeRTOS heap available to create the @@ -168,11 +169,12 @@ typedef TickType_t EventBits_t; * * Although event groups are not related to ticks, for internal implementation * reasons the number of bits available for use in an event group is dependent - * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If - * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit - * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has - * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store - * event bits within an event group. + * on the configTICK_TYPE_WIDTH_IN_BITS setting in FreeRTOSConfig.h. If + * configTICK_TYPE_WIDTH_IN_BITS is 0 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configTICK_TYPE_WIDTH_IN_BITS is set to 1 then each event group has + * 24 usable bits (bit 0 to bit 23). If configTICK_TYPE_WIDTH_IN_BITS is set to 2 then + * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type + * is used to store event bits within an event group. * * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type * StaticEventGroup_t, which will be then be used to hold the event group's data diff --git a/include/projdefs.h b/include/projdefs.h index b4b8c14ff79..67fc5351937 100644 --- a/include/projdefs.h +++ b/include/projdefs.h @@ -60,10 +60,14 @@ typedef void (* TaskFunction_t)( void * ); #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 #endif -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #define pdINTEGRITY_CHECK_VALUE 0x5a5a -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5a5a5a5a5aULL +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /* The following errno values are used by FreeRTOS+ components, not FreeRTOS diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/BCC/16BitDOS/Flsh186/prtmacro.h b/portable/BCC/16BitDOS/Flsh186/prtmacro.h index 5aaebaa4d8b..295c0bc736e 100644 --- a/portable/BCC/16BitDOS/Flsh186/prtmacro.h +++ b/portable/BCC/16BitDOS/Flsh186/prtmacro.h @@ -52,12 +52,14 @@ typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/BCC/16BitDOS/PC/prtmacro.h b/portable/BCC/16BitDOS/PC/prtmacro.h index 1d26c5bf416..5fb4ed6a497 100644 --- a/portable/BCC/16BitDOS/PC/prtmacro.h +++ b/portable/BCC/16BitDOS/PC/prtmacro.h @@ -52,12 +52,14 @@ typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/CCS/ARM_CM3/portmacro.h b/portable/CCS/ARM_CM3/portmacro.h index 5b5f4fbac07..7ac1d709caf 100644 --- a/portable/CCS/ARM_CM3/portmacro.h +++ b/portable/CCS/ARM_CM3/portmacro.h @@ -57,16 +57,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/CCS/ARM_CM4F/portmacro.h b/portable/CCS/ARM_CM4F/portmacro.h index 9e78588ad94..34988c223f5 100644 --- a/portable/CCS/ARM_CM4F/portmacro.h +++ b/portable/CCS/ARM_CM4F/portmacro.h @@ -57,16 +57,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/CCS/ARM_Cortex-R4/portmacro.h b/portable/CCS/ARM_Cortex-R4/portmacro.h index 5d9e91d66a9..07c1827cb7a 100644 --- a/portable/CCS/ARM_Cortex-R4/portmacro.h +++ b/portable/CCS/ARM_Cortex-R4/portmacro.h @@ -52,16 +52,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if (configUSE_16_BIT_TICKS == 1) +#if (configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS) typedef uint16_t TickType_t; #define portMAX_DELAY (TickType_t) 0xFFFF -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY (TickType_t) 0xFFFFFFFFF /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/CCS/MSP430X/portmacro.h b/portable/CCS/MSP430X/portmacro.h index 1d651c19410..064b0503ae4 100644 --- a/portable/CCS/MSP430X/portmacro.h +++ b/portable/CCS/MSP430X/portmacro.h @@ -62,12 +62,14 @@ typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/CodeWarrior/ColdFire_V1/portmacro.h b/portable/CodeWarrior/ColdFire_V1/portmacro.h index eca83debbab..edae69ab2b2 100644 --- a/portable/CodeWarrior/ColdFire_V1/portmacro.h +++ b/portable/CodeWarrior/ColdFire_V1/portmacro.h @@ -57,12 +57,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/CodeWarrior/ColdFire_V2/portmacro.h b/portable/CodeWarrior/ColdFire_V2/portmacro.h index 634d7404202..665ae4b304c 100644 --- a/portable/CodeWarrior/ColdFire_V2/portmacro.h +++ b/portable/CodeWarrior/ColdFire_V2/portmacro.h @@ -56,12 +56,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/CodeWarrior/HCS12/portmacro.h b/portable/CodeWarrior/HCS12/portmacro.h index 2fd14ae4e01..d0d0a140eb4 100644 --- a/portable/CodeWarrior/HCS12/portmacro.h +++ b/portable/CodeWarrior/HCS12/portmacro.h @@ -53,12 +53,14 @@ typedef portSTACK_TYPE StackType_t; typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM7_AT91FR40008/portmacro.h b/portable/GCC/ARM7_AT91FR40008/portmacro.h index 8a1666e1319..69ee70f078c 100644 --- a/portable/GCC/ARM7_AT91FR40008/portmacro.h +++ b/portable/GCC/ARM7_AT91FR40008/portmacro.h @@ -79,12 +79,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM7_AT91SAM7S/portmacro.h b/portable/GCC/ARM7_AT91SAM7S/portmacro.h index 4f514258805..1a440a68c5f 100644 --- a/portable/GCC/ARM7_AT91SAM7S/portmacro.h +++ b/portable/GCC/ARM7_AT91SAM7S/portmacro.h @@ -79,12 +79,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM7_LPC2000/portmacro.h b/portable/GCC/ARM7_LPC2000/portmacro.h index 84029962b58..50922065441 100644 --- a/portable/GCC/ARM7_LPC2000/portmacro.h +++ b/portable/GCC/ARM7_LPC2000/portmacro.h @@ -56,12 +56,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM7_LPC23xx/portmacro.h b/portable/GCC/ARM7_LPC23xx/portmacro.h index c69003ca8d0..768e86dbed1 100644 --- a/portable/GCC/ARM7_LPC23xx/portmacro.h +++ b/portable/GCC/ARM7_LPC23xx/portmacro.h @@ -79,12 +79,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM0/portmacro.h b/portable/GCC/ARM_CM0/portmacro.h index a89c8ba42d0..6d60fce4c90 100644 --- a/portable/GCC/ARM_CM0/portmacro.h +++ b/portable/GCC/ARM_CM0/portmacro.h @@ -57,16 +57,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM3/portmacro.h b/portable/GCC/ARM_CM3/portmacro.h index a7b45a5867a..c1f7b899217 100644 --- a/portable/GCC/ARM_CM3/portmacro.h +++ b/portable/GCC/ARM_CM3/portmacro.h @@ -57,16 +57,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM3_MPU/portmacro.h b/portable/GCC/ARM_CM3_MPU/portmacro.h index 693fc7b9091..d3b3af58f4c 100644 --- a/portable/GCC/ARM_CM3_MPU/portmacro.h +++ b/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -57,16 +57,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM4F/portmacro.h b/portable/GCC/ARM_CM4F/portmacro.h index 0ab47e05b86..1ffdc5b8b93 100644 --- a/portable/GCC/ARM_CM4F/portmacro.h +++ b/portable/GCC/ARM_CM4F/portmacro.h @@ -57,16 +57,21 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + typedef uint64_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffULL + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM4_MPU/portmacro.h b/portable/GCC/ARM_CM4_MPU/portmacro.h index 462075854ce..f3365d14371 100644 --- a/portable/GCC/ARM_CM4_MPU/portmacro.h +++ b/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -60,16 +60,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM7/r0p1/portmacro.h b/portable/GCC/ARM_CM7/r0p1/portmacro.h index 214dc2bffb5..d65a4c24932 100644 --- a/portable/GCC/ARM_CM7/r0p1/portmacro.h +++ b/portable/GCC/ARM_CM7/r0p1/portmacro.h @@ -57,16 +57,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ATMega323/portmacro.h b/portable/GCC/ATMega323/portmacro.h index 7afdef9075c..c22706de5d4 100644 --- a/portable/GCC/ATMega323/portmacro.h +++ b/portable/GCC/ATMega323/portmacro.h @@ -65,12 +65,14 @@ typedef portSTACK_TYPE StackType_t; typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/AVR32_UC3/portmacro.h b/portable/GCC/AVR32_UC3/portmacro.h index 2ebc711402a..86014a135b5 100644 --- a/portable/GCC/AVR32_UC3/portmacro.h +++ b/portable/GCC/AVR32_UC3/portmacro.h @@ -109,12 +109,14 @@ typedef unsigned long UBaseType_t; #define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL) -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/CORTUS_APS3/portmacro.h b/portable/GCC/CORTUS_APS3/portmacro.h index 486db878961..86000665681 100644 --- a/portable/GCC/CORTUS_APS3/portmacro.h +++ b/portable/GCC/CORTUS_APS3/portmacro.h @@ -58,12 +58,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ColdFire_V2/portmacro.h b/portable/GCC/ColdFire_V2/portmacro.h index 8792cd96d18..9b4c1da8833 100644 --- a/portable/GCC/ColdFire_V2/portmacro.h +++ b/portable/GCC/ColdFire_V2/portmacro.h @@ -56,12 +56,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/H8S2329/portmacro.h b/portable/GCC/H8S2329/portmacro.h index f568853fc4e..4c87abd163c 100644 --- a/portable/GCC/H8S2329/portmacro.h +++ b/portable/GCC/H8S2329/portmacro.h @@ -57,12 +57,14 @@ typedef portSTACK_TYPE StackType_t; typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/HCS12/portmacro.h b/portable/GCC/HCS12/portmacro.h index 1a458f9ae66..9202510ccc8 100644 --- a/portable/GCC/HCS12/portmacro.h +++ b/portable/GCC/HCS12/portmacro.h @@ -58,12 +58,14 @@ typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/MSP430F449/portmacro.h b/portable/GCC/MSP430F449/portmacro.h index 149de12178b..8d6827a57e9 100644 --- a/portable/GCC/MSP430F449/portmacro.h +++ b/portable/GCC/MSP430F449/portmacro.h @@ -56,12 +56,14 @@ typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/MicroBlaze/portmacro.h b/portable/GCC/MicroBlaze/portmacro.h index 5bc52ffe26c..7d96d5c9004 100644 --- a/portable/GCC/MicroBlaze/portmacro.h +++ b/portable/GCC/MicroBlaze/portmacro.h @@ -56,16 +56,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/MicroBlazeV8/portmacro.h b/portable/GCC/MicroBlazeV8/portmacro.h index 28e54017265..a4237336f2e 100644 --- a/portable/GCC/MicroBlazeV8/portmacro.h +++ b/portable/GCC/MicroBlazeV8/portmacro.h @@ -60,16 +60,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/MicroBlazeV9/portmacro.h b/portable/GCC/MicroBlazeV9/portmacro.h index f41205e3b93..84b358f5b5a 100644 --- a/portable/GCC/MicroBlazeV9/portmacro.h +++ b/portable/GCC/MicroBlazeV9/portmacro.h @@ -60,16 +60,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/NiosII/portmacro.h b/portable/GCC/NiosII/portmacro.h index fb482ffb978..7a159925db2 100644 --- a/portable/GCC/NiosII/portmacro.h +++ b/portable/GCC/NiosII/portmacro.h @@ -58,16 +58,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/PPC405_Xilinx/portmacro.h b/portable/GCC/PPC405_Xilinx/portmacro.h index eaad8fe7b75..d7f32944c40 100644 --- a/portable/GCC/PPC405_Xilinx/portmacro.h +++ b/portable/GCC/PPC405_Xilinx/portmacro.h @@ -58,12 +58,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/PPC440_Xilinx/portmacro.h b/portable/GCC/PPC440_Xilinx/portmacro.h index eaad8fe7b75..d7f32944c40 100644 --- a/portable/GCC/PPC440_Xilinx/portmacro.h +++ b/portable/GCC/PPC440_Xilinx/portmacro.h @@ -58,12 +58,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/RL78/portmacro.h b/portable/GCC/RL78/portmacro.h index 4b3cc497235..8108f1c1221 100644 --- a/portable/GCC/RL78/portmacro.h +++ b/portable/GCC/RL78/portmacro.h @@ -54,12 +54,14 @@ typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/RX100/portmacro.h b/portable/GCC/RX100/portmacro.h index 842754f1f1e..863596685aa 100644 --- a/portable/GCC/RX100/portmacro.h +++ b/portable/GCC/RX100/portmacro.h @@ -63,16 +63,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/RX200/portmacro.h b/portable/GCC/RX200/portmacro.h index 7c3fefc253c..80fc8c8041d 100644 --- a/portable/GCC/RX200/portmacro.h +++ b/portable/GCC/RX200/portmacro.h @@ -64,16 +64,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/RX600/portmacro.h b/portable/GCC/RX600/portmacro.h index 5919edfe081..7e1fd1e0c92 100644 --- a/portable/GCC/RX600/portmacro.h +++ b/portable/GCC/RX600/portmacro.h @@ -64,16 +64,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/RX600v2/portmacro.h b/portable/GCC/RX600v2/portmacro.h index 5919edfe081..7e1fd1e0c92 100644 --- a/portable/GCC/RX600v2/portmacro.h +++ b/portable/GCC/RX600v2/portmacro.h @@ -64,16 +64,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/RX700v3_DPFPU/portmacro.h b/portable/GCC/RX700v3_DPFPU/portmacro.h index 75d405fb8a1..6b76374c882 100644 --- a/portable/GCC/RX700v3_DPFPU/portmacro.h +++ b/portable/GCC/RX700v3_DPFPU/portmacro.h @@ -76,16 +76,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/STR75x/portmacro.h b/portable/GCC/STR75x/portmacro.h index b7fbe669305..85262dac4d5 100644 --- a/portable/GCC/STR75x/portmacro.h +++ b/portable/GCC/STR75x/portmacro.h @@ -57,12 +57,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/TriCore_1782/portmacro.h b/portable/GCC/TriCore_1782/portmacro.h index 4e51954afcc..734abc5949c 100644 --- a/portable/GCC/TriCore_1782/portmacro.h +++ b/portable/GCC/TriCore_1782/portmacro.h @@ -60,16 +60,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*---------------------------------------------------------------------------*/ diff --git a/portable/IAR/78K0R/portmacro.h b/portable/IAR/78K0R/portmacro.h index 673cf156c4f..e6f67cdd3b7 100644 --- a/portable/IAR/78K0R/portmacro.h +++ b/portable/IAR/78K0R/portmacro.h @@ -57,12 +57,14 @@ typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if (configUSE_16_BIT_TICKS==1) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef unsigned int TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM0/portmacro.h b/portable/IAR/ARM_CM0/portmacro.h index 00561582349..ce1aa08fc9d 100644 --- a/portable/IAR/ARM_CM0/portmacro.h +++ b/portable/IAR/ARM_CM0/portmacro.h @@ -57,16 +57,18 @@ typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM3/portmacro.h b/portable/IAR/ARM_CM3/portmacro.h index 3825a7c5317..c334978ea73 100644 --- a/portable/IAR/ARM_CM3/portmacro.h +++ b/portable/IAR/ARM_CM3/portmacro.h @@ -60,16 +60,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM4F/portmacro.h b/portable/IAR/ARM_CM4F/portmacro.h index e6c8726f5f8..148c81d14ee 100644 --- a/portable/IAR/ARM_CM4F/portmacro.h +++ b/portable/IAR/ARM_CM4F/portmacro.h @@ -59,16 +59,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM4F_MPU/portmacro.h b/portable/IAR/ARM_CM4F_MPU/portmacro.h index 1e44234fae4..96787e7c31f 100644 --- a/portable/IAR/ARM_CM4F_MPU/portmacro.h +++ b/portable/IAR/ARM_CM4F_MPU/portmacro.h @@ -62,16 +62,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM7/r0p1/portmacro.h b/portable/IAR/ARM_CM7/r0p1/portmacro.h index 813cc545a4c..08867c289c3 100644 --- a/portable/IAR/ARM_CM7/r0p1/portmacro.h +++ b/portable/IAR/ARM_CM7/r0p1/portmacro.h @@ -59,16 +59,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 51e21ea8ddd..ca7e9225c05 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -72,16 +72,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ATMega323/portmacro.h b/portable/IAR/ATMega323/portmacro.h index 973d6d9cac9..111f4d02667 100644 --- a/portable/IAR/ATMega323/portmacro.h +++ b/portable/IAR/ATMega323/portmacro.h @@ -64,12 +64,14 @@ typedef portSTACK_TYPE StackType_t; typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/AVR32_UC3/portmacro.h b/portable/IAR/AVR32_UC3/portmacro.h index f2d02e2fa7e..eb48b59b589 100644 --- a/portable/IAR/AVR32_UC3/portmacro.h +++ b/portable/IAR/AVR32_UC3/portmacro.h @@ -112,12 +112,14 @@ typedef unsigned long UBaseType_t; #define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL) -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/AVR_AVRDx/portmacro.h b/portable/IAR/AVR_AVRDx/portmacro.h index d02c691bd86..5b4b5be8b3c 100644 --- a/portable/IAR/AVR_AVRDx/portmacro.h +++ b/portable/IAR/AVR_AVRDx/portmacro.h @@ -60,12 +60,14 @@ typedef portSTACK_TYPE StackType_t; typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/AVR_Mega0/portmacro.h b/portable/IAR/AVR_Mega0/portmacro.h index d02c691bd86..5b4b5be8b3c 100644 --- a/portable/IAR/AVR_Mega0/portmacro.h +++ b/portable/IAR/AVR_Mega0/portmacro.h @@ -60,12 +60,14 @@ typedef portSTACK_TYPE StackType_t; typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/AtmelSAM7S64/portmacro.h b/portable/IAR/AtmelSAM7S64/portmacro.h index 3c651b0398e..173d3fbaa2d 100644 --- a/portable/IAR/AtmelSAM7S64/portmacro.h +++ b/portable/IAR/AtmelSAM7S64/portmacro.h @@ -57,12 +57,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/AtmelSAM9XE/portmacro.h b/portable/IAR/AtmelSAM9XE/portmacro.h index 623a7b060db..3d1d82ec17b 100644 --- a/portable/IAR/AtmelSAM9XE/portmacro.h +++ b/portable/IAR/AtmelSAM9XE/portmacro.h @@ -60,12 +60,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/LPC2000/portmacro.h b/portable/IAR/LPC2000/portmacro.h index e7fd1097b78..f41d8b3445e 100644 --- a/portable/IAR/LPC2000/portmacro.h +++ b/portable/IAR/LPC2000/portmacro.h @@ -60,12 +60,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/MSP430/portmacro.h b/portable/IAR/MSP430/portmacro.h index 8659c4f02fa..298307f5519 100644 --- a/portable/IAR/MSP430/portmacro.h +++ b/portable/IAR/MSP430/portmacro.h @@ -53,12 +53,14 @@ typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/MSP430X/portmacro.h b/portable/IAR/MSP430X/portmacro.h index d7d60480456..1ab4665b9bf 100644 --- a/portable/IAR/MSP430X/portmacro.h +++ b/portable/IAR/MSP430X/portmacro.h @@ -62,12 +62,14 @@ typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/RL78/portmacro.h b/portable/IAR/RL78/portmacro.h index 7467c33f18a..9c74a3f0452 100644 --- a/portable/IAR/RL78/portmacro.h +++ b/portable/IAR/RL78/portmacro.h @@ -75,12 +75,14 @@ typedef unsigned short UBaseType_t; #endif -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef unsigned int TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/RX100/portmacro.h b/portable/IAR/RX100/portmacro.h index ff1dc0eb92d..d408a1389a5 100644 --- a/portable/IAR/RX100/portmacro.h +++ b/portable/IAR/RX100/portmacro.h @@ -64,16 +64,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/RX600/portmacro.h b/portable/IAR/RX600/portmacro.h index e80f52a63ca..e5decdaf34a 100644 --- a/portable/IAR/RX600/portmacro.h +++ b/portable/IAR/RX600/portmacro.h @@ -61,16 +61,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/RX700v3_DPFPU/portmacro.h b/portable/IAR/RX700v3_DPFPU/portmacro.h index 8538b152b49..e0204fa0c3c 100644 --- a/portable/IAR/RX700v3_DPFPU/portmacro.h +++ b/portable/IAR/RX700v3_DPFPU/portmacro.h @@ -79,16 +79,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/RXv2/portmacro.h b/portable/IAR/RXv2/portmacro.h index 07444eb35ae..984a4fb50e2 100644 --- a/portable/IAR/RXv2/portmacro.h +++ b/portable/IAR/RXv2/portmacro.h @@ -61,16 +61,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/STR71x/portmacro.h b/portable/IAR/STR71x/portmacro.h index 492bfb2ae8b..119eec84786 100644 --- a/portable/IAR/STR71x/portmacro.h +++ b/portable/IAR/STR71x/portmacro.h @@ -61,12 +61,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/STR75x/portmacro.h b/portable/IAR/STR75x/portmacro.h index b852c644120..674505d3f0c 100644 --- a/portable/IAR/STR75x/portmacro.h +++ b/portable/IAR/STR75x/portmacro.h @@ -60,12 +60,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/STR91x/portmacro.h b/portable/IAR/STR91x/portmacro.h index a8b24da878f..43ea6d7e8dc 100644 --- a/portable/IAR/STR91x/portmacro.h +++ b/portable/IAR/STR91x/portmacro.h @@ -60,12 +60,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/V850ES/portmacro.h b/portable/IAR/V850ES/portmacro.h index 0381f024471..76b1186761d 100644 --- a/portable/IAR/V850ES/portmacro.h +++ b/portable/IAR/V850ES/portmacro.h @@ -57,12 +57,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if (configUSE_16_BIT_TICKS==1) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/MPLAB/PIC18F/portmacro.h b/portable/MPLAB/PIC18F/portmacro.h index 9b1e44e6a8a..6fef1afe2dd 100644 --- a/portable/MPLAB/PIC18F/portmacro.h +++ b/portable/MPLAB/PIC18F/portmacro.h @@ -52,12 +52,14 @@ typedef portSTACK_TYPE StackType_t; typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/MPLAB/PIC24_dsPIC/portmacro.h b/portable/MPLAB/PIC24_dsPIC/portmacro.h index 2a6f44b18ec..d05317e6f8c 100644 --- a/portable/MPLAB/PIC24_dsPIC/portmacro.h +++ b/portable/MPLAB/PIC24_dsPIC/portmacro.h @@ -56,15 +56,17 @@ typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff /* 16-bit tick type on a 16-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/MPLAB/PIC32MEC14xx/portmacro.h b/portable/MPLAB/PIC32MEC14xx/portmacro.h index dad5aa3530f..d9aad5df0aa 100644 --- a/portable/MPLAB/PIC32MEC14xx/portmacro.h +++ b/portable/MPLAB/PIC32MEC14xx/portmacro.h @@ -56,12 +56,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/MPLAB/PIC32MX/portmacro.h b/portable/MPLAB/PIC32MX/portmacro.h index a81dbf341d6..e2a1078e631 100644 --- a/portable/MPLAB/PIC32MX/portmacro.h +++ b/portable/MPLAB/PIC32MX/portmacro.h @@ -59,16 +59,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/MPLAB/PIC32MZ/portmacro.h b/portable/MPLAB/PIC32MZ/portmacro.h index 43d65985504..17b266e1124 100644 --- a/portable/MPLAB/PIC32MZ/portmacro.h +++ b/portable/MPLAB/PIC32MZ/portmacro.h @@ -59,16 +59,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/MSVC-MingW/portmacro.h b/portable/MSVC-MingW/portmacro.h index 3cbb06b5533..b1282b3d71e 100644 --- a/portable/MSVC-MingW/portmacro.h +++ b/portable/MSVC-MingW/portmacro.h @@ -50,16 +50,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32/64-bit tick type on a 32/64-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /* Hardware specifics. */ diff --git a/portable/MikroC/ARM_CM4F/portmacro.h b/portable/MikroC/ARM_CM4F/portmacro.h index 1fa3d796403..fa614c31488 100644 --- a/portable/MikroC/ARM_CM4F/portmacro.h +++ b/portable/MikroC/ARM_CM4F/portmacro.h @@ -62,16 +62,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Paradigm/Tern_EE/large_untested/portmacro.h b/portable/Paradigm/Tern_EE/large_untested/portmacro.h index 753686c5a2c..ed513309c7c 100644 --- a/portable/Paradigm/Tern_EE/large_untested/portmacro.h +++ b/portable/Paradigm/Tern_EE/large_untested/portmacro.h @@ -57,12 +57,14 @@ typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Paradigm/Tern_EE/small/portmacro.h b/portable/Paradigm/Tern_EE/small/portmacro.h index 5918b04be60..9eb5b863023 100644 --- a/portable/Paradigm/Tern_EE/small/portmacro.h +++ b/portable/Paradigm/Tern_EE/small/portmacro.h @@ -59,12 +59,14 @@ typedef unsigned short UBaseType_t; typedef void ( __interrupt __far *pxISR )(); -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/RVDS/ARM7_LPC21xx/portmacro.h b/portable/RVDS/ARM7_LPC21xx/portmacro.h index 821d2e2f26e..95043eb8deb 100644 --- a/portable/RVDS/ARM7_LPC21xx/portmacro.h +++ b/portable/RVDS/ARM7_LPC21xx/portmacro.h @@ -60,12 +60,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/RVDS/ARM_CA9/portmacro.h b/portable/RVDS/ARM_CA9/portmacro.h index a092952a940..65dd8174f7c 100644 --- a/portable/RVDS/ARM_CA9/portmacro.h +++ b/portable/RVDS/ARM_CA9/portmacro.h @@ -57,16 +57,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/RVDS/ARM_CM0/portmacro.h b/portable/RVDS/ARM_CM0/portmacro.h index c6cd9e859c1..54165e74cc4 100644 --- a/portable/RVDS/ARM_CM0/portmacro.h +++ b/portable/RVDS/ARM_CM0/portmacro.h @@ -59,16 +59,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/RVDS/ARM_CM3/portmacro.h b/portable/RVDS/ARM_CM3/portmacro.h index 5ecfb7b0e8b..c23a6b3fdbd 100644 --- a/portable/RVDS/ARM_CM3/portmacro.h +++ b/portable/RVDS/ARM_CM3/portmacro.h @@ -59,16 +59,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/RVDS/ARM_CM4F/portmacro.h b/portable/RVDS/ARM_CM4F/portmacro.h index 1b3f93b0e97..de92c8d4bd9 100644 --- a/portable/RVDS/ARM_CM4F/portmacro.h +++ b/portable/RVDS/ARM_CM4F/portmacro.h @@ -59,16 +59,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/RVDS/ARM_CM4_MPU/portmacro.h b/portable/RVDS/ARM_CM4_MPU/portmacro.h index ac89aedac97..c7cd5628951 100644 --- a/portable/RVDS/ARM_CM4_MPU/portmacro.h +++ b/portable/RVDS/ARM_CM4_MPU/portmacro.h @@ -59,16 +59,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/RVDS/ARM_CM7/r0p1/portmacro.h b/portable/RVDS/ARM_CM7/r0p1/portmacro.h index a46ec16bce0..a8fa6630e65 100644 --- a/portable/RVDS/ARM_CM7/r0p1/portmacro.h +++ b/portable/RVDS/ARM_CM7/r0p1/portmacro.h @@ -59,16 +59,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Renesas/RX100/portmacro.h b/portable/Renesas/RX100/portmacro.h index cc789b2be6f..9bcbd3c8c3d 100644 --- a/portable/Renesas/RX100/portmacro.h +++ b/portable/Renesas/RX100/portmacro.h @@ -61,16 +61,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Renesas/RX200/portmacro.h b/portable/Renesas/RX200/portmacro.h index fc20449a7d5..62a085023e2 100644 --- a/portable/Renesas/RX200/portmacro.h +++ b/portable/Renesas/RX200/portmacro.h @@ -61,16 +61,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Renesas/RX600/portmacro.h b/portable/Renesas/RX600/portmacro.h index 1430b54a9f0..3b29cbddb50 100644 --- a/portable/Renesas/RX600/portmacro.h +++ b/portable/Renesas/RX600/portmacro.h @@ -61,16 +61,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Renesas/RX600v2/portmacro.h b/portable/Renesas/RX600v2/portmacro.h index eb12462272d..d67a8f892aa 100644 --- a/portable/Renesas/RX600v2/portmacro.h +++ b/portable/Renesas/RX600v2/portmacro.h @@ -61,16 +61,18 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Renesas/RX700v3_DPFPU/portmacro.h b/portable/Renesas/RX700v3_DPFPU/portmacro.h index da1e0b1d67e..12657ee82bf 100644 --- a/portable/Renesas/RX700v3_DPFPU/portmacro.h +++ b/portable/Renesas/RX700v3_DPFPU/portmacro.h @@ -79,16 +79,18 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Renesas/SH2A_FPU/portmacro.h b/portable/Renesas/SH2A_FPU/portmacro.h index 8fb7e66a536..422cd59ed48 100644 --- a/portable/Renesas/SH2A_FPU/portmacro.h +++ b/portable/Renesas/SH2A_FPU/portmacro.h @@ -60,10 +60,10 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL diff --git a/portable/Rowley/MSP430F449/portmacro.h b/portable/Rowley/MSP430F449/portmacro.h index c56e436d984..7137a6e0964 100644 --- a/portable/Rowley/MSP430F449/portmacro.h +++ b/portable/Rowley/MSP430F449/portmacro.h @@ -53,12 +53,14 @@ typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/SDCC/Cygnal/portmacro.h b/portable/SDCC/Cygnal/portmacro.h index f4fa20e8478..04186381f62 100644 --- a/portable/SDCC/Cygnal/portmacro.h +++ b/portable/SDCC/Cygnal/portmacro.h @@ -61,12 +61,14 @@ typedef portSTACK_TYPE StackType_t; typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Softune/MB91460/portmacro.h b/portable/Softune/MB91460/portmacro.h index 2a3c6f189fb..9ae6959c46b 100644 --- a/portable/Softune/MB91460/portmacro.h +++ b/portable/Softune/MB91460/portmacro.h @@ -59,12 +59,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Softune/MB96340/portmacro.h b/portable/Softune/MB96340/portmacro.h index c953083f13e..827874fde9d 100644 --- a/portable/Softune/MB96340/portmacro.h +++ b/portable/Softune/MB96340/portmacro.h @@ -65,12 +65,14 @@ typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/Tasking/ARM_CM4F/portmacro.h b/portable/Tasking/ARM_CM4F/portmacro.h index a59418cb1ab..3371f34f47a 100644 --- a/portable/Tasking/ARM_CM4F/portmacro.h +++ b/portable/Tasking/ARM_CM4F/portmacro.h @@ -58,16 +58,18 @@ typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/CDK/T-HEAD_CK802/portmacro.h b/portable/ThirdParty/CDK/T-HEAD_CK802/portmacro.h index ac00ff54ab0..b82e48695d9 100644 --- a/portable/ThirdParty/CDK/T-HEAD_CK802/portmacro.h +++ b/portable/ThirdParty/CDK/T-HEAD_CK802/portmacro.h @@ -60,12 +60,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef void (*portvectorfunc)(void); -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h b/portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h index d41ad8534cf..49b15b09959 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h +++ b/portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h @@ -82,12 +82,14 @@ typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef unsigned int TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) diff --git a/portable/ThirdParty/GCC/ARC_v1/portmacro.h b/portable/ThirdParty/GCC/ARC_v1/portmacro.h index d8850e75897..72fbb49759e 100644 --- a/portable/ThirdParty/GCC/ARC_v1/portmacro.h +++ b/portable/ThirdParty/GCC/ARC_v1/portmacro.h @@ -81,12 +81,14 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef unsigned int TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) diff --git a/portable/ThirdParty/GCC/ATmega/portmacro.h b/portable/ThirdParty/GCC/ATmega/portmacro.h index 40e59ff2ba6..3e7714eb836 100644 --- a/portable/ThirdParty/GCC/ATmega/portmacro.h +++ b/portable/ThirdParty/GCC/ATmega/portmacro.h @@ -56,12 +56,14 @@ typedef uint8_t StackType_t; typedef int8_t BaseType_t; typedef uint8_t UBaseType_t; -#if configUSE_16_BIT_TICKS == 1 +#if configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/GCC/RP2040/include/portmacro.h b/portable/ThirdParty/GCC/RP2040/include/portmacro.h index 105600d1305..f19e96a0141 100644 --- a/portable/ThirdParty/GCC/RP2040/include/portmacro.h +++ b/portable/ThirdParty/GCC/RP2040/include/portmacro.h @@ -58,16 +58,18 @@ typedef int32_t BaseType_t; typedef uint32_t UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/GCC/RP2040/port.c b/portable/ThirdParty/GCC/RP2040/port.c index 550c1794d50..41dd114a001 100644 --- a/portable/ThirdParty/GCC/RP2040/port.c +++ b/portable/ThirdParty/GCC/RP2040/port.c @@ -706,24 +706,24 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) static inline EventBits_t prvGetEventGroupBit( spin_lock_t * spinLock ) { uint32_t ulBit; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) ulBit = 1u << (spin_lock_get_num(spinLock) & 0x7u); - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) ulBit = 1u << spin_lock_get_num(spinLock); /* reduce to range 0-24 */ ulBit |= ulBit << 8u; ulBit >>= 8u; - #endif /* configUSE_16_BIT_TICKS */ + #endif /* configTICK_TYPE_WIDTH_IN_BITS */ return ( EventBits_t ) ulBit; } static inline EventBits_t prvGetAllEventGroupBits() { - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) return (EventBits_t) 0xffu; - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) return ( EventBits_t ) 0xffffffu; - #endif /* configUSE_16_BIT_TICKS */ + #endif /* configTICK_TYPE_WIDTH_IN_BITS */ } void vPortLockInternalSpinUnlockWithWait( struct lock_core * pxLock, uint32_t ulSave ) diff --git a/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h b/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h index d66ca3da5a0..e87d560cfcd 100644 --- a/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h +++ b/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h @@ -119,12 +119,14 @@ typedef portBASE_TYPE BaseType_t; typedef unsigned portBASE_TYPE UBaseType_t; - #if ( configUSE_16_BIT_TICKS == 1 ) + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff - #else + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/XCC/Xtensa/portmacro.h b/portable/ThirdParty/XCC/Xtensa/portmacro.h index a0b87a007a6..c81576c9f78 100644 --- a/portable/ThirdParty/XCC/Xtensa/portmacro.h +++ b/portable/ThirdParty/XCC/Xtensa/portmacro.h @@ -70,12 +70,14 @@ typedef portSTACK_TYPE StackType_t; typedef portBASE_TYPE BaseType_t; typedef unsigned portBASE_TYPE UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/WizC/PIC18/portmacro.h b/portable/WizC/PIC18/portmacro.h index fea77758b77..ad70560e4ad 100644 --- a/portable/WizC/PIC18/portmacro.h +++ b/portable/WizC/PIC18/portmacro.h @@ -58,12 +58,14 @@ typedef signed char BaseType_t; typedef unsigned char UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) ( 0xFFFF ) -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif #define portBYTE_ALIGNMENT 1 diff --git a/portable/oWatcom/16BitDOS/Flsh186/portmacro.h b/portable/oWatcom/16BitDOS/Flsh186/portmacro.h index 29e8270b571..a2b4c16a40b 100644 --- a/portable/oWatcom/16BitDOS/Flsh186/portmacro.h +++ b/portable/oWatcom/16BitDOS/Flsh186/portmacro.h @@ -58,12 +58,14 @@ typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/portable/oWatcom/16BitDOS/PC/portmacro.h b/portable/oWatcom/16BitDOS/PC/portmacro.h index 6c8e022b410..ab4eea87210 100644 --- a/portable/oWatcom/16BitDOS/PC/portmacro.h +++ b/portable/oWatcom/16BitDOS/PC/portmacro.h @@ -57,12 +57,14 @@ typedef short BaseType_t; typedef unsigned short UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ diff --git a/tasks.c b/tasks.c index ac221afe739..845af7daa7b 100644 --- a/tasks.c +++ b/tasks.c @@ -241,10 +241,12 @@ * the scheduler that the value should not be changed - in which case it is the * responsibility of whichever module is using the value to ensure it gets set back * to its original value when it is released. */ -#if ( configUSE_16_BIT_TICKS == 1 ) +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U -#else +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000000000000000ULL #endif /* From 050cf0d80f4a25c06a37efa7ab6f1b4c877a84b0 Mon Sep 17 00:00:00 2001 From: bbain <16752579+bbain@users.noreply.github.com> Date: Mon, 13 Feb 2023 15:58:20 +1100 Subject: [PATCH 046/109] Introduce portMEMORY_BARRIER for Microblaze port. (#621) The introduction of `portMEMORY_BARRIER` will ensure the places in the kernel use a barrier will work. For example, `xTaskResumeAll` has a memory barrier to ensure its correctness when compiled with optimization enabled. Without the barrier `xTaskResumeAll` can fail (e.g. start reading and writing to address 0 and/or infinite looping) when `xPendingReadyList` contains more than one task to restore. In `xTaskResumeAll` the compiler chooses to cache the `pxTCB` the first time through the loop for use in every subsequent loop. This is incorrect as the removal of `pxTCB->xEventListItem` will actually change the value of `pxTCB` if it was read again at the top of the loop. The barrier forces the compiler to read `pxTCB` again at the top of the loop. The compiler is operating correctly. The removal `pxTCB->xEventListItem` executes on a `List_t *` and `ListItem_t *`. This means that the compiler can assume that any `MiniListItem_t` values are unchanged by the loop (i.e. "strict-aliasing"). This allows the compiler to cache `pxTCB` as it is obtained via a `MiniListItem_t`. This is incorrect in this case because it is possible for a `ListItem_t *` to actually alias a `MiniListItem_t`. This is technically a "violation of aliasing rules" so we use the the barrier to disable the strict-aliasing optimization in this loop. --- portable/GCC/MicroBlaze/portmacro.h | 1 + portable/GCC/MicroBlazeV8/portmacro.h | 1 + portable/GCC/MicroBlazeV9/portmacro.h | 1 + 3 files changed, 3 insertions(+) diff --git a/portable/GCC/MicroBlaze/portmacro.h b/portable/GCC/MicroBlaze/portmacro.h index 7d96d5c9004..c646496ab3f 100644 --- a/portable/GCC/MicroBlaze/portmacro.h +++ b/portable/GCC/MicroBlaze/portmacro.h @@ -115,6 +115,7 @@ void vTaskSwitchContext(); #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portNOP() asm volatile ( "NOP" ) +#define portMEMORY_BARRIER() asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ diff --git a/portable/GCC/MicroBlazeV8/portmacro.h b/portable/GCC/MicroBlazeV8/portmacro.h index a4237336f2e..be9dfacc42f 100644 --- a/portable/GCC/MicroBlazeV8/portmacro.h +++ b/portable/GCC/MicroBlazeV8/portmacro.h @@ -152,6 +152,7 @@ extern volatile uint32_t ulTaskSwitchRequested; #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portNOP() asm volatile ( "NOP" ) +#define portMEMORY_BARRIER() asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ diff --git a/portable/GCC/MicroBlazeV9/portmacro.h b/portable/GCC/MicroBlazeV9/portmacro.h index 84b358f5b5a..c26daa79fc2 100644 --- a/portable/GCC/MicroBlazeV9/portmacro.h +++ b/portable/GCC/MicroBlazeV9/portmacro.h @@ -152,6 +152,7 @@ extern volatile uint32_t ulTaskSwitchRequested; #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portNOP() asm volatile ( "NOP" ) +#define portMEMORY_BARRIER() asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) From 8252edec4547afed4e6ada74bd9353b52972894f Mon Sep 17 00:00:00 2001 From: Ju1He1 <93189163+Ju1He1@users.noreply.github.com> Date: Wed, 15 Feb 2023 07:10:32 +0100 Subject: [PATCH 047/109] Do not call exit() on MSVC Port when calling vPortEndScheduler (#624) * make port exitable * correctly set xPortRunning to False * add suggestions from Review Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * add suggestions from Review Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- portable/MSVC-MingW/port.c | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/portable/MSVC-MingW/port.c b/portable/MSVC-MingW/port.c index 67b79baa917..f39f0ecbb88 100644 --- a/portable/MSVC-MingW/port.c +++ b/portable/MSVC-MingW/port.c @@ -160,7 +160,7 @@ TIMECAPS xTimeCaps; /* Just to prevent compiler warnings. */ ( void ) lpParameter; - for( ;; ) + while( xPortRunning == pdTRUE ) { /* Wait until the timer expires and we can access the simulated interrupt variables. *NOTE* this is not a 'real time' way of generating tick @@ -177,32 +177,32 @@ TIMECAPS xTimeCaps; Sleep( portTICK_PERIOD_MS ); } - configASSERT( xPortRunning ); + if( xPortRunning == pdTRUE ) + { + configASSERT( xPortRunning ); - /* Can't proceed if in a critical section as pvInterruptEventMutex won't - be available. */ - WaitForSingleObject( pvInterruptEventMutex, INFINITE ); + /* Can't proceed if in a critical section as pvInterruptEventMutex won't + be available. */ + WaitForSingleObject( pvInterruptEventMutex, INFINITE ); - /* The timer has expired, generate the simulated tick event. */ - ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK ); + /* The timer has expired, generate the simulated tick event. */ + ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK ); - /* The interrupt is now pending - notify the simulated interrupt - handler thread. Must be outside of a critical section to get here so - the handler thread can execute immediately pvInterruptEventMutex is - released. */ - configASSERT( ulCriticalNesting == 0UL ); - SetEvent( pvInterruptEvent ); + /* The interrupt is now pending - notify the simulated interrupt + handler thread. Must be outside of a critical section to get here so + the handler thread can execute immediately pvInterruptEventMutex is + released. */ + configASSERT( ulCriticalNesting == 0UL ); + SetEvent( pvInterruptEvent ); - /* Give back the mutex so the simulated interrupt handler unblocks - and can access the interrupt handler variables. */ - ReleaseMutex( pvInterruptEventMutex ); + /* Give back the mutex so the simulated interrupt handler unblocks + and can access the interrupt handler variables. */ + ReleaseMutex( pvInterruptEventMutex ); + } } - #ifdef __GNUC__ - /* Should never reach here - MingW complains if you leave this line out, - MSVC complains if you put it in. */ - return 0; - #endif + + return 0; } /*-----------------------------------------------------------*/ @@ -566,7 +566,7 @@ uint32_t ulErrorCode; void vPortEndScheduler( void ) { - exit( 0 ); + xPortRunning = pdFALSE; } /*-----------------------------------------------------------*/ From ba1deb54e8fb76b8325c8ca9fe44abd5daed8ddf Mon Sep 17 00:00:00 2001 From: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:16:57 -0800 Subject: [PATCH 048/109] Update PR template to include checkbox for Unit Test related changes (#627) --- .github/pull_request_template.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c3c8607fbde..a39aa2bfa33 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,6 +8,13 @@ Test Steps ----------- +Checklist: +---------- + + +- [ ] I have tested my changes. No regression in existing tests. +- [ ] I have modified and/or added unit-tests to cover the code changes in this Pull Request. + Related Issue ----------- From 5d056010455613d7cfda28f27da26573000773fd Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Thu, 23 Feb 2023 09:37:42 +0530 Subject: [PATCH 049/109] Fix build failure introduced in PR #597 (#629) The PR #597 introduced a new config option configTICK_TYPE_WIDTH_IN_BITS which can be defined to one of the following: * TICK_TYPE_WIDTH_16_BITS - Tick type is 16 bit wide. * TICK_TYPE_WIDTH_32_BITS - Tick type is 32 bit wide. * TICK_TYPE_WIDTH_64_BITS - Tick type is 64 bit wide. Earlier we supported 16 and 32 bit width for tick type which was controlled using the config option configUSE_16_BIT_TICKS. The PR tried to maintain backward compatibility by honoring configUSE_16_BIT_TICKS. The backward compatibility did not work as expected though, as the macro configTICK_TYPE_WIDTH_IN_BITS was used before it was defined. This PR addresses it by ensuring that the macro configTICK_TYPE_WIDTH_IN_BITS is defined before it is used. Testing 1. configUSE_16_BIT_TICKS is defined to 0. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 109e: 4b50 ldr r3, [pc, #320] ; (11e0 ) 10a0: f8d3 4134 ldr.w r4, [r3, #308] ; 0x134 10a4: 3401 adds r4, #1 10a6: f8c3 4134 str.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 32 bit. 2. configUSE_16_BIT_TICKS is defined to 1. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 10e2: 4b53 ldr r3, [pc, #332] ; (1230 ) 10e4: f8b3 4134 ldrh.w r4, [r3, #308] ; 0x134 10e8: b2a4 uxth r4, r4 10ea: 3401 adds r4, #1 10ec: b2a4 uxth r4, r4 10ee: f8a3 4134 strh.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 16 bit. 3. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_16_BITS. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 10e2: 4b53 ldr r3, [pc, #332] ; (1230 ) 10e4: f8b3 4134 ldrh.w r4, [r3, #308] ; 0x134 10e8: b2a4 uxth r4, r4 10ea: 3401 adds r4, #1 10ec: b2a4 uxth r4, r4 10ee: f8a3 4134 strh.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 16 bit. 4. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_32_BITS. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 109e: 4b50 ldr r3, [pc, #320] ; (11e0 ) 10a0: f8d3 4134 ldr.w r4, [r3, #308] ; 0x134 10a4: 3401 adds r4, #1 10a6: f8c3 4134 str.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 32 bit. 5. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_64_BITS. ``` #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. ``` The testing was done for GCC/ARM_CM3 port which does not support 64 bit tick type. 6. Neither configUSE_16_BIT_TICKS nor configTICK_TYPE_WIDTH_IN_BITS defined. ``` #error Missing definition: One of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. ``` 7. Both configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS defined. ``` #error Only one of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. ``` Related issue - https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/628 Signed-off-by: Gaurav Aggarwal --- include/FreeRTOS.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 790a06db058..b7a654961e2 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -63,6 +63,24 @@ /* Application specific configuration options. */ #include "FreeRTOSConfig.h" +#if !defined( configUSE_16_BIT_TICKS ) && !defined( configTICK_TYPE_WIDTH_IN_BITS ) + #error Missing definition: One of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if defined( configUSE_16_BIT_TICKS ) && defined( configTICK_TYPE_WIDTH_IN_BITS ) + #error Only one of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +/* Define configTICK_TYPE_WIDTH_IN_BITS according to the + * value of configUSE_16_BIT_TICKS for backward compatibility. */ +#ifndef configTICK_TYPE_WIDTH_IN_BITS + #if ( configUSE_16_BIT_TICKS == 1 ) + #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_16_BITS + #else + #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS + #endif +#endif + /* Basic FreeRTOS definitions. */ #include "projdefs.h" @@ -160,24 +178,6 @@ #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif -#if !defined( configUSE_16_BIT_TICKS ) && !defined( configTICK_TYPE_WIDTH_IN_BITS ) - #error Missing definition: One of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#if defined( configUSE_16_BIT_TICKS ) && defined( configTICK_TYPE_WIDTH_IN_BITS ) - #error Only one of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -/* Define configTICK_TYPE_WIDTH_IN_BITS according to the - * value of configUSE_16_BIT_TICKS for backward compatibility. */ -#ifndef configTICK_TYPE_WIDTH_IN_BITS - #if ( configUSE_16_BIT_TICKS == 1 ) - #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_16_BITS - #else - #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS - #endif -#endif - #if ( ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_16_BITS ) && \ ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_32_BITS ) && \ ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_64_BITS ) ) From 8cd5451ad50819b3a969b250ac1fd3528ef56ece Mon Sep 17 00:00:00 2001 From: phelter Date: Thu, 23 Feb 2023 10:05:04 -0800 Subject: [PATCH 050/109] Feature/fixing clang gnu compiler warnings (#620) * Adding in ability to support a library for freertos_config and a custom freertos_kernel_port (#558) * Using single name definition for libraries everywhere. (#558) * Supporting backwards compatibility with FREERTOS_CONFIG_FILE_DIRECTORY (#571) * Removing compiler warnings for GNU and Clang. (#571) * Added in documentation on how to consume from a main project. Added default PORT selection for native POSIX and MINGW platforms. * Only adding freertos_config if it exists. Removing auto generation of it from a FREERTOS_CONFIG_FILE_DIRECTORY. * Fixing clang and gnu compiler warnings. * Adding in project information and how to compile for GNU/clang * Fixing compiler issue with unused variable - no need to declare variable. * Adding in compile warnings for linux builds that kernel is okay with using. * Fixing more extra-semi-stmt clang warnings. * Moving definition of hooks into header files if features are enabled. * Fixing formatting with uncrustify. * Fixing merge conflicts with main merge. * Fixing compiler errors due to merge issues and formatting. * Fixing Line feeds. * Adding 'portNORETURN' into portmacros.h. Other Updates based on PR request * Further clean-up of clang and clang-tidy issues. * Removing compiler specific pragmas from common c files. * Fixing missing lexicon entry and uncrustify formatting changes. * Resolving merge issue multiple defnitions of proto for prvIdleTask * Fixing formatting issues that are not covered by uncrustify. Use clang-tidy instead if you want this level of control. * More uncrustify formatting issues. * Fixing extra bracket in #if statement. --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- .github/lexicon.txt | 1 + CMakeLists.txt | 41 ++++++ event_groups.c | 10 +- include/FreeRTOS.h | 4 + include/list.h | 36 ++--- include/queue.h | 6 +- include/stack_macros.h | 4 +- include/task.h | 4 +- include/timers.h | 14 ++ .../portable/GCC/ARM_CM23/portmacro.h | 1 + .../portable/GCC/ARM_CM23_NTZ/portmacro.h | 1 + .../portable/GCC/ARM_CM33/portmacro.h | 1 + .../portable/GCC/ARM_CM33_NTZ/portmacro.h | 1 + .../portable/GCC/ARM_CM55/portmacro.h | 1 + .../portable/GCC/ARM_CM85/portmacro.h | 1 + portable/GCC/ARM_CM0/portmacro.h | 1 + portable/GCC/ARM_CM23/non_secure/portmacro.h | 1 + .../GCC/ARM_CM23_NTZ/non_secure/portmacro.h | 1 + portable/GCC/ARM_CM3/portmacro.h | 1 + portable/GCC/ARM_CM33/non_secure/portmacro.h | 1 + .../GCC/ARM_CM33_NTZ/non_secure/portmacro.h | 1 + portable/GCC/ARM_CM3_MPU/portmacro.h | 1 + portable/GCC/ARM_CM4F/portmacro.h | 1 + portable/GCC/ARM_CM4_MPU/portmacro.h | 1 + portable/GCC/ARM_CM55/non_secure/portmacro.h | 1 + .../GCC/ARM_CM55_NTZ/non_secure/portmacro.h | 1 + portable/GCC/ARM_CM7/r0p1/portmacro.h | 1 + portable/GCC/ARM_CM85/non_secure/portmacro.h | 1 + .../GCC/ARM_CM85_NTZ/non_secure/portmacro.h | 1 + portable/MemMang/heap_4.c | 8 +- portable/ThirdParty/GCC/Posix/port.c | 7 +- portable/ThirdParty/GCC/Posix/portmacro.h | 2 + .../ThirdParty/GCC/RP2040/include/portmacro.h | 1 + .../GCC/Xtensa_ESP32/include/portmacro.h | 2 + queue.c | 64 ++++----- stream_buffer.c | 56 ++++---- tasks.c | 128 +++++++++--------- timers.c | 24 ++-- 38 files changed, 260 insertions(+), 172 deletions(-) diff --git a/.github/lexicon.txt b/.github/lexicon.txt index 765b05c1eb5..47ce4ccde11 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -2458,6 +2458,7 @@ vaninterruptserviceroutine vanisr vanothertask vapplicationcleartimerinterrupt +vapplicationdaemontaskstartuphook vapplicationexceptionregisterdump vapplicationfpusafeirqhandler vapplicationgetidletaskmemory diff --git a/CMakeLists.txt b/CMakeLists.txt index 09bd4bdb84d..3224a97653b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,6 +222,47 @@ elseif((FREERTOS_PORT STREQUAL "A_CUSTOM_PORT") AND (NOT TARGET freertos_kernel_ " freertos_kernel)") endif() +######################################################################## +# Requirements +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) + +######################################################################## +# Overall Compile Options +# Note the compile option strategy is to error on everything and then +# Per library opt-out of things that are warnings/errors. +# This ensures that no matter what strategy for compilation you take, the +# builds will still occur. +# +# Only tested with GNU and Clang. +# Other options are https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html#variable:CMAKE_%3CLANG%3E_COMPILER_ID +# Naming of compilers translation map: +# +# FreeRTOS | CMake +# ------------------- +# CCS | ?TBD? +# GCC | GNU, Clang, *Clang Others? +# IAR | IAR +# Keil | ARMCC +# MSVC | MSVC # Note only for MinGW? +# Renesas | ?TBD? + +add_compile_options( + ### Gnu/Clang C Options + $<$:-fdiagnostics-color=always> + $<$:-fcolor-diagnostics> + + $<$:-Wall> + $<$:-Wextra> + $<$:-Wpedantic> + $<$:-Werror> + $<$:-Weverything> + + # TODO: Add in other Compilers here. +) + + +######################################################################## add_subdirectory(portable) add_library(freertos_kernel STATIC diff --git a/event_groups.c b/event_groups.c index a64c5ead34c..7c86e605a88 100644 --- a/event_groups.c +++ b/event_groups.c @@ -69,14 +69,14 @@ typedef struct EventGroupDef_t { EventBits_t uxEventBits; - List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ + List_t xTasksWaitingForBits; /**< List of tasks waiting for a bit to be set. */ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxEventGroupNumber; #endif #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ + uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ #endif } EventGroup_t; @@ -521,15 +521,15 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) { - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; EventGroup_t const * const pxEventBits = xEventGroup; EventBits_t uxReturn; - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { uxReturn = pxEventBits->uxEventBits; } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return uxReturn; } /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index b7a654961e2..e720480dc64 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -904,6 +904,10 @@ #define portDONT_DISCARD #endif +#ifndef portNORETURN + #define portNORETURN +#endif + #ifndef configUSE_TIME_SLICING #define configUSE_TIME_SLICING 1 #endif diff --git a/include/list.h b/include/list.h index 248212260a1..c86eb7165f8 100644 --- a/include/list.h +++ b/include/list.h @@ -143,20 +143,20 @@ struct xLIST; struct xLIST_ITEM { - listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ - configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in ascending order. */ - struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ - struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ - void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ - struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ - listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; /**< The value being listed. In most cases this is used to sort the list in ascending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /**< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /**< Pointer to the previous ListItem_t in the list. */ + void * pvOwner; /**< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + struct xLIST * configLIST_VOLATILE pxContainer; /**< Pointer to the list in which this list item is placed (if any). */ + listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ }; typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ #if ( configUSE_MINI_LIST_ITEM == 1 ) struct xMINI_LIST_ITEM { - listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ configLIST_VOLATILE TickType_t xItemValue; struct xLIST_ITEM * configLIST_VOLATILE pxNext; struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; @@ -171,11 +171,11 @@ typedef struct xLIST_ITEM ListItem_t; /* For some reason lint */ typedef struct xLIST { - listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listFIRST_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ volatile UBaseType_t uxNumberOfItems; - ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ - MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ - listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + ListItem_t * configLIST_VOLATILE pxIndex; /**< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t xListEnd; /**< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ + listSECOND_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ } List_t; /* @@ -283,7 +283,7 @@ typedef struct xLIST * \ingroup LinkedList */ #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ - { \ + do { \ List_t * const pxConstList = ( pxList ); \ /* Increment the index to the next item and return the item, ensuring */ \ /* we don't return the marker used at the end of the list. */ \ @@ -293,7 +293,7 @@ typedef struct xLIST ( pxConstList )->pxIndex = ( pxConstList )->xListEnd.pxNext; \ } \ ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ - } + } while( 0 ) /* * Version of uxListRemove() that does not return a value. Provided as a slight @@ -312,7 +312,7 @@ typedef struct xLIST * \ingroup LinkedList */ #define listREMOVE_ITEM( pxItemToRemove ) \ - { \ + do { \ /* The list item knows which list it is in. Obtain the list from the list \ * item. */ \ List_t * const pxList = ( pxItemToRemove )->pxContainer; \ @@ -327,7 +327,7 @@ typedef struct xLIST \ ( pxItemToRemove )->pxContainer = NULL; \ ( pxList->uxNumberOfItems )--; \ - } + } while( 0 ) /* * Inline version of vListInsertEnd() to provide slight optimisation for @@ -352,7 +352,7 @@ typedef struct xLIST * \ingroup LinkedList */ #define listINSERT_END( pxList, pxNewListItem ) \ - { \ + do { \ ListItem_t * const pxIndex = ( pxList )->pxIndex; \ \ /* Only effective when configASSERT() is also defined, these tests may catch \ @@ -374,7 +374,7 @@ typedef struct xLIST ( pxNewListItem )->pxContainer = ( pxList ); \ \ ( ( pxList )->uxNumberOfItems )++; \ - } + } while( 0 ) /* * Access function to obtain the owner of the first entry in a list. Lists diff --git a/include/queue.h b/include/queue.h index 02356766abb..f488a2e7641 100644 --- a/include/queue.h +++ b/include/queue.h @@ -1346,9 +1346,9 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * @param pvBuffer Pointer to the buffer into which the received item will * be copied. * - * @param pxTaskWoken A task may be blocked waiting for space to become - * available on the queue. If xQueueReceiveFromISR causes such a task to - * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * @param pxHigherPriorityTaskWoken A task may be blocked waiting for space to + * become available on the queue. If xQueueReceiveFromISR causes such a task + * to unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will * remain unchanged. * * @return pdTRUE if an item was successfully received from the queue, diff --git a/include/stack_macros.h b/include/stack_macros.h index 9b36959baea..7ffc7b34338 100644 --- a/include/stack_macros.h +++ b/include/stack_macros.h @@ -87,7 +87,7 @@ #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) #define taskCHECK_FOR_STACK_OVERFLOW() \ - { \ + do { \ const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ \ @@ -98,7 +98,7 @@ { \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ } \ - } + } while( 0 ) #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ /*-----------------------------------------------------------*/ diff --git a/include/task.h b/include/task.h index f4e72c2c2f5..08c14dd6ff1 100644 --- a/include/task.h +++ b/include/task.h @@ -658,7 +658,7 @@ typedef enum * * @param xTask The handle of the task being updated. * - * @param xRegions A pointer to a MemoryRegion_t structure that contains the + * @param[in] pxRegions A pointer to a MemoryRegion_t structure that contains the * new memory region definitions. * * Example usage: @@ -1667,7 +1667,7 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL #endif -#if ( configUSE_TICK_HOOK > 0 ) +#if ( configUSE_TICK_HOOK != 0 ) /** * task.h diff --git a/include/timers.h b/include/timers.h index d255c3986e7..6a064d62a41 100644 --- a/include/timers.h +++ b/include/timers.h @@ -1361,6 +1361,20 @@ BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, #endif +#if ( configUSE_DAEMON_TASK_STARTUP_HOOK != 0 ) + +/** + * timers.h + * @code{c} + * void vApplicationDaemonTaskStartupHook( void ); + * @endcode + * + * This hook function is called form the timer task once when the task starts running. + */ + void vApplicationDaemonTaskStartupHook( void ); + +#endif + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h index f98b8f277cb..2891a6c7e08 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h index f98b8f277cb..2891a6c7e08 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h index 943c665cc43..53c1020008d 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h index 943c665cc43..53c1020008d 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h index b654748e138..35c160f3407 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h index 830fa2c1379..69d32d7f57a 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM0/portmacro.h b/portable/GCC/ARM_CM0/portmacro.h index 6d60fce4c90..408162d6402 100644 --- a/portable/GCC/ARM_CM0/portmacro.h +++ b/portable/GCC/ARM_CM0/portmacro.h @@ -77,6 +77,7 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) + #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacro.h b/portable/GCC/ARM_CM23/non_secure/portmacro.h index f98b8f277cb..2891a6c7e08 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacro.h @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h index f98b8f277cb..2891a6c7e08 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/GCC/ARM_CM3/portmacro.h b/portable/GCC/ARM_CM3/portmacro.h index c1f7b899217..dd729f13f2c 100644 --- a/portable/GCC/ARM_CM3/portmacro.h +++ b/portable/GCC/ARM_CM3/portmacro.h @@ -77,6 +77,7 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) + #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacro.h b/portable/GCC/ARM_CM33/non_secure/portmacro.h index 943c665cc43..53c1020008d 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacro.h @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h index 943c665cc43..53c1020008d 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM3_MPU/portmacro.h b/portable/GCC/ARM_CM3_MPU/portmacro.h index d3b3af58f4c..25058026973 100644 --- a/portable/GCC/ARM_CM3_MPU/portmacro.h +++ b/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -113,6 +113,7 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) + #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ diff --git a/portable/GCC/ARM_CM4F/portmacro.h b/portable/GCC/ARM_CM4F/portmacro.h index 1ffdc5b8b93..a3b2b46c989 100644 --- a/portable/GCC/ARM_CM4F/portmacro.h +++ b/portable/GCC/ARM_CM4F/portmacro.h @@ -80,6 +80,7 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) + #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ diff --git a/portable/GCC/ARM_CM4_MPU/portmacro.h b/portable/GCC/ARM_CM4_MPU/portmacro.h index f3365d14371..df23d95381f 100644 --- a/portable/GCC/ARM_CM4_MPU/portmacro.h +++ b/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -203,6 +203,7 @@ typedef struct MPU_SETTINGS #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacro.h b/portable/GCC/ARM_CM55/non_secure/portmacro.h index b654748e138..35c160f3407 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacro.h @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h index b654748e138..35c160f3407 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM7/r0p1/portmacro.h b/portable/GCC/ARM_CM7/r0p1/portmacro.h index d65a4c24932..897fef5f468 100644 --- a/portable/GCC/ARM_CM7/r0p1/portmacro.h +++ b/portable/GCC/ARM_CM7/r0p1/portmacro.h @@ -77,6 +77,7 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) + #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacro.h b/portable/GCC/ARM_CM85/non_secure/portmacro.h index 830fa2c1379..69d32d7f57a 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacro.h @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h index 830fa2c1379..69d32d7f57a 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/MemMang/heap_4.c b/portable/MemMang/heap_4.c index f97a1edc12c..8ca7c81e4f3 100644 --- a/portable/MemMang/heap_4.c +++ b/portable/MemMang/heap_4.c @@ -96,8 +96,8 @@ * of their memory address. */ typedef struct A_BLOCK_LINK { - struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */ - size_t xBlockSize; /*<< The size of the free block. */ + struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ + size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ @@ -390,7 +390,7 @@ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ { uxAddress += ( portBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ); - xTotalHeapSize -= uxAddress - ( portPOINTER_SIZE_TYPE ) ucHeap; + xTotalHeapSize -= ( size_t ) ( uxAddress - ( portPOINTER_SIZE_TYPE ) ucHeap ); } pucAlignedHeap = ( uint8_t * ) uxAddress; @@ -402,7 +402,7 @@ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ - uxAddress = ( ( portPOINTER_SIZE_TYPE ) pucAlignedHeap ) + xTotalHeapSize; + uxAddress = ( portPOINTER_SIZE_TYPE ) ( pucAlignedHeap + xTotalHeapSize ); uxAddress -= xHeapStructSize; uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ); pxEnd = ( BlockLink_t * ) uxAddress; diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index bd0842fbf55..82aa27ba889 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -115,6 +115,9 @@ static void prvPortYieldFromISR( void ); /*-----------------------------------------------------------*/ static void prvFatalError( const char * pcCall, + int iErrno ) __attribute__ ((__noreturn__)); + +void prvFatalError( const char * pcCall, int iErrno ) { fprintf( stderr, "%s: %s\n", pcCall, strerror( iErrno ) ); @@ -141,7 +144,7 @@ portSTACK_TYPE * pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, */ thread = ( Thread_t * ) ( pxTopOfStack + 1 ) - 1; pxTopOfStack = ( portSTACK_TYPE * ) thread - 1; - ulStackSize = ( pxTopOfStack + 1 - pxEndOfStack ) * sizeof( *pxTopOfStack ); + ulStackSize = ( size_t )( pxTopOfStack + 1 - pxEndOfStack ) * sizeof( *pxTopOfStack ); thread->pxCode = pxCode; thread->pvParams = pvParameters; @@ -340,7 +343,7 @@ static uint64_t prvGetTimeNs( void ) clock_gettime( CLOCK_MONOTONIC, &t ); - return t.tv_sec * 1000000000ULL + t.tv_nsec; + return ( uint64_t )t.tv_sec * 1000000000ULL + ( uint64_t )t.tv_nsec; } static uint64_t prvStartTimeNs; diff --git a/portable/ThirdParty/GCC/Posix/portmacro.h b/portable/ThirdParty/GCC/Posix/portmacro.h index a5173871359..2061c323642 100644 --- a/portable/ThirdParty/GCC/Posix/portmacro.h +++ b/portable/ThirdParty/GCC/Posix/portmacro.h @@ -68,6 +68,8 @@ typedef unsigned long TickType_t; /*-----------------------------------------------------------*/ /* Architecture specifics. */ +#define portNORETURN __attribute__( ( noreturn ) ) + #define portSTACK_GROWTH ( -1 ) #define portHAS_STACK_OVERFLOW_CHECKING ( 1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) diff --git a/portable/ThirdParty/GCC/RP2040/include/portmacro.h b/portable/ThirdParty/GCC/RP2040/include/portmacro.h index f19e96a0141..1043d2c5587 100644 --- a/portable/ThirdParty/GCC/RP2040/include/portmacro.h +++ b/portable/ThirdParty/GCC/RP2040/include/portmacro.h @@ -78,6 +78,7 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) + #define portNORETURN __attribute__( ( noreturn ) ) /* We have to use PICO_DIVIDER_DISABLE_INTERRUPTS as the source of truth rathern than our config, * as our FreeRTOSConfig.h header cannot be included by ASM code - which is what this affects in the SDK */ #define portUSE_DIVIDER_SAVE_RESTORE !PICO_DIVIDER_DISABLE_INTERRUPTS diff --git a/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h b/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h index e87d560cfcd..575659ac597 100644 --- a/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h +++ b/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h @@ -335,6 +335,8 @@ /*-----------------------------------------------------------*/ /* Architecture specifics. */ + #define portNORETURN __attribute__( ( noreturn ) ) + #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 4 diff --git a/queue.c b/queue.c index 21e398f15ba..ca6bfbc60dc 100644 --- a/queue.c +++ b/queue.c @@ -64,14 +64,14 @@ typedef struct QueuePointers { - int8_t * pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ - int8_t * pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ + int8_t * pcTail; /**< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + int8_t * pcReadFrom; /**< Points to the last place that a queued item was read from when the structure is used as a queue. */ } QueuePointers_t; typedef struct SemaphoreData { - TaskHandle_t xMutexHolder; /*< The handle of the task that holds the mutex. */ - UBaseType_t uxRecursiveCallCount; /*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ + TaskHandle_t xMutexHolder; /**< The handle of the task that holds the mutex. */ + UBaseType_t uxRecursiveCallCount; /**< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ } SemaphoreData_t; /* Semaphores do not actually store or copy data, so have an item size of @@ -95,27 +95,27 @@ typedef struct SemaphoreData */ typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { - int8_t * pcHead; /*< Points to the beginning of the queue storage area. */ - int8_t * pcWriteTo; /*< Points to the free next place in the storage area. */ + int8_t * pcHead; /**< Points to the beginning of the queue storage area. */ + int8_t * pcWriteTo; /**< Points to the free next place in the storage area. */ union { - QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */ - SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */ + QueuePointers_t xQueue; /**< Data required exclusively when this structure is used as a queue. */ + SemaphoreData_t xSemaphore; /**< Data required exclusively when this structure is used as a semaphore. */ } u; - List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ - List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + List_t xTasksWaitingToSend; /**< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + List_t xTasksWaitingToReceive; /**< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ - volatile UBaseType_t uxMessagesWaiting; /*< The number of items currently in the queue. */ - UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ - UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ + volatile UBaseType_t uxMessagesWaiting; /**< The number of items currently in the queue. */ + UBaseType_t uxLength; /**< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + UBaseType_t uxItemSize; /**< The size of each items that the queue will hold. */ - volatile int8_t cRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ - volatile int8_t cTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile int8_t cRxLock; /**< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile int8_t cTxLock; /**< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ + uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ #endif #if ( configUSE_QUEUE_SETS == 1 ) @@ -264,14 +264,14 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, * tasks than the number of tasks in the system. */ #define prvIncrementQueueTxLock( pxQueue, cTxLock ) \ - { \ + do { \ const UBaseType_t uxNumberOfTasks = uxTaskGetNumberOfTasks(); \ if( ( UBaseType_t ) ( cTxLock ) < uxNumberOfTasks ) \ { \ configASSERT( ( cTxLock ) != queueINT8_MAX ); \ ( pxQueue )->cTxLock = ( int8_t ) ( ( cTxLock ) + ( int8_t ) 1 ); \ } \ - } + } while( 0 ) /* * Macro to increment cRxLock member of the queue data structure. It is @@ -279,14 +279,14 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, * tasks than the number of tasks in the system. */ #define prvIncrementQueueRxLock( pxQueue, cRxLock ) \ - { \ + do { \ const UBaseType_t uxNumberOfTasks = uxTaskGetNumberOfTasks(); \ if( ( UBaseType_t ) ( cRxLock ) < uxNumberOfTasks ) \ { \ configASSERT( ( cRxLock ) != queueINT8_MAX ); \ ( pxQueue )->cRxLock = ( int8_t ) ( ( cRxLock ) + ( int8_t ) 1 ); \ } \ - } + } while( 0 ) /*-----------------------------------------------------------*/ BaseType_t xQueueGenericReset( QueueHandle_t xQueue, @@ -1046,7 +1046,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const BaseType_t xCopyPosition ) { BaseType_t xReturn; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); @@ -1074,7 +1074,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, * read, instead return a flag to say whether a context switch is required or * not (i.e. has a task with a higher priority than us been woken by this * post). */ - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) { @@ -1199,7 +1199,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, xReturn = errQUEUE_FULL; } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } @@ -1209,7 +1209,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) { BaseType_t xReturn; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; Queue_t * const pxQueue = xQueue; /* Similar to xQueueGenericSendFromISR() but used with semaphores where the @@ -1245,7 +1245,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; @@ -1365,7 +1365,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, xReturn = errQUEUE_FULL; } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } @@ -1880,7 +1880,7 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) { BaseType_t xReturn; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); @@ -1902,7 +1902,7 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; @@ -1962,7 +1962,7 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } @@ -1972,7 +1972,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) { BaseType_t xReturn; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; int8_t * pcOriginalReadPosition; Queue_t * const pxQueue = xQueue; @@ -1996,7 +1996,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Cannot block in an ISR, so check there is data available. */ if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) @@ -2017,7 +2017,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } diff --git a/stream_buffer.c b/stream_buffer.c index b81f072fb1a..0d0b3350acd 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -70,7 +70,7 @@ ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ } \ } \ - ( void ) xTaskResumeAll(); + ( void ) xTaskResumeAll() #endif /* sbRECEIVE_COMPLETED */ /* If user has provided a per-instance receive complete callback, then @@ -95,10 +95,10 @@ #ifndef sbRECEIVE_COMPLETED_FROM_ISR #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ pxHigherPriorityTaskWoken ) \ - { \ - UBaseType_t uxSavedInterruptStatus; \ + do { \ + portBASE_TYPE xSavedInterruptStatus; \ \ - uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ { \ if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ { \ @@ -109,8 +109,8 @@ ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ } \ } \ - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ - } + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); \ + } while( 0 ) #endif /* sbRECEIVE_COMPLETED_FROM_ISR */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) @@ -147,7 +147,7 @@ ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ } \ } \ - ( void ) xTaskResumeAll(); + ( void ) xTaskResumeAll() #endif /* sbSEND_COMPLETED */ /* If user has provided a per-instance send completed callback, then @@ -155,7 +155,7 @@ */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define prvSEND_COMPLETED( pxStreamBuffer ) \ - { \ + do { \ if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \ { \ pxStreamBuffer->pxSendCompletedCallback( ( pxStreamBuffer ), pdFALSE, NULL ); \ @@ -164,7 +164,7 @@ { \ sbSEND_COMPLETED( ( pxStreamBuffer ) ); \ } \ - } + } while( 0 ) #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #define prvSEND_COMPLETED( pxStreamBuffer ) sbSEND_COMPLETED( ( pxStreamBuffer ) ) #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ @@ -172,10 +172,10 @@ #ifndef sbSEND_COMPLETE_FROM_ISR #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ - { \ - UBaseType_t uxSavedInterruptStatus; \ + do { \ + portBASE_TYPE xSavedInterruptStatus; \ \ - uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ { \ if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ { \ @@ -186,14 +186,14 @@ ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ } \ } \ - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ - } + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); \ + } while( 0 ) #endif /* sbSEND_COMPLETE_FROM_ISR */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ - { \ + do { \ if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \ { \ ( pxStreamBuffer )->pxSendCompletedCallback( ( pxStreamBuffer ), pdTRUE, ( pxHigherPriorityTaskWoken ) ); \ @@ -202,7 +202,7 @@ { \ sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \ } \ - } + } while( 0 ) #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ) @@ -436,13 +436,11 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); #if ( configASSERT_DEFINED == 1 ) - { + /* Sanity check that the size of the structure used to declare a * variable of type StaticStreamBuffer_t equals the size of the real * message buffer structure. */ - volatile size_t xSize = sizeof( StaticStreamBuffer_t ); - configASSERT( xSize == sizeof( StreamBuffer_t ) ); - } /*lint !e529 xSize is referenced is configASSERT() is defined. */ + configASSERT( sizeof( StaticStreamBuffer_t ) == sizeof( StreamBuffer_t ) ); #endif /* configASSERT_DEFINED */ if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) ) @@ -1188,11 +1186,11 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; configASSERT( pxStreamBuffer ); - uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) { @@ -1208,7 +1206,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer xReturn = pdFALSE; } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } @@ -1219,11 +1217,11 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; configASSERT( pxStreamBuffer ); - uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) { @@ -1239,7 +1237,7 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf xReturn = pdFALSE; } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } @@ -1372,9 +1370,9 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, /* The value written just has to be identifiable when looking at the * memory. Don't use 0xA5 as that is the stack fill value and could * result in confusion as to what is actually being observed. */ - const BaseType_t xWriteValue = 0x55; - configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer ); - } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */ + #define STREAM_BUFFER_BUFFER_WRITE_VALUE ( 0x55 ) + configASSERT( memset( pucBuffer, ( int ) STREAM_BUFFER_BUFFER_WRITE_VALUE, xBufferSizeBytes ) == pucBuffer ); + } #endif ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */ diff --git a/tasks.c b/tasks.c index 845af7daa7b..2b73b1b9703 100644 --- a/tasks.c +++ b/tasks.c @@ -134,7 +134,7 @@ /*-----------------------------------------------------------*/ #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - { \ + do { \ UBaseType_t uxTopPriority = uxTopReadyPriority; \ \ /* Find the highest priority queue that contains ready tasks. */ \ @@ -148,7 +148,7 @@ * the same priority get an equal share of the processor time. */ \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ uxTopReadyPriority = uxTopPriority; \ - } /* taskSELECT_HIGHEST_PRIORITY_TASK */ + } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ /*-----------------------------------------------------------*/ @@ -170,14 +170,14 @@ /*-----------------------------------------------------------*/ #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - { \ + do { \ UBaseType_t uxTopPriority; \ \ /* Find the highest priority list that contains ready tasks. */ \ portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ - } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ + } while( 0 ) /*-----------------------------------------------------------*/ @@ -185,12 +185,12 @@ * is being referenced from a ready list. If it is referenced from a delayed * or suspended list then it won't be in a ready list. */ #define taskRESET_READY_PRIORITY( uxPriority ) \ - { \ + do { \ if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ { \ portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ } \ - } + } while( 0 ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ @@ -199,7 +199,7 @@ /* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick * count overflows. */ #define taskSWITCH_DELAYED_LISTS() \ - { \ + do { \ List_t * pxTemp; \ \ /* The delayed tasks list should be empty when the lists are switched. */ \ @@ -210,7 +210,7 @@ pxOverflowDelayedTaskList = pxTemp; \ xNumOfOverflows++; \ prvResetNextTaskUnblockTime(); \ - } + } while( 0 ) /*-----------------------------------------------------------*/ @@ -218,11 +218,13 @@ * Place the task represented by pxTCB into the appropriate ready list for * the task. It is inserted at the end of the list. */ -#define prvAddTaskToReadyList( pxTCB ) \ - traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ - taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ - listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \ - tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +#define prvAddTaskToReadyList( pxTCB ) \ + do { \ + traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \ + tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ); \ + } while( 0 ) /*-----------------------------------------------------------*/ /* @@ -256,33 +258,33 @@ */ 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. */ + 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. */ + 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 - 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. */ - 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. */ + 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. */ + 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 ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) - StackType_t * pxEndOfStack; /*< Points to the highest valid address for the stack. */ + 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. */ + 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. */ + 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 uxBasePriority; /**< The priority last assigned to the task - used by the priority inheritance mechanism. */ UBaseType_t uxMutexesHeld; #endif @@ -295,11 +297,11 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to #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. */ + 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. */ + configTLS_BLOCK_TYPE xTLSBlock; /**< Memory block used as Thread Local Storage (TLS) Block for the task. */ #endif #if ( configUSE_TASK_NOTIFICATIONS == 1 ) @@ -310,7 +312,7 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to /* 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. */ + 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 ) @@ -334,23 +336,23 @@ portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; * xDelayedTaskList1 and xDelayedTaskList2 could be moved to function scope but * doing so breaks some kernel aware debuggers and debuggers that rely on removing * the static qualifier. */ -PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */ -PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ -PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ -PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ -PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ -PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ +PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; /**< Prioritised ready tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList1; /**< Delayed tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList2; /**< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ +PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /**< Points to the delayed task list currently being used. */ +PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /**< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ +PRIVILEGED_DATA static List_t xPendingReadyList; /**< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ #if ( INCLUDE_vTaskDelete == 1 ) - PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ + PRIVILEGED_DATA static List_t xTasksWaitingTermination; /**< Tasks that have been deleted - but their memory not yet freed. */ PRIVILEGED_DATA static volatile UBaseType_t uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; #endif #if ( INCLUDE_vTaskSuspend == 1 ) - PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ + PRIVILEGED_DATA static List_t xSuspendedTaskList; /**< Tasks that are currently suspended. */ #endif @@ -370,7 +372,7 @@ PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ -PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /**< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ /* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. * For tracking the state of remote threads, OpenOCD uses uxTopUsedPriority @@ -391,8 +393,8 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t /* Do not move these variables to function scope as doing so prevents the * code working with debuggers that need to remove the static qualifier. */ - PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ - PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ + PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime = 0UL; /**< Holds the value of a timer/counter the last time a task was switched in. */ + PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime = 0UL; /**< Holds the total amount of execution time as defined by the run time counter clock. */ #endif @@ -430,7 +432,7 @@ static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; * void prvIdleTask( void *pvParameters ); * */ -static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION; +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) portNORETURN PRIVILEGED_FUNCTION; /* * Utility to free all memory allocated by the scheduler to hold a TCB, @@ -1469,7 +1471,8 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) { TCB_t const * pxTCB; - UBaseType_t uxReturn, uxSavedInterruptState; + UBaseType_t uxReturn; + portBASE_TYPE xSavedInterruptState; /* RTOS ports that support interrupt nesting have the concept of a * maximum system call (or maximum API call) interrupt priority. @@ -1489,14 +1492,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR(); { /* If null is passed in here then it is the priority of the calling * task that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); uxReturn = pxTCB->uxPriority; } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptState ); return uxReturn; } @@ -1882,7 +1885,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) { BaseType_t xYieldRequired = pdFALSE; TCB_t * const pxTCB = xTaskToResume; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; configASSERT( xTaskToResume ); @@ -1904,7 +1907,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) { @@ -1945,7 +1948,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) mtCOVERAGE_TEST_MARKER(); } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xYieldRequired; } @@ -2303,7 +2306,7 @@ TickType_t xTaskGetTickCount( void ) TickType_t xTaskGetTickCountFromISR( void ) { TickType_t xReturn; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are @@ -2321,11 +2324,11 @@ TickType_t xTaskGetTickCountFromISR( void ) * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); { xReturn = xTickCount; } - portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } @@ -2535,7 +2538,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) ); #else - *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + *pulTotalRunTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); #endif } } @@ -2956,18 +2959,18 @@ BaseType_t xTaskIncrementTick( void ) { TCB_t * pxTCB; TaskHookFunction_t xReturn; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; /* If xTask is NULL then set the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { xReturn = pxTCB->pxTaskTag; } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } @@ -3026,7 +3029,7 @@ void vTaskSwitchContext( void ) #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); #else - ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + ulTotalRunTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); #endif /* Add the amount of time the task has been running to the @@ -3426,7 +3429,8 @@ void vTaskMissedYield( void ) * void prvIdleTask( void *pvParameters ); * */ -static portTASK_FUNCTION( prvIdleTask, pvParameters ) + +portTASK_FUNCTION( prvIdleTask, pvParameters ) { /* Stop warnings. */ ( void ) pvParameters; @@ -4975,7 +4979,7 @@ TickType_t uxTaskResetEventItemValue( void ) TCB_t * pxTCB; uint8_t ucOriginalNotifyState; BaseType_t xReturn = pdPASS; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; configASSERT( xTaskToNotify ); configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); @@ -5000,7 +5004,7 @@ TickType_t uxTaskResetEventItemValue( void ) pxTCB = xTaskToNotify; - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { if( pulPreviousNotificationValue != NULL ) { @@ -5094,7 +5098,7 @@ TickType_t uxTaskResetEventItemValue( void ) } } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); return xReturn; } @@ -5110,7 +5114,7 @@ TickType_t uxTaskResetEventItemValue( void ) { TCB_t * pxTCB; uint8_t ucOriginalNotifyState; - UBaseType_t uxSavedInterruptStatus; + portBASE_TYPE xSavedInterruptStatus; configASSERT( xTaskToNotify ); configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); @@ -5135,7 +5139,7 @@ TickType_t uxTaskResetEventItemValue( void ) pxTCB = xTaskToNotify; - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; @@ -5185,7 +5189,7 @@ TickType_t uxTaskResetEventItemValue( void ) } } } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); } #endif /* configUSE_TASK_NOTIFICATIONS */ @@ -5269,7 +5273,7 @@ TickType_t uxTaskResetEventItemValue( void ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; - ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE(); + ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); /* For percentage calculations. */ ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; diff --git a/timers.c b/timers.c index 4894a309dc3..06a29279597 100644 --- a/timers.c +++ b/timers.c @@ -74,15 +74,15 @@ /* The definition of the timers themselves. */ typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { - const char * pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ - ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ - TickType_t xTimerPeriodInTicks; /*<< How quickly and often the timer expires. */ - void * pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ - TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ + const char * pcTimerName; /**< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + ListItem_t xTimerListItem; /**< Standard linked list item as used by all kernel features for event management. */ + TickType_t xTimerPeriodInTicks; /**< How quickly and often the timer expires. */ + void * pvTimerID; /**< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + TimerCallbackFunction_t pxCallbackFunction; /**< The function that will be called when the timer expires. */ #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ + UBaseType_t uxTimerNumber; /**< An ID assigned by trace tools such as FreeRTOS+Trace */ #endif - uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ + uint8_t ucStatus; /**< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ } xTIMER; /* The old xTIMER name is maintained above then typedefed to the new Timer_t @@ -96,8 +96,8 @@ * and xCallbackParametersType respectively. */ typedef struct tmrTimerParameters { - TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ - Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ + TickType_t xMessageValue; /**< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + Timer_t * pxTimer; /**< The timer to which the command will be applied. */ } TimerParameter_t; @@ -112,7 +112,7 @@ * that is used to determine which message type is valid. */ typedef struct tmrTimerQueueMessage { - BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ + BaseType_t xMessageID; /**< The command being sent to the timer service task. */ union { TimerParameter_t xTimerParameters; @@ -158,7 +158,7 @@ * task. Other tasks communicate with the timer service task using the * xTimerQueue queue. */ - static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION; + static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) portNORETURN PRIVILEGED_FUNCTION; /* * Called by the timer service task to interpret and process a command it @@ -575,8 +575,6 @@ #if ( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) { - extern void vApplicationDaemonTaskStartupHook( void ); - /* Allow the application writer to execute some code in the context of * this task at the point the task starts executing. This is useful if the * application includes initialisation code that would benefit from From cd87681789dd3317b1291a0b32800c64b8fd850f Mon Sep 17 00:00:00 2001 From: jacky309 Date: Mon, 27 Feb 2023 19:21:11 +0100 Subject: [PATCH 051/109] POSIX port fixes (#626) * Fix types in POSIX port Use TaskFunction_t and StackType_t as other ports do. * Fix portTICK_RATE_MICROSECONDS in POSIX port --------- Co-authored-by: Jacques GUILLOU Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- portable/ThirdParty/GCC/Posix/port.c | 8 ++++---- portable/ThirdParty/GCC/Posix/portmacro.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 82aa27ba889..12076b9898d 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -73,7 +73,7 @@ typedef struct THREAD { pthread_t pthread; - pdTASK_CODE pxCode; + TaskFunction_t pxCode; void * pvParams; BaseType_t xDying; struct event * ev; @@ -127,9 +127,9 @@ void prvFatalError( const char * pcCall, /* * See header file for description. */ -portSTACK_TYPE * pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, - portSTACK_TYPE * pxEndOfStack, - pdTASK_CODE pxCode, +portSTACK_TYPE * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, void * pvParameters ) { Thread_t * thread; diff --git a/portable/ThirdParty/GCC/Posix/portmacro.h b/portable/ThirdParty/GCC/Posix/portmacro.h index 2061c323642..68655861202 100644 --- a/portable/ThirdParty/GCC/Posix/portmacro.h +++ b/portable/ThirdParty/GCC/Posix/portmacro.h @@ -73,7 +73,7 @@ typedef unsigned long TickType_t; #define portSTACK_GROWTH ( -1 ) #define portHAS_STACK_OVERFLOW_CHECKING ( 1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portTICK_RATE_MICROSECONDS ( ( portTickType ) 1000000 / configTICK_RATE_HZ ) +#define portTICK_RATE_MICROSECONDS ( ( TickType_t ) 1000000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ From 5fdbb7fd2b6102bddfeb665f2d276c24a86c82df Mon Sep 17 00:00:00 2001 From: Devaraj Ranganna Date: Tue, 28 Feb 2023 07:28:59 +0000 Subject: [PATCH 052/109] Cortex-M35P: Add Cortex-M35P port (#631) * Cortex-M35P: Add Cortex-M35P port The Cortex-M35P support added to kernel. The port hasn't been validated yet with TF-M. Hence TF-M support is not included in this port. Signed-off-by: Devaraj Ranganna * Add portNORETURN to the newly added portmacro.h Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Devaraj Ranganna Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> --- CMakeLists.txt | 6 + portable/ARMv8M/copy_files.py | 30 +- .../portable/GCC/ARM_CM23/portmacro.h | 2 +- .../portable/GCC/ARM_CM23_NTZ/portmacro.h | 2 +- .../portable/GCC/ARM_CM33/portmacro.h | 2 +- .../portable/GCC/ARM_CM33_NTZ/portmacro.h | 2 +- .../portable/GCC/ARM_CM35P/portmacro.h | 67 + .../portable/GCC/ARM_CM55/portmacro.h | 2 +- .../portable/GCC/ARM_CM85/portmacro.h | 2 +- .../portable/IAR/ARM_CM35P/portmacro.h | 78 + portable/CMakeLists.txt | 36 + portable/GCC/ARM_CM23/non_secure/portasm.c | 2 +- portable/GCC/ARM_CM23/non_secure/portmacro.h | 2 +- .../GCC/ARM_CM23_NTZ/non_secure/portmacro.h | 2 +- portable/GCC/ARM_CM33/non_secure/portmacro.h | 2 +- .../GCC/ARM_CM33_NTZ/non_secure/portmacro.h | 2 +- portable/GCC/ARM_CM35P/non_secure/port.c | 1261 +++++++++++++++++ portable/GCC/ARM_CM35P/non_secure/portasm.c | 470 ++++++ portable/GCC/ARM_CM35P/non_secure/portasm.h | 114 ++ portable/GCC/ARM_CM35P/non_secure/portmacro.h | 67 + .../ARM_CM35P/non_secure/portmacrocommon.h | 313 ++++ .../GCC/ARM_CM35P/secure/secure_context.c | 351 +++++ .../GCC/ARM_CM35P/secure/secure_context.h | 135 ++ .../ARM_CM35P/secure/secure_context_port.c | 97 ++ portable/GCC/ARM_CM35P/secure/secure_heap.c | 454 ++++++ portable/GCC/ARM_CM35P/secure/secure_heap.h | 66 + portable/GCC/ARM_CM35P/secure/secure_init.c | 106 ++ portable/GCC/ARM_CM35P/secure/secure_init.h | 54 + .../GCC/ARM_CM35P/secure/secure_port_macros.h | 140 ++ portable/GCC/ARM_CM35P_NTZ/non_secure/port.c | 1261 +++++++++++++++++ .../GCC/ARM_CM35P_NTZ/non_secure/portasm.c | 365 +++++ .../GCC/ARM_CM35P_NTZ/non_secure/portasm.h | 114 ++ .../GCC/ARM_CM35P_NTZ/non_secure/portmacro.h | 67 + .../non_secure/portmacrocommon.h | 313 ++++ portable/GCC/ARM_CM55/non_secure/portmacro.h | 2 +- .../GCC/ARM_CM55_NTZ/non_secure/portmacro.h | 2 +- portable/GCC/ARM_CM85/non_secure/portmacro.h | 2 +- .../GCC/ARM_CM85_NTZ/non_secure/portmacro.h | 2 +- portable/IAR/ARM_CM35P/non_secure/port.c | 1261 +++++++++++++++++ portable/IAR/ARM_CM35P/non_secure/portasm.h | 114 ++ portable/IAR/ARM_CM35P/non_secure/portasm.s | 353 +++++ portable/IAR/ARM_CM35P/non_secure/portmacro.h | 78 + .../ARM_CM35P/non_secure/portmacrocommon.h | 313 ++++ .../IAR/ARM_CM35P/secure/secure_context.c | 351 +++++ .../IAR/ARM_CM35P/secure/secure_context.h | 135 ++ .../secure/secure_context_port_asm.s | 86 ++ portable/IAR/ARM_CM35P/secure/secure_heap.c | 454 ++++++ portable/IAR/ARM_CM35P/secure/secure_heap.h | 66 + portable/IAR/ARM_CM35P/secure/secure_init.c | 106 ++ portable/IAR/ARM_CM35P/secure/secure_init.h | 54 + .../IAR/ARM_CM35P/secure/secure_port_macros.h | 140 ++ portable/IAR/ARM_CM35P_NTZ/non_secure/port.c | 1261 +++++++++++++++++ .../IAR/ARM_CM35P_NTZ/non_secure/portasm.h | 114 ++ .../IAR/ARM_CM35P_NTZ/non_secure/portasm.s | 262 ++++ .../IAR/ARM_CM35P_NTZ/non_secure/portmacro.h | 78 + .../non_secure/portmacrocommon.h | 313 ++++ 56 files changed, 11509 insertions(+), 25 deletions(-) create mode 100644 portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h create mode 100644 portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h create mode 100644 portable/GCC/ARM_CM35P/non_secure/port.c create mode 100644 portable/GCC/ARM_CM35P/non_secure/portasm.c create mode 100644 portable/GCC/ARM_CM35P/non_secure/portasm.h create mode 100644 portable/GCC/ARM_CM35P/non_secure/portmacro.h create mode 100644 portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h create mode 100644 portable/GCC/ARM_CM35P/secure/secure_context.c create mode 100644 portable/GCC/ARM_CM35P/secure/secure_context.h create mode 100644 portable/GCC/ARM_CM35P/secure/secure_context_port.c create mode 100644 portable/GCC/ARM_CM35P/secure/secure_heap.c create mode 100644 portable/GCC/ARM_CM35P/secure/secure_heap.h create mode 100644 portable/GCC/ARM_CM35P/secure/secure_init.c create mode 100644 portable/GCC/ARM_CM35P/secure/secure_init.h create mode 100644 portable/GCC/ARM_CM35P/secure/secure_port_macros.h create mode 100644 portable/GCC/ARM_CM35P_NTZ/non_secure/port.c create mode 100644 portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c create mode 100644 portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h create mode 100644 portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h create mode 100644 portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h create mode 100644 portable/IAR/ARM_CM35P/non_secure/port.c create mode 100644 portable/IAR/ARM_CM35P/non_secure/portasm.h create mode 100644 portable/IAR/ARM_CM35P/non_secure/portasm.s create mode 100644 portable/IAR/ARM_CM35P/non_secure/portmacro.h create mode 100644 portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h create mode 100644 portable/IAR/ARM_CM35P/secure/secure_context.c create mode 100644 portable/IAR/ARM_CM35P/secure/secure_context.h create mode 100644 portable/IAR/ARM_CM35P/secure/secure_context_port_asm.s create mode 100644 portable/IAR/ARM_CM35P/secure/secure_heap.c create mode 100644 portable/IAR/ARM_CM35P/secure/secure_heap.h create mode 100644 portable/IAR/ARM_CM35P/secure/secure_init.c create mode 100644 portable/IAR/ARM_CM35P/secure/secure_init.h create mode 100644 portable/IAR/ARM_CM35P/secure/secure_port_macros.h create mode 100644 portable/IAR/ARM_CM35P_NTZ/non_secure/port.c create mode 100644 portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h create mode 100644 portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s create mode 100644 portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h create mode 100644 portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3224a97653b..aead9a0d841 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,9 @@ if(NOT FREERTOS_PORT) " GCC_ARM_CM33_SECURE - Compiler: GCC Target: ARM Cortex-M33 secure\n" " GCC_ARM_CM33_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M33 non-trustzone non-secure\n" " GCC_ARM_CM33_TFM - Compiler: GCC Target: ARM Cortex-M33 non-secure for TF-M\n" + " GCC_ARM_CM35P_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-secure\n" + " GCC_ARM_CM35P_SECURE - Compiler: GCC Target: ARM Cortex-M35P secure\n" + " GCC_ARM_CM35P_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-trustzone non-secure\n" " GCC_ARM_CM55_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-secure\n" " GCC_ARM_CM55_SECURE - Compiler: GCC Target: ARM Cortex-M55 secure\n" " GCC_ARM_CM55_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-trustzone non-secure\n" @@ -134,6 +137,9 @@ if(NOT FREERTOS_PORT) " IAR_ARM_CM33_NONSECURE - Compiler: IAR Target: ARM Cortex-M33 non-secure\n" " IAR_ARM_CM33_SECURE - Compiler: IAR Target: ARM Cortex-M33 secure\n" " IAR_ARM_CM33_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M33 non-trustzone non-secure\n" + " IAR_ARM_CM35P_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-secure\n" + " IAR_ARM_CM35P_SECURE - Compiler: IAR Target: ARM Cortex-M35P secure\n" + " IAR_ARM_CM35P_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-trustzone non-secure\n" " IAR_ARM_CM55_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-secure\n" " IAR_ARM_CM55_SECURE - Compiler: IAR Target: ARM Cortex-M55 secure\n" " IAR_ARM_CM55_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-trustzone non-secure\n" diff --git a/portable/ARMv8M/copy_files.py b/portable/ARMv8M/copy_files.py index ebe8009703c..d064969809c 100644 --- a/portable/ARMv8M/copy_files.py +++ b/portable/ARMv8M/copy_files.py @@ -33,8 +33,8 @@ _FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_) _COMPILERS_ = ['GCC', 'IAR'] -_ARCH_NS_ = ['ARM_CM85', 'ARM_CM85_NTZ', 'ARM_CM55', 'ARM_CM55_NTZ', 'ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ'] -_ARCH_S_ = ['ARM_CM85', 'ARM_CM55', 'ARM_CM33', 'ARM_CM23'] +_ARCH_NS_ = ['ARM_CM85', 'ARM_CM85_NTZ', 'ARM_CM55', 'ARM_CM55_NTZ', 'ARM_CM35P', 'ARM_CM35P_NTZ', 'ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ'] +_ARCH_S_ = ['ARM_CM85', 'ARM_CM55', 'ARM_CM35P', 'ARM_CM33', 'ARM_CM23'] # Files to be compiled in the Secure Project _SECURE_COMMON_FILE_PATHS_ = [ @@ -46,16 +46,18 @@ _SECURE_PORTABLE_FILE_PATHS_ = { 'GCC':{ - 'ARM_CM23':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM23')], - 'ARM_CM33':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')], - 'ARM_CM55':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')], - 'ARM_CM85':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')] + 'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM23')], + 'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')], + 'ARM_CM35P':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')], + 'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')], + 'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')] }, 'IAR':{ - 'ARM_CM23':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM23')], - 'ARM_CM33':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')], - 'ARM_CM55':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')], - 'ARM_CM85':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')] + 'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM23')], + 'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')], + 'ARM_CM35P':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')], + 'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')], + 'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')] } } @@ -70,6 +72,10 @@ 'ARM_CM23_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM23_NTZ')], 'ARM_CM33' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33')], 'ARM_CM33_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ')], + 'ARM_CM35P' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'), + os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM35P', 'portmacro.h')], + 'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'), + os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM35P', 'portmacro.h')], 'ARM_CM55' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')], 'ARM_CM55_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'), @@ -84,6 +90,10 @@ 'ARM_CM23_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM23_NTZ')], 'ARM_CM33' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33')], 'ARM_CM33_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ')], + 'ARM_CM35P' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'), + os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM35P', 'portmacro.h')], + 'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'), + os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM35P', 'portmacro.h')], 'ARM_CM55' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')], 'ARM_CM55_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'), diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h index 2891a6c7e08..c6dad99857c 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h @@ -50,7 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h index 2891a6c7e08..c6dad99857c 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h @@ -50,7 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h index 53c1020008d..4fe8c59147a 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h @@ -50,7 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h index 53c1020008d..4fe8c59147a 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h @@ -50,7 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h new file mode 100644 index 00000000000..33bfb283461 --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h @@ -0,0 +1,67 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "portmacrocommon.h" + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + +/** + * Architecture specifics. + */ +#define portARCH_NAME "Cortex-M35P" +#define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ +#define portDISABLE_INTERRUPTS() ulSetInterruptMask() +#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) +/*-----------------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif /* PORTMACRO_H */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h index 35c160f3407..adb47d8420f 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h @@ -55,7 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h index 69d32d7f57a..fec6923394c 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h @@ -55,7 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h new file mode 100644 index 00000000000..a0efc1f9dcf --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h @@ -0,0 +1,78 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "portmacrocommon.h" + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + +/** + * Architecture specifics. + */ +#define portARCH_NAME "Cortex-M35P" +#define portDONT_DISCARD __root +/*-----------------------------------------------------------*/ + +#if( configTOTAL_MPU_REGIONS == 16 ) + #error 16 MPU regions are not yet supported for this port. +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ +#define portDISABLE_INTERRUPTS() ulSetInterruptMask() +#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) +/*-----------------------------------------------------------*/ + +/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in + * the source code because to do so would cause other compilers to generate + * warnings. */ +#pragma diag_suppress=Be006 +#pragma diag_suppress=Pa082 +/*-----------------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif /* PORTMACRO_H */ diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt index ae9de9cfe1b..2824df05dc0 100644 --- a/portable/CMakeLists.txt +++ b/portable/CMakeLists.txt @@ -123,6 +123,20 @@ add_library(freertos_kernel_port STATIC GCC/ARM_CM33_NTZ/non_secure/portasm.c ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> + $<$: + GCC/ARM_CM35P/non_secure/port.c + GCC/ARM_CM35P/non_secure/portasm.c> + + $<$: + GCC/ARM_CM35P/secure/secure_context_port.c + GCC/ARM_CM35P/secure/secure_context.c + GCC/ARM_CM35P/secure/secure_heap.c + GCC/ARM_CM35P/secure/secure_init.c> + + $<$: + GCC/ARM_CM35P_NTZ/non_secure/port.c + GCC/ARM_CM35P_NTZ/non_secure/portasm.c> + # ARMv8.1-M ports for GCC $<$: GCC/ARM_CM55/non_secure/port.c @@ -397,6 +411,20 @@ add_library(freertos_kernel_port STATIC IAR/ARM_CM33_NTZ/non_secure/port.c IAR/ARM_CM33_NTZ/non_secure/portasm.s> + $<$: + IAR/ARM_CM35P/non_secure/port.c + IAR/ARM_CM35P/non_secure/portasm.s> + + $<$: + IAR/ARM_CM35P/secure/secure_context_port_asm.s + IAR/ARM_CM35P/secure/secure_context.c + IAR/ARM_CM35P/secure/secure_heap.c + IAR/ARM_CM35P/secure/secure_init.c> + + $<$: + IAR/ARM_CM35P_NTZ/non_secure/port.c + IAR/ARM_CM35P_NTZ/non_secure/portasm.s> + # ARMv8.1-M ports for IAR EWARM $<$: IAR/ARM_CM55/non_secure/port.c @@ -738,6 +766,10 @@ target_include_directories(freertos_kernel_port PUBLIC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM33_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM33_NTZ/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM35P/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM35P/secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM35P_NTZ/non_secure> + # ARMv8.1-M ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55/secure> @@ -860,6 +892,10 @@ target_include_directories(freertos_kernel_port PUBLIC $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33_NTZ/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM35P/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM35P/secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM35P_NTZ/non_secure> + # ARMv8.1-M ports for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55/secure> diff --git a/portable/GCC/ARM_CM23/non_secure/portasm.c b/portable/GCC/ARM_CM23/non_secure/portasm.c index 5435439c5fe..44f159af1fa 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23/non_secure/portasm.c @@ -367,7 +367,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r3] \n"/* Restore the task's xSecureContext. */ " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacro.h b/portable/GCC/ARM_CM23/non_secure/portmacro.h index 2891a6c7e08..c6dad99857c 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacro.h @@ -50,7 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h index 2891a6c7e08..c6dad99857c 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h @@ -50,7 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/GCC/ARM_CM33/non_secure/portmacro.h b/portable/GCC/ARM_CM33/non_secure/portmacro.h index 53c1020008d..4fe8c59147a 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacro.h @@ -50,7 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h index 53c1020008d..4fe8c59147a 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h @@ -50,7 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c new file mode 100644 index 00000000000..9976daee49a --- /dev/null +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -0,0 +1,1261 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/* Portasm includes. */ +#include "portasm.h" + +#if ( configENABLE_TRUSTZONE == 1 ) + /* Secure components includes. */ + #include "secure_context.h" + #include "secure_init.h" +#endif /* configENABLE_TRUSTZONE */ + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/** + * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only + * i.e. the processor boots as secure and never jumps to the non-secure side. + * The Trust Zone support in the port must be disabled in order to run FreeRTOS + * on the secure side. The following are the valid configuration seetings: + * + * 1. Run FreeRTOS on the Secure Side: + * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 + * + * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 + * + * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 + */ +#if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) + #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the NVIC. + */ +#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) +#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) +#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the SCB. + */ +#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) +#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the FPU. + */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR_CP10_VALUE ( 3UL ) +#define portCPACR_CP11_VALUE portCPACR_CP10_VALUE +#define portCPACR_CP10_POS ( 20UL ) +#define portCPACR_CP11_POS ( 22UL ) + +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR_ASPEN_POS ( 31UL ) +#define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) +#define portFPCCR_LSPEN_POS ( 30UL ) +#define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the MPU. + */ +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) + +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) + +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) + +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) + +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) + +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) + +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ + +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) + +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) + +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) + +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) + +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) + +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) + +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) + +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) + +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) + +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) + +/* Enable privileged access to unmapped region. */ +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) + +/* Enable MPU. */ +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) + +/* Expected value of the portMPU_TYPE register. */ +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief The maximum 24-bit number. + * + * It is needed because the systick is a 24-bit counter. + */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/** + * @brief A fiddle factor to estimate the number of SysTick counts that would + * have occurred while the SysTick counter is stopped during tickless idle + * calculations. + */ +#define portMISSED_COUNTS_FACTOR ( 94UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to set up the initial stack. + */ +#define portINITIAL_XPSR ( 0x01000000 ) + +#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ + #define portINITIAL_EXC_RETURN ( 0xfffffffd ) +#else + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ + #define portINITIAL_EXC_RETURN ( 0xffffffbc ) +#endif /* configRUN_FREERTOS_SECURE_ONLY */ + +/** + * @brief CONTROL register privileged bit mask. + * + * Bit[0] in CONTROL register tells the privilege: + * Bit[0] = 0 ==> The task is privileged. + * Bit[0] = 1 ==> The task is not privileged. + */ +#define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) + +/** + * @brief Initial CONTROL register values. + */ +#define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) +#define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) + +/** + * @brief Let the user override the default SysTick clock rate. If defined by the + * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the + * configuration register. + */ +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) +#else + /* Select the option to clock SysTick not at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) +#endif + +/** + * @brief Let the user override the pre-loading of the initial LR with the + * address of prvTaskExitError() in case it messes up unwinding of the stack + * in the debugger. + */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/** + * @brief If portPRELOAD_REGISTERS then registers will be given an initial value + * when a task is created. This helps in debugging at the cost of code size. + */ +#define portPRELOAD_REGISTERS 1 + +/** + * @brief A task is created without a secure context, and must call + * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes + * any secure calls. + */ +#define portNO_SECURE_CONTEXT 0 +/*-----------------------------------------------------------*/ + +/** + * @brief Used to catch tasks that attempt to return from their implementing + * function. + */ +static void prvTaskExitError( void ); + +#if ( configENABLE_MPU == 1 ) + +/** + * @brief Setup the Memory Protection Unit (MPU). + */ + static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_FPU == 1 ) + +/** + * @brief Setup the Floating Point Unit (FPU). + */ + static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_FPU */ + +/** + * @brief Setup the timer to generate the tick interrupts. + * + * The implementation in this file is weak to allow application writers to + * change the timer used to generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether the current execution context is interrupt. + * + * @return pdTRUE if the current execution context is interrupt, pdFALSE + * otherwise. + */ +BaseType_t xPortIsInsideInterrupt( void ); + +/** + * @brief Yield the processor. + */ +void vPortYield( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Enter critical section. + */ +void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Exit from critical section. + */ +void vPortExitCritical( void ) PRIVILEGED_FUNCTION; + +/** + * @brief SysTick handler. + */ +void SysTick_Handler( void ) PRIVILEGED_FUNCTION; + +/** + * @brief C part of SVC handler. + */ +portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +/** + * @brief Each task maintains its own interrupt status in the critical nesting + * variable. + */ +PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; + +#if ( configENABLE_TRUSTZONE == 1 ) + +/** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ + PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; +#endif /* configENABLE_TRUSTZONE */ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + +/** + * @brief The number of SysTick increments that make up one tick period. + */ + PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; + +/** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ + PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; + +/** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ + PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + * method as that will mask interrupts that should exit sleep mode. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* If a context switch is pending or a task is waiting for the scheduler + * to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Re-enable interrupts - see comments above the cpsid instruction + * above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + else + { + /* Stop the SysTick momentarily. The time the SysTick is stopped for + * is accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Use the SysTick current-value register to determine the number of + * SysTick decrements remaining until the next tick interrupt. If the + * current-value register is zero, then there are actually + * ulTimerCountsForOneTick decrements remaining, not zero, because the + * SysTick requests the interrupt when decrementing from 1 to 0. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulTimerCountsForOneTick; + } + + /* Calculate the reload value required to wait xExpectedIdleTime + * tick periods. -1 is used because this code normally executes part + * way through the first tick period. But if the SysTick IRQ is now + * pending, then clear the IRQ, suppressing the first tick, and correct + * the reload value to reflect that the second tick period is already + * underway. The expected idle time is always at least two ticks. */ + ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + + if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) + { + portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; + ulReloadValue -= ulTimerCountsForOneTick; + } + + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + * zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + * set its parameter to 0 to indicate that its implementation contains + * its own wait for interrupt or wait for event instruction, and so wfi + * should not be executed again. However, the original expected idle + * time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + + if( xModifiableIdleTime > 0 ) + { + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "wfi" ); + __asm volatile ( "isb" ); + } + + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Re-enable interrupts to allow the interrupt that brought the MCU + * out of sleep mode to execute immediately. See comments above + * the cpsid instruction above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable interrupts again because the clock is about to be stopped + * and interrupts that execute while the clock is stopped will increase + * any slippage between the time maintained by the RTOS and calendar + * time. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable the SysTick clock without reading the + * portNVIC_SYSTICK_CTRL_REG register to ensure the + * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, + * the time the SysTick is stopped for is accounted for as best it can + * be, but using the tickless mode will inevitably result in some tiny + * drift of the time maintained by the kernel with respect to calendar + * time*/ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Determine whether the SysTick has already counted to zero. */ + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt ended the sleep (or is now pending), and + * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG + * with whatever remains of the new tick period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + * underflowed because the post sleep hook did something + * that took too long or because the SysTick current-value register + * is zero. */ + if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* As the pending tick will be processed as soon as this + * function exits, the tick value maintained by the tick is stepped + * forward by one less than the time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. */ + + /* Use the SysTick current-value register to determine the + * number of SysTick decrements remaining until the expected idle + * time would have ended. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) + { + /* If the SysTick is not using the core clock, the current- + * value register might still be zero here. In that case, the + * SysTick didn't load from the reload register, and there are + * ulReloadValue decrements remaining in the expected idle + * time, not zero. */ + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulReloadValue; + } + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Work out how long the sleep lasted rounded to complete tick + * periods (not the ulReload value which accounted for part + * ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; + + /* How many complete tick periods passed while the processor + * was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + * period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, + * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If + * the SysTick is not using the core clock, temporarily configure it to + * use the core clock. This configuration forces the SysTick to load + * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next + * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready + * to receive the standard value immediately. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) + { + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + #else + { + /* The temporary usage of the core clock has served its purpose, + * as described above. Resume usage of the other clock. */ + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; + + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + /* The partial tick period already ended. Be sure the SysTick + * counts it only once. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; + } + + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Step the tick to account for any tick periods that elapsed. */ + vTaskStepTick( ulCompleteTickPeriods ); + + /* Exit with interrupts enabled. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + } +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if ( configUSE_TICKLESS_IDLE == 1 ) + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Stop and reset the SysTick. */ + portNVIC_SYSTICK_CTRL_REG = 0UL; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + volatile uint32_t ulDummy = 0UL; + + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). Artificially force an assert() + * to be triggered if configASSERT() is defined, then stop here so + * application writers can catch the error. */ + configASSERT( ulCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + + while( ulDummy == 0 ) + { + /* This file calls prvTaskExitError() after the scheduler has been + * started to remove a compiler warning about the function being + * defined but never called. ulDummy is used purely to quieten other + * warnings about code appearing after this function is called - making + * ulDummy volatile makes the compiler think the function could return + * and therefore not output an 'unreachable code' warning for code that + * appears after it. */ + } +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + extern uint32_t * __unprivileged_flash_start__; + extern uint32_t * __unprivileged_flash_end__; + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + #else /* if defined( __ARMCC_VERSION ) */ + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + extern uint32_t __unprivileged_flash_start__[]; + extern uint32_t __unprivileged_flash_end__[]; + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + + /* The only permitted number of regions are 8 or 16. */ + configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); + + /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ + configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + + /* Check that the MPU is present. */ + if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) + { + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; + + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); + } + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* Enable non-secure access to the FPU. */ + SecureInit_EnableNSFPUAccess(); + } + #endif /* configENABLE_TRUSTZONE */ + + /* CP10 = 11 ==> Full access to FPU i.e. both privileged and + * unprivileged code should be able to access FPU. CP11 should be + * programmed to the same value as CP10. */ + *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | + ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) + ); + + /* ASPEN = 1 ==> Hardware should automatically preserve floating point + * context on exception entry and restore on exception return. + * LSPEN = 1 ==> Enable lazy context save of FP state. */ + *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); + } +#endif /* configENABLE_FPU */ +/*-----------------------------------------------------------*/ + +void vPortYield( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + portDISABLE_INTERRUPTS(); + ulCriticalNesting++; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + configASSERT( ulCriticalNesting ); + ulCriticalNesting--; + + if( ulCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulPreviousMask; + + ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ +{ + #if ( configENABLE_MPU == 1 ) + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + #endif /* configENABLE_MPU */ + + uint32_t ulPC; + + #if ( configENABLE_TRUSTZONE == 1 ) + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; + #if ( configENABLE_MPU == 1 ) + uint32_t ulControl, ulIsTaskPrivileged; + #endif /* configENABLE_MPU */ + #endif /* configENABLE_TRUSTZONE */ + uint8_t ucSVCNumber; + + /* Register are stored on the stack in the following order - R0, R1, R2, R3, + * R12, LR, PC, xPSR. */ + ulPC = pulCallerStackAddress[ 6 ]; + ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; + + switch( ucSVCNumber ) + { + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: + + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; + + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ + + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; + + case portSVC_FREE_SECURE_CONTEXT: + + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; + + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ + + case portSVC_START_SCHEDULER: + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* De-prioritize the non-secure exceptions so that the + * non-secure pendSV runs at the lowest priority. */ + SecureInit_DePrioritizeNSExceptions(); + + /* Initialize the secure context management system. */ + SecureContext_Init(); + } + #endif /* configENABLE_TRUSTZONE */ + + #if ( configENABLE_FPU == 1 ) + { + /* Setup the Floating Point Unit (FPU). */ + prvSetupFPU(); + } + #endif /* configENABLE_FPU */ + + /* Setup the context of the first task so that the first task starts + * executing. */ + vRestoreContextOfFirstTask(); + break; + + #if ( configENABLE_MPU == 1 ) + case portSVC_RAISE_PRIVILEGE: + + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* configENABLE_MPU */ + + default: + /* Incorrect SVC call. */ + configASSERT( pdFALSE ); + } +} +/*-----------------------------------------------------------*/ +/* *INDENT-OFF* */ +#if ( configENABLE_MPU == 1 ) + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ +#else + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +#endif /* configENABLE_MPU */ +/* *INDENT-ON* */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; + + #if ( configENABLE_MPU == 1 ) + { + pxTopOfStack--; + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + } + #endif /* configENABLE_MPU */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + + #if ( configENABLE_TRUSTZONE == 1 ) + { + pxTopOfStack--; + *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ + } + #endif /* configENABLE_TRUSTZONE */ + } + #else /* portPRELOAD_REGISTERS */ + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ + + #if ( configENABLE_MPU == 1 ) + { + pxTopOfStack--; + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + } + #endif /* configENABLE_MPU */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + + #if ( configENABLE_TRUSTZONE == 1 ) + { + pxTopOfStack--; + *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ + } + #endif /* configENABLE_TRUSTZONE */ + } + #endif /* portPRELOAD_REGISTERS */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ + portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; + portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; + + #if ( configENABLE_MPU == 1 ) + { + /* Setup the Memory Protection Unit (MPU). */ + prvSetupMPU(); + } + #endif /* configENABLE_MPU */ + + /* Start the timer that generates the tick ISR. Interrupts are disabled + * here already. */ + vPortSetupTimerInterrupt(); + + /* Initialize the critical nesting count ready for the first task. */ + ulCriticalNesting = 0; + + /* Start the first task. */ + vStartFirstTask(); + + /* Should never get here as the tasks will now be executing. Call the task + * exit error function to prevent compiler warnings about a static function + * not being called in the case that the application writer overrides this + * functionality by defining configTASK_RETURN_ADDRESS. Call + * vTaskSwitchContext() so link time optimization does not remove the + * symbol. */ + vTaskSwitchContext(); + prvTaskExitError(); + + /* Should not get here. */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( ulCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) + { + uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; + int32_t lIndex = 0; + + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + + /* Setup MAIR0. */ + xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + + /* This function is called automatically when the task is created - in + * which case the stack region parameters will be valid. At all other + * times the stack parameters will not be valid and it is assumed that + * the stack region has already been configured. */ + if( ulStackDepth > 0 ) + { + ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + + /* If the stack is within the privileged SRAM, do not protect it + * using a separate MPU region. This is needed because privileged + * SRAM is already protected using an MPU region and ARMv8-M does + * not allow overlapping MPU regions. */ + if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && + ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) + { + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; + xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; + } + else + { + /* Define the region that allows access to the stack. */ + ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; + ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; + + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + + xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + } + } + + /* User supplied configurable regions. */ + for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) + { + /* If xRegions is NULL i.e. the task has not specified any MPU + * region, the else part ensures that all the configurable MPU + * regions are invalidated. */ + if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) + { + /* Translate the generic region definition contained in xRegions + * into the ARMv8 specific MPU settings that are then stored in + * xMPUSettings. */ + ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; + ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; + ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; + + /* Start address. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | + ( portMPU_REGION_NON_SHAREABLE ); + + /* RO/RW. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); + } + else + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); + } + + /* XN. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); + } + + /* End Address. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Normal memory/ Device memory. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) + { + /* Attr1 in MAIR0 is configured as device memory. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; + } + else + { + /* Attr0 in MAIR0 is configured as normal memory. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; + } + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; + } + + lIndex++; + } + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. Interrupt Program + * Status Register (IPSR) holds the exception number of the currently-executing + * exception or zero for Thread mode.*/ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.c b/portable/GCC/ARM_CM35P/non_secure/portasm.c new file mode 100644 index 00000000000..9f9b2e68d39 --- /dev/null +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.c @@ -0,0 +1,470 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION + * is defined correctly and privileged functions are placed in correct sections. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Portasm includes. */ +#include "portasm.h" + +/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the + * header files. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ + " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + " \n" + #if ( configENABLE_MPU == 1 ) + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + " str r4, [r2] \n"/* Disable MPU. */ + " \n" + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ + " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r2] \n"/* Program MAIR0. */ + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #4 \n"/* r4 = 4. */ + " str r4, [r2] \n"/* Program RNR = 4. */ + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ + " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #8 \n"/* r4 = 8. */ + " str r4, [r2] \n"/* Program RNR = 8. */ + " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #12 \n"/* r4 = 12. */ + " str r4, [r2] \n"/* Program RNR = 12. */ + " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + " str r4, [r2] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ + #endif /* configENABLE_MPU */ + " \n" + #if ( configENABLE_MPU == 1 ) + " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ + " ldr r5, xSecureContextConst2 \n" + " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " msr control, r3 \n"/* Set this task's CONTROL value. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r4 \n"/* Finally, branch to EXC_RETURN. */ + #else /* configENABLE_MPU */ + " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n"/* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + "xSecureContextConst2: .word xSecureContext \n" + #if ( configENABLE_MPU == 1 ) + "xMPUCTRLConst2: .word 0xe000ed94 \n" + "xMAIR0Const2: .word 0xe000edc0 \n" + "xRNRConst2: .word 0xe000ed98 \n" + "xRBARConst2: .word 0xe000ed9c \n" + #endif /* configENABLE_MPU */ + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n"/* r0 = CONTROL. */ + " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ + " ite ne \n" + " movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ + " moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ + " bx lr \n"/* Return. */ + " \n" + " .align 4 \n" + ::: "r0", "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n"/* Read the CONTROL register. */ + " bic r0, #1 \n"/* Clear the bit 0. */ + " msr control, r0 \n"/* Write back the new CONTROL value. */ + " bx lr \n"/* Return to the caller. */ + ::: "r0", "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vResetPrivilege( void ) /* __attribute__ (( naked )) */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n"/* r0 = CONTROL. */ + " orr r0, #1 \n"/* r0 = r0 | 1. */ + " msr control, r0 \n"/* CONTROL = r0. */ + " bx lr \n"/* Return to the caller. */ + ::: "r0", "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */ + " ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */ + " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ + " cpsie i \n"/* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc %0 \n"/* System call to start the first task. */ + " nop \n" + " \n" + " .align 4 \n" + "xVTORConst: .word 0xe000ed08 \n" + ::"i" ( portSVC_START_SCHEDULER ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ + " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bx lr \n"/* Return. */ + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " msr basepri, r0 \n"/* basepri = ulMask. */ + " dsb \n" + " isb \n" + " bx lr \n"/* Return. */ + ::: "memory" + ); +} +/*-----------------------------------------------------------*/ + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n"/* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n"/* No secure context to save. */ + " push {r0-r2, r14} \n" + " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r3} \n"/* LR is now in r3. */ + " mov lr, r3 \n"/* LR = r3. */ + " lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " \n" + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ + #if ( configENABLE_MPU == 1 ) + " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + #else /* configENABLE_MPU */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ + #endif /* configENABLE_MPU */ + " b select_next_task \n" + " \n" + " save_ns_context: \n" + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( configENABLE_MPU == 1 ) + " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + #else /* configENABLE_MPU */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ + #endif /* configENABLE_MPU */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n"/* r0 = 0. */ + " msr basepri, r0 \n"/* Enable interrupts. */ + " \n" + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + #if ( configENABLE_MPU == 1 ) + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + " str r4, [r3] \n"/* Disable MPU. */ + " \n" + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ + " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r3] \n"/* Program MAIR0. */ + " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #4 \n"/* r4 = 4. */ + " str r4, [r3] \n"/* Program RNR = 4. */ + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #8 \n"/* r4 = 8. */ + " str r4, [r3] \n"/* Program RNR = 8. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #12 \n"/* r4 = 12. */ + " str r4, [r3] \n"/* Program RNR = 12. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + " str r4, [r3] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ + #endif /* configENABLE_MPU */ + " \n" + #if ( configENABLE_MPU == 1 ) + " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" + #else /* configENABLE_MPU */ + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" + #endif /* configENABLE_MPU */ + " \n" + " restore_ns_context: \n" + " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + "xSecureContextConst: .word xSecureContext \n" + #if ( configENABLE_MPU == 1 ) + "xMPUCTRLConst: .word 0xe000ed94 \n" + "xMAIR0Const: .word 0xe000edc0 \n" + "xRNRConst: .word 0xe000ed98 \n" + "xRBARConst: .word 0xe000ed9c \n" + #endif /* configENABLE_MPU */ + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} +/*-----------------------------------------------------------*/ + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " tst lr, #4 \n" + " ite eq \n" + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r1, svchandler_address_const \n" + " bx r1 \n" + " \n" + " .align 4 \n" + "svchandler_address_const: .word vPortSVCHandler_C \n" + ); +} +/*-----------------------------------------------------------*/ + +void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " svc %0 \n"/* Secure context is allocated in the supervisor call. */ + " bx lr \n"/* Return. */ + ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */ + " ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */ + " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ + " it ne \n" + " svcne %0 \n"/* Secure context is freed in the supervisor call. */ + " bx lr \n"/* Return. */ + ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.h b/portable/GCC/ARM_CM35P/non_secure/portasm.h new file mode 100644 index 00000000000..ecd86b97fd1 --- /dev/null +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.h @@ -0,0 +1,114 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __PORT_ASM_H__ +#define __PORT_ASM_H__ + +/* Scheduler includes. */ +#include "FreeRTOS.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ +void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ +BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + +/** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kenrel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vResetPrivilege( void ) __attribute__( ( naked ) ); + +/** + * @brief Starts the first task. + */ +void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Disables interrupts. + */ +uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Enables interrupts. + */ +void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief PendSV Exception handler. + */ +void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief SVC Handler. + */ +void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ +void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + +/** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ +void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +#endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacro.h b/portable/GCC/ARM_CM35P/non_secure/portmacro.h new file mode 100644 index 00000000000..33bfb283461 --- /dev/null +++ b/portable/GCC/ARM_CM35P/non_secure/portmacro.h @@ -0,0 +1,67 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "portmacrocommon.h" + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + +/** + * Architecture specifics. + */ +#define portARCH_NAME "Cortex-M35P" +#define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ +#define portDISABLE_INTERRUPTS() ulSetInterruptMask() +#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) +/*-----------------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif /* PORTMACRO_H */ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h new file mode 100644 index 00000000000..ca7e9225c05 --- /dev/null +++ b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h @@ -0,0 +1,313 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACROCOMMON_H + #define PORTMACROCOMMON_H + + #ifdef __cplusplus + extern "C" { + #endif + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + + #ifndef configENABLE_FPU + #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. + #endif /* configENABLE_FPU */ + + #ifndef configENABLE_MPU + #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. + #endif /* configENABLE_MPU */ + + #ifndef configENABLE_TRUSTZONE + #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. + #endif /* configENABLE_TRUSTZONE */ + +/*-----------------------------------------------------------*/ + +/** + * @brief Type definitions. + */ + #define portCHAR char + #define portFLOAT float + #define portDOUBLE double + #define portLONG long + #define portSHORT short + #define portSTACK_TYPE uint32_t + #define portBASE_TYPE long + + typedef portSTACK_TYPE StackType_t; + typedef long BaseType_t; + typedef unsigned long UBaseType_t; + + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + * not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. + #endif +/*-----------------------------------------------------------*/ + +/** + * Architecture specifics. + */ + #define portSTACK_GROWTH ( -1 ) + #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + #define portBYTE_ALIGNMENT 8 + #define portNOP() + #define portINLINE __inline + #ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) + #endif + #define portHAS_STACK_OVERFLOW_CHECKING 1 +/*-----------------------------------------------------------*/ + +/** + * @brief Extern declarations. + */ + extern BaseType_t xPortIsInsideInterrupt( void ); + + extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; + + extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; + extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; + + extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + + #if ( configENABLE_TRUSTZONE == 1 ) + extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ + extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; + #endif /* configENABLE_TRUSTZONE */ + + #if ( configENABLE_MPU == 1 ) + extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; + extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; + #endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief MPU specific constants. + */ + #if ( configENABLE_MPU == 1 ) + #define portUSING_MPU_WRAPPERS 1 + #define portPRIVILEGE_BIT ( 0x80000000UL ) + #else + #define portPRIVILEGE_BIT ( 0x0UL ) + #endif /* configENABLE_MPU */ + +/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +#ifndef configTOTAL_MPU_REGIONS + /* Define to 8 for backward compatibility. */ + #define configTOTAL_MPU_REGIONS ( 8UL ) +#endif + +/* MPU regions. */ + #define portPRIVILEGED_FLASH_REGION ( 0UL ) + #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) + #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) + #define portPRIVILEGED_RAM_REGION ( 3UL ) + #define portSTACK_REGION ( 4UL ) + #define portFIRST_CONFIGURABLE_REGION ( 5UL ) + #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) + #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) + #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +/* Device memory attributes used in MPU_MAIR registers. + * + * 8-bit values encoded as follows: + * Bit[7:4] - 0000 - Device Memory + * Bit[3:2] - 00 --> Device-nGnRnE + * 01 --> Device-nGnRE + * 10 --> Device-nGRE + * 11 --> Device-GRE + * Bit[1:0] - 00, Reserved. + */ + #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ + #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ + #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ + #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ + +/* Normal memory attributes used in MPU_MAIR registers. */ + #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ + #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ + +/* Attributes used in MPU_RBAR registers. */ + #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) + #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) + #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) + + #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) + #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) + #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) + #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) + + #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + +/** + * @brief MPU settings as stored in the TCB. + */ + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + } xMPU_SETTINGS; +/*-----------------------------------------------------------*/ + +/** + * @brief SVC numbers. + */ + #define portSVC_ALLOCATE_SECURE_CONTEXT 0 + #define portSVC_FREE_SECURE_CONTEXT 1 + #define portSVC_START_SCHEDULER 2 + #define portSVC_RAISE_PRIVILEGE 3 +/*-----------------------------------------------------------*/ + +/** + * @brief Scheduler utilities. + */ + #define portYIELD() vPortYield() + #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) + #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) + #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) + #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ + #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) + #define portENTER_CRITICAL() vPortEnterCritical() + #define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/** + * @brief Tickless idle/low power functionality. + */ + #ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) + #endif +/*-----------------------------------------------------------*/ + +/** + * @brief Task function macros as described on the FreeRTOS.org WEB site. + */ + #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) + #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +/*-----------------------------------------------------------*/ + + #if ( configENABLE_TRUSTZONE == 1 ) + +/** + * @brief Allocate a secure context for the task. + * + * Tasks are not created with a secure context. Any task that is going to call + * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a + * secure context before it calls any secure function. + * + * @param[in] ulSecureStackSize The size of the secure stack to be allocated. + */ + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) + +/** + * @brief Called when a task is deleted to delete the task's secure context, + * if it has one. + * + * @param[in] pxTCB The TCB of the task being deleted. + */ + #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) + #endif /* configENABLE_TRUSTZONE */ +/*-----------------------------------------------------------*/ + + #if ( configENABLE_MPU == 1 ) + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + #define portIS_PRIVILEGED() xIsPrivileged() + +/** + * @brief Raise an SVC request to raise privilege. + * + * The SVC handler checks that the SVC was raised from a system call and only + * then it raises the privilege. If this is called from any other place, + * the privilege is not raised. + */ + #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + */ + #define portRESET_PRIVILEGE() vResetPrivilege() + #else + #define portIS_PRIVILEGED() + #define portRAISE_PRIVILEGE() + #define portRESET_PRIVILEGE() + #endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief Barriers. + */ + #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) +/*-----------------------------------------------------------*/ + + #ifdef __cplusplus + } + #endif + +#endif /* PORTMACROCOMMON_H */ diff --git a/portable/GCC/ARM_CM35P/secure/secure_context.c b/portable/GCC/ARM_CM35P/secure/secure_context.c new file mode 100644 index 00000000000..0730d574dd0 --- /dev/null +++ b/portable/GCC/ARM_CM35P/secure/secure_context.c @@ -0,0 +1,351 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Secure context includes. */ +#include "secure_context.h" + +/* Secure heap includes. */ +#include "secure_heap.h" + +/* Secure port macros. */ +#include "secure_port_macros.h" + +/** + * @brief CONTROL value for privileged tasks. + * + * Bit[0] - 0 --> Thread mode is privileged. + * Bit[1] - 1 --> Thread mode uses PSP. + */ +#define securecontextCONTROL_VALUE_PRIVILEGED 0x02 + +/** + * @brief CONTROL value for un-privileged tasks. + * + * Bit[0] - 1 --> Thread mode is un-privileged. + * Bit[1] - 1 --> Thread mode uses PSP. + */ +#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 + +/** + * @brief Size of stack seal values in bytes. + */ +#define securecontextSTACK_SEAL_SIZE 8 + +/** + * @brief Stack seal value as recommended by ARM. + */ +#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 + +/** + * @brief Maximum number of secure contexts. + */ +#ifndef secureconfigMAX_SECURE_CONTEXTS + #define secureconfigMAX_SECURE_CONTEXTS 8UL +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Pre-allocated array of secure contexts. + */ +SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; +/*-----------------------------------------------------------*/ + +/** + * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). + * + * This function ensures that only one secure context is allocated for a task. + * + * @param[in] pvTaskHandle The task handle for which the secure context is allocated. + * + * @return Index of a free secure context in the xSecureContexts array. + */ +static uint32_t ulGetSecureContext( void * pvTaskHandle ); + +/** + * @brief Return the secure context to the secure context pool (xSecureContexts). + * + * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. + */ +static void vReturnSecureContext( uint32_t ulSecureContextIndex ); + +/* These are implemented in assembly. */ +extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); +extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); +/*-----------------------------------------------------------*/ + +static uint32_t ulGetSecureContext( void * pvTaskHandle ) +{ + /* Start with invalid index. */ + uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; + + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) + { + if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && + ( xSecureContexts[ i ].pucStackLimit == NULL ) && + ( xSecureContexts[ i ].pucStackStart == NULL ) && + ( xSecureContexts[ i ].pvTaskHandle == NULL ) && + ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) + { + ulSecureContextIndex = i; + } + else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) + { + /* A task can only have one secure context. Do not allocate a second + * context for the same task. */ + ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; + break; + } + } + + return ulSecureContextIndex; +} +/*-----------------------------------------------------------*/ + +static void vReturnSecureContext( uint32_t ulSecureContextIndex ) +{ + xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; + xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; + xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) +{ + uint32_t ulIPSR, i; + static uint32_t ulSecureContextsInitialized = 0; + + /* Read the Interrupt Program Status Register (IPSR) value. */ + secureportREAD_IPSR( ulIPSR ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. */ + if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) + { + /* Ensure to initialize secure contexts only once. */ + ulSecureContextsInitialized = 1; + + /* No stack for thread mode until a task's context is loaded. */ + secureportSET_PSPLIM( securecontextNO_STACK ); + secureportSET_PSP( securecontextNO_STACK ); + + /* Initialize all secure contexts. */ + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) + { + xSecureContexts[ i ].pucCurrentStackPointer = NULL; + xSecureContexts[ i ].pucStackLimit = NULL; + xSecureContexts[ i ].pucStackStart = NULL; + xSecureContexts[ i ].pvTaskHandle = NULL; + } + + #if ( configENABLE_MPU == 1 ) + { + /* Configure thread mode to use PSP and to be unprivileged. */ + secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); + } + #else /* configENABLE_MPU */ + { + /* Configure thread mode to use PSP and to be privileged. */ + secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); + } + #endif /* configENABLE_MPU */ + } +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ) +#else /* configENABLE_MPU */ + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ) +#endif /* configENABLE_MPU */ +{ + uint8_t * pucStackMemory = NULL; + uint8_t * pucStackLimit; + uint32_t ulIPSR, ulSecureContextIndex; + SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; + + #if ( configENABLE_MPU == 1 ) + uint32_t * pulCurrentStackPointer = NULL; + #endif /* configENABLE_MPU */ + + /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit + * Register (PSPLIM) value. */ + secureportREAD_IPSR( ulIPSR ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. + * Also do nothing, if a secure context us already loaded. PSPLIM is set to + * securecontextNO_STACK when no secure context is loaded. */ + if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) + { + /* Ontain a free secure context. */ + ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); + + /* Were we able to get a free context? */ + if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) + { + /* Allocate the stack space. */ + pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); + + if( pucStackMemory != NULL ) + { + /* Since stack grows down, the starting point will be the last + * location. Note that this location is next to the last + * allocated byte for stack (excluding the space for seal values) + * because the hardware decrements the stack pointer before + * writing i.e. if stack pointer is 0x2, a push operation will + * decrement the stack pointer to 0x1 and then write at 0x1. */ + xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; + + /* Seal the created secure process stack. */ + *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; + *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; + + /* The stack cannot go beyond this location. This value is + * programmed in the PSPLIM register on context switch.*/ + xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; + + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; + + #if ( configENABLE_MPU == 1 ) + { + /* Store the correct CONTROL value for the task on the stack. + * This value is programmed in the CONTROL register on + * context switch. */ + pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart; + pulCurrentStackPointer--; + + if( ulIsTaskPrivileged ) + { + *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED; + } + else + { + *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED; + } + + /* Store the current stack pointer. This value is programmed in + * the PSP register on context switch. */ + xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer; + } + #else /* configENABLE_MPU */ + { + /* Current SP is set to the starting of the stack. This + * value programmed in the PSP register on context switch. */ + xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; + } + #endif /* configENABLE_MPU */ + + /* Ensure to never return 0 as a valid context handle. */ + xSecureContextHandle = ulSecureContextIndex + 1UL; + } + } + } + + return xSecureContextHandle; +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) +{ + uint32_t ulIPSR, ulSecureContextIndex; + + /* Read the Interrupt Program Status Register (IPSR) value. */ + secureportREAD_IPSR( ulIPSR ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. */ + if( ulIPSR != 0 ) + { + /* Only free if a valid context handle is passed. */ + if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) + { + ulSecureContextIndex = xSecureContextHandle - 1UL; + + /* Ensure that the secure context being deleted is associated with + * the task. */ + if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) + { + /* Free the stack space. */ + vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); + + /* Return the secure context back to the free secure contexts pool. */ + vReturnSecureContext( ulSecureContextIndex ); + } + } + } +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) +{ + uint8_t * pucStackLimit; + uint32_t ulSecureContextIndex; + + if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) + { + ulSecureContextIndex = xSecureContextHandle - 1UL; + + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that no secure context is loaded and the task is loading it's + * own context. */ + if( ( pucStackLimit == securecontextNO_STACK ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } + } +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) +{ + uint8_t * pucStackLimit; + uint32_t ulSecureContextIndex; + + if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) + { + ulSecureContextIndex = xSecureContextHandle - 1UL; + + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that task's context is loaded and the task is saving it's own + * context. */ + if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } + } +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/secure/secure_context.h b/portable/GCC/ARM_CM35P/secure/secure_context.h new file mode 100644 index 00000000000..d0adbaf018f --- /dev/null +++ b/portable/GCC/ARM_CM35P/secure/secure_context.h @@ -0,0 +1,135 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __SECURE_CONTEXT_H__ +#define __SECURE_CONTEXT_H__ + +/* Standard includes. */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOSConfig.h" + +/** + * @brief PSP value when no secure context is loaded. + */ +#define securecontextNO_STACK 0x0 + +/** + * @brief Invalid context ID. + */ +#define securecontextINVALID_CONTEXT_ID 0UL +/*-----------------------------------------------------------*/ + +/** + * @brief Structure to represent a secure context. + * + * @note Since stack grows down, pucStackStart is the highest address while + * pucStackLimit is the first address of the allocated memory. + */ +typedef struct SecureContext +{ + uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ + uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ + uint8_t * pucStackStart; /**< First location of the stack memory. */ + void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ +} SecureContext_t; +/*-----------------------------------------------------------*/ + +/** + * @brief Opaque handle for a secure context. + */ +typedef uint32_t SecureContextHandle_t; +/*-----------------------------------------------------------*/ + +/** + * @brief Initializes the secure context management system. + * + * PSP is set to NULL and therefore a task must allocate and load a context + * before calling any secure side function in the thread mode. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + */ +void SecureContext_Init( void ); + +/** + * @brief Allocates a context on the secure side. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + * + * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. + * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. + * + * @return Opaque context handle if context is successfully allocated, NULL + * otherwise. + */ +#if ( configENABLE_MPU == 1 ) + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ); +#else /* configENABLE_MPU */ + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ); +#endif /* configENABLE_MPU */ + +/** + * @brief Frees the given context. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + * + * @param[in] xSecureContextHandle Context handle corresponding to the + * context to be freed. + */ +void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); + +/** + * @brief Loads the given context. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + * + * @param[in] xSecureContextHandle Context handle corresponding to the context + * to be loaded. + */ +void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); + +/** + * @brief Saves the given context. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + * + * @param[in] xSecureContextHandle Context handle corresponding to the context + * to be saved. + */ +void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); + +#endif /* __SECURE_CONTEXT_H__ */ diff --git a/portable/GCC/ARM_CM35P/secure/secure_context_port.c b/portable/GCC/ARM_CM35P/secure/secure_context_port.c new file mode 100644 index 00000000000..13520870bca --- /dev/null +++ b/portable/GCC/ARM_CM35P/secure/secure_context_port.c @@ -0,0 +1,97 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Secure context includes. */ +#include "secure_context.h" + +/* Secure port macros. */ +#include "secure_port_macros.h" + +void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); +void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); + +void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) +{ + /* pxSecureContext value is in r0. */ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r1, ipsr \n" /* r1 = IPSR. */ + " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ + " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ + " \n" + #if ( configENABLE_MPU == 1 ) + " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */ + " msr control, r3 \n" /* CONTROL = r3. */ + #endif /* configENABLE_MPU */ + " \n" + " msr psplim, r2 \n" /* PSPLIM = r2. */ + " msr psp, r1 \n" /* PSP = r1. */ + " \n" + " load_ctx_therad_mode: \n" + " bx lr \n" + " \n" + ::: "r0", "r1", "r2" + ); +} +/*-----------------------------------------------------------*/ + +void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) +{ + /* pxSecureContext value is in r0. */ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r1, ipsr \n" /* r1 = IPSR. */ + " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ + " mrs r1, psp \n" /* r1 = PSP. */ + " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " vstmdb r1!, {s0} \n" /* Trigger the deferred stacking of FPU registers. */ + " vldmia r1!, {s0} \n" /* Nullify the effect of the previous statement. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + #if ( configENABLE_MPU == 1 ) + " mrs r2, control \n" /* r2 = CONTROL. */ + " stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */ + #endif /* configENABLE_MPU */ + " \n" + " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ + " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */ + " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */ + " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ + " \n" + " save_ctx_therad_mode: \n" + " bx lr \n" + " \n" + ::"i" ( securecontextNO_STACK ) : "r1", "memory" + ); +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/secure/secure_heap.c b/portable/GCC/ARM_CM35P/secure/secure_heap.c new file mode 100644 index 00000000000..157fdbf0eec --- /dev/null +++ b/portable/GCC/ARM_CM35P/secure/secure_heap.c @@ -0,0 +1,454 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Standard includes. */ +#include + +/* Secure context heap includes. */ +#include "secure_heap.h" + +/* Secure port macros. */ +#include "secure_port_macros.h" + +/** + * @brief Total heap size. + */ +#ifndef secureconfigTOTAL_HEAP_SIZE + #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) +#endif + +/* No test marker by default. */ +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +/* No tracing by default. */ +#ifndef traceMALLOC + #define traceMALLOC( pvReturn, xWantedSize ) +#endif + +/* No tracing by default. */ +#ifndef traceFREE + #define traceFREE( pv, xBlockSize ) +#endif + +/* Block sizes must not get too small. */ +#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) +/*-----------------------------------------------------------*/ + +/* Allocate the memory for the heap. */ +#if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) + +/* The application writer has already defined the array used for the RTOS +* heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; +#else /* configAPPLICATION_ALLOCATED_HEAP */ + static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/** + * @brief The linked list structure. + * + * This is used to link free blocks in order of their memory address. + */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ + size_t xBlockSize; /**< The size of the free block. */ +} BlockLink_t; +/*-----------------------------------------------------------*/ + +/** + * @brief Called automatically to setup the required heap structures the first + * time pvPortMalloc() is called. + */ +static void prvHeapInit( void ); + +/** + * @brief Inserts a block of memory that is being freed into the correct + * position in the list of free memory blocks. + * + * The block being freed will be merged with the block in front it and/or the + * block behind it if the memory blocks are adjacent to each other. + * + * @param[in] pxBlockToInsert The block being freed. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); +/*-----------------------------------------------------------*/ + +/** + * @brief The size of the structure placed at the beginning of each allocated + * memory block must by correctly byte aligned. + */ +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); + +/** + * @brief Create a couple of list links to mark the start and end of the list. + */ +static BlockLink_t xStart; +static BlockLink_t * pxEnd = NULL; + +/** + * @brief Keeps track of the number of free bytes remaining, but says nothing + * about fragmentation. + */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/** + * @brief Gets set to the top bit of an size_t type. + * + * When this bit in the xBlockSize member of an BlockLink_t structure is set + * then the block belongs to the application. When the bit is free the block is + * still part of the free heap space. + */ +static size_t xBlockAllocatedBit = 0; +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ + BlockLink_t * pxFirstFreeBlock; + uint8_t * pucAlignedHeap; + size_t uxAddress; + size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; + + /* Ensure the heap starts on a correctly aligned boundary. */ + uxAddress = ( size_t ) ucHeap; + + if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) + { + uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); + uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); + xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; + } + + pucAlignedHeap = ( uint8_t * ) uxAddress; + + /* xStart is used to hold a pointer to the first item in the list of free + * blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + * at the end of the heap space. */ + uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; + uxAddress -= xHeapStructSize; + uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); + pxEnd = ( void * ) uxAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + * entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* Only one block exists - and it covers the entire usable heap space. */ + xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) +{ + BlockLink_t * pxIterator; + uint8_t * puc; + + /* Iterate through the list until a block is found that has a higher address + * than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + * make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + * make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + * before and the block after, then it's pxNextFreeBlock pointer will have + * already been set, and should not be set here as that would make it point + * to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +void * pvPortMalloc( size_t xWantedSize ) +{ + BlockLink_t * pxBlock; + BlockLink_t * pxPreviousBlock; + BlockLink_t * pxNewBlockLink; + void * pvReturn = NULL; + + /* If this is the first call to malloc then the heap will require + * initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Check the requested block size is not so large that the top bit is set. + * The top bit of the block size member of the BlockLink_t structure is used + * to determine who owns the block - the application or the kernel, so it + * must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + * structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number of + * bytes. */ + if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); + secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + * one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size was + * not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + * BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + * of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + * two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + * block following the number of bytes requested. The void + * cast is used to prevent byte alignment warnings from the + * compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); + + /* Calculate the sizes of two blocks split from the single + * block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( pxNewBlockLink ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned by + * the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + + #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ + + secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void * pv ) +{ + uint8_t * puc = ( uint8_t * ) pv; + BlockLink_t * pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + * before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + secureportASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + * allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + secureportDISABLE_NON_SECURE_INTERRUPTS(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + secureportENABLE_NON_SECURE_INTERRUPTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/secure/secure_heap.h b/portable/GCC/ARM_CM35P/secure/secure_heap.h new file mode 100644 index 00000000000..c13590f86ad --- /dev/null +++ b/portable/GCC/ARM_CM35P/secure/secure_heap.h @@ -0,0 +1,66 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __SECURE_HEAP_H__ +#define __SECURE_HEAP_H__ + +/* Standard includes. */ +#include + +/** + * @brief Allocates memory from heap. + * + * @param[in] xWantedSize The size of the memory to be allocated. + * + * @return Pointer to the memory region if the allocation is successful, NULL + * otherwise. + */ +void * pvPortMalloc( size_t xWantedSize ); + +/** + * @brief Frees the previously allocated memory. + * + * @param[in] pv Pointer to the memory to be freed. + */ +void vPortFree( void * pv ); + +/** + * @brief Get the free heap size. + * + * @return Free heap size. + */ +size_t xPortGetFreeHeapSize( void ); + +/** + * @brief Get the minimum ever free heap size. + * + * @return Minimum ever free heap size. + */ +size_t xPortGetMinimumEverFreeHeapSize( void ); + +#endif /* __SECURE_HEAP_H__ */ diff --git a/portable/GCC/ARM_CM35P/secure/secure_init.c b/portable/GCC/ARM_CM35P/secure/secure_init.c new file mode 100644 index 00000000000..dc19ebc7d5e --- /dev/null +++ b/portable/GCC/ARM_CM35P/secure/secure_init.c @@ -0,0 +1,106 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Standard includes. */ +#include + +/* Secure init includes. */ +#include "secure_init.h" + +/* Secure port macros. */ +#include "secure_port_macros.h" + +/** + * @brief Constants required to manipulate the SCB. + */ +#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ +#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) +#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) +#define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) +#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) + +/** + * @brief Constants required to manipulate the FPU. + */ +#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define secureinitFPCCR_LSPENS_POS ( 29UL ) +#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) +#define secureinitFPCCR_TS_POS ( 26UL ) +#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) + +#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ +#define secureinitNSACR_CP10_POS ( 10UL ) +#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) +#define secureinitNSACR_CP11_POS ( 11UL ) +#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) +{ + uint32_t ulIPSR; + + /* Read the Interrupt Program Status Register (IPSR) value. */ + secureportREAD_IPSR( ulIPSR ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. */ + if( ulIPSR != 0 ) + { + *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | + ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | + ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); + } +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) +{ + uint32_t ulIPSR; + + /* Read the Interrupt Program Status Register (IPSR) value. */ + secureportREAD_IPSR( ulIPSR ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. */ + if( ulIPSR != 0 ) + { + /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is + * permitted. CP11 should be programmed to the same value as CP10. */ + *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); + + /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures + * that we can enable/disable lazy stacking in port.c file. */ + *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); + + /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP + * registers (S16-S31) are also pushed to stack on exception entry and + * restored on exception return. */ + *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); + } +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/secure/secure_init.h b/portable/GCC/ARM_CM35P/secure/secure_init.h new file mode 100644 index 00000000000..21daeda6b89 --- /dev/null +++ b/portable/GCC/ARM_CM35P/secure/secure_init.h @@ -0,0 +1,54 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __SECURE_INIT_H__ +#define __SECURE_INIT_H__ + +/** + * @brief De-prioritizes the non-secure exceptions. + * + * This is needed to ensure that the non-secure PendSV runs at the lowest + * priority. Context switch is done in the non-secure PendSV handler. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + */ +void SecureInit_DePrioritizeNSExceptions( void ); + +/** + * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. + * + * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point + * Registers are not leaked to the non-secure side. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + */ +void SecureInit_EnableNSFPUAccess( void ); + +#endif /* __SECURE_INIT_H__ */ diff --git a/portable/GCC/ARM_CM35P/secure/secure_port_macros.h b/portable/GCC/ARM_CM35P/secure/secure_port_macros.h new file mode 100644 index 00000000000..304913b8dbf --- /dev/null +++ b/portable/GCC/ARM_CM35P/secure/secure_port_macros.h @@ -0,0 +1,140 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __SECURE_PORT_MACROS_H__ +#define __SECURE_PORT_MACROS_H__ + +/** + * @brief Byte alignment requirements. + */ +#define secureportBYTE_ALIGNMENT 8 +#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) + +/** + * @brief Macro to declare a function as non-secure callable. + */ +#if defined( __IAR_SYSTEMS_ICC__ ) + #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root +#else + #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) +#endif + +/** + * @brief Set the secure PRIMASK value. + */ +#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ + __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) + +/** + * @brief Set the non-secure PRIMASK value. + */ +#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ + __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) + +/** + * @brief Read the PSP value in the given variable. + */ +#define secureportREAD_PSP( pucOutCurrentStackPointer ) \ + __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) + +/** + * @brief Set the PSP to the given value. + */ +#define secureportSET_PSP( pucCurrentStackPointer ) \ + __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) + +/** + * @brief Read the PSPLIM value in the given variable. + */ +#define secureportREAD_PSPLIM( pucOutStackLimit ) \ + __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) + +/** + * @brief Set the PSPLIM to the given value. + */ +#define secureportSET_PSPLIM( pucStackLimit ) \ + __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) + +/** + * @brief Set the NonSecure MSP to the given value. + */ +#define secureportSET_MSP_NS( pucMainStackPointer ) \ + __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) + +/** + * @brief Set the CONTROL register to the given value. + */ +#define secureportSET_CONTROL( ulControl ) \ + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) + +/** + * @brief Read the Interrupt Program Status Register (IPSR) value in the given + * variable. + */ +#define secureportREAD_IPSR( ulIPSR ) \ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) + +/** + * @brief PRIMASK value to enable interrupts. + */ +#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 + +/** + * @brief PRIMASK value to disable interrupts. + */ +#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 + +/** + * @brief Disable secure interrupts. + */ +#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) + +/** + * @brief Disable non-secure interrupts. + * + * This effectively disables context switches. + */ +#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) + +/** + * @brief Enable non-secure interrupts. + */ +#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) + +/** + * @brief Assert definition. + */ +#define secureportASSERT( x ) \ + if( ( x ) == 0 ) \ + { \ + secureportDISABLE_SECURE_INTERRUPTS(); \ + secureportDISABLE_NON_SECURE_INTERRUPTS(); \ + for( ; ; ) {; } \ + } + +#endif /* __SECURE_PORT_MACROS_H__ */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c new file mode 100644 index 00000000000..9976daee49a --- /dev/null +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -0,0 +1,1261 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/* Portasm includes. */ +#include "portasm.h" + +#if ( configENABLE_TRUSTZONE == 1 ) + /* Secure components includes. */ + #include "secure_context.h" + #include "secure_init.h" +#endif /* configENABLE_TRUSTZONE */ + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/** + * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only + * i.e. the processor boots as secure and never jumps to the non-secure side. + * The Trust Zone support in the port must be disabled in order to run FreeRTOS + * on the secure side. The following are the valid configuration seetings: + * + * 1. Run FreeRTOS on the Secure Side: + * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 + * + * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 + * + * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 + */ +#if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) + #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the NVIC. + */ +#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) +#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) +#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the SCB. + */ +#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) +#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the FPU. + */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR_CP10_VALUE ( 3UL ) +#define portCPACR_CP11_VALUE portCPACR_CP10_VALUE +#define portCPACR_CP10_POS ( 20UL ) +#define portCPACR_CP11_POS ( 22UL ) + +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR_ASPEN_POS ( 31UL ) +#define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) +#define portFPCCR_LSPEN_POS ( 30UL ) +#define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the MPU. + */ +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) + +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) + +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) + +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) + +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) + +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) + +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ + +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) + +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) + +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) + +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) + +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) + +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) + +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) + +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) + +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) + +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) + +/* Enable privileged access to unmapped region. */ +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) + +/* Enable MPU. */ +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) + +/* Expected value of the portMPU_TYPE register. */ +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief The maximum 24-bit number. + * + * It is needed because the systick is a 24-bit counter. + */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/** + * @brief A fiddle factor to estimate the number of SysTick counts that would + * have occurred while the SysTick counter is stopped during tickless idle + * calculations. + */ +#define portMISSED_COUNTS_FACTOR ( 94UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to set up the initial stack. + */ +#define portINITIAL_XPSR ( 0x01000000 ) + +#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ + #define portINITIAL_EXC_RETURN ( 0xfffffffd ) +#else + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ + #define portINITIAL_EXC_RETURN ( 0xffffffbc ) +#endif /* configRUN_FREERTOS_SECURE_ONLY */ + +/** + * @brief CONTROL register privileged bit mask. + * + * Bit[0] in CONTROL register tells the privilege: + * Bit[0] = 0 ==> The task is privileged. + * Bit[0] = 1 ==> The task is not privileged. + */ +#define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) + +/** + * @brief Initial CONTROL register values. + */ +#define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) +#define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) + +/** + * @brief Let the user override the default SysTick clock rate. If defined by the + * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the + * configuration register. + */ +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) +#else + /* Select the option to clock SysTick not at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) +#endif + +/** + * @brief Let the user override the pre-loading of the initial LR with the + * address of prvTaskExitError() in case it messes up unwinding of the stack + * in the debugger. + */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/** + * @brief If portPRELOAD_REGISTERS then registers will be given an initial value + * when a task is created. This helps in debugging at the cost of code size. + */ +#define portPRELOAD_REGISTERS 1 + +/** + * @brief A task is created without a secure context, and must call + * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes + * any secure calls. + */ +#define portNO_SECURE_CONTEXT 0 +/*-----------------------------------------------------------*/ + +/** + * @brief Used to catch tasks that attempt to return from their implementing + * function. + */ +static void prvTaskExitError( void ); + +#if ( configENABLE_MPU == 1 ) + +/** + * @brief Setup the Memory Protection Unit (MPU). + */ + static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_FPU == 1 ) + +/** + * @brief Setup the Floating Point Unit (FPU). + */ + static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_FPU */ + +/** + * @brief Setup the timer to generate the tick interrupts. + * + * The implementation in this file is weak to allow application writers to + * change the timer used to generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether the current execution context is interrupt. + * + * @return pdTRUE if the current execution context is interrupt, pdFALSE + * otherwise. + */ +BaseType_t xPortIsInsideInterrupt( void ); + +/** + * @brief Yield the processor. + */ +void vPortYield( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Enter critical section. + */ +void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Exit from critical section. + */ +void vPortExitCritical( void ) PRIVILEGED_FUNCTION; + +/** + * @brief SysTick handler. + */ +void SysTick_Handler( void ) PRIVILEGED_FUNCTION; + +/** + * @brief C part of SVC handler. + */ +portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +/** + * @brief Each task maintains its own interrupt status in the critical nesting + * variable. + */ +PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; + +#if ( configENABLE_TRUSTZONE == 1 ) + +/** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ + PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; +#endif /* configENABLE_TRUSTZONE */ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + +/** + * @brief The number of SysTick increments that make up one tick period. + */ + PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; + +/** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ + PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; + +/** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ + PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + * method as that will mask interrupts that should exit sleep mode. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* If a context switch is pending or a task is waiting for the scheduler + * to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Re-enable interrupts - see comments above the cpsid instruction + * above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + else + { + /* Stop the SysTick momentarily. The time the SysTick is stopped for + * is accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Use the SysTick current-value register to determine the number of + * SysTick decrements remaining until the next tick interrupt. If the + * current-value register is zero, then there are actually + * ulTimerCountsForOneTick decrements remaining, not zero, because the + * SysTick requests the interrupt when decrementing from 1 to 0. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulTimerCountsForOneTick; + } + + /* Calculate the reload value required to wait xExpectedIdleTime + * tick periods. -1 is used because this code normally executes part + * way through the first tick period. But if the SysTick IRQ is now + * pending, then clear the IRQ, suppressing the first tick, and correct + * the reload value to reflect that the second tick period is already + * underway. The expected idle time is always at least two ticks. */ + ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + + if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) + { + portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; + ulReloadValue -= ulTimerCountsForOneTick; + } + + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + * zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + * set its parameter to 0 to indicate that its implementation contains + * its own wait for interrupt or wait for event instruction, and so wfi + * should not be executed again. However, the original expected idle + * time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + + if( xModifiableIdleTime > 0 ) + { + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "wfi" ); + __asm volatile ( "isb" ); + } + + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Re-enable interrupts to allow the interrupt that brought the MCU + * out of sleep mode to execute immediately. See comments above + * the cpsid instruction above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable interrupts again because the clock is about to be stopped + * and interrupts that execute while the clock is stopped will increase + * any slippage between the time maintained by the RTOS and calendar + * time. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable the SysTick clock without reading the + * portNVIC_SYSTICK_CTRL_REG register to ensure the + * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, + * the time the SysTick is stopped for is accounted for as best it can + * be, but using the tickless mode will inevitably result in some tiny + * drift of the time maintained by the kernel with respect to calendar + * time*/ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Determine whether the SysTick has already counted to zero. */ + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt ended the sleep (or is now pending), and + * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG + * with whatever remains of the new tick period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + * underflowed because the post sleep hook did something + * that took too long or because the SysTick current-value register + * is zero. */ + if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* As the pending tick will be processed as soon as this + * function exits, the tick value maintained by the tick is stepped + * forward by one less than the time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. */ + + /* Use the SysTick current-value register to determine the + * number of SysTick decrements remaining until the expected idle + * time would have ended. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) + { + /* If the SysTick is not using the core clock, the current- + * value register might still be zero here. In that case, the + * SysTick didn't load from the reload register, and there are + * ulReloadValue decrements remaining in the expected idle + * time, not zero. */ + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulReloadValue; + } + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Work out how long the sleep lasted rounded to complete tick + * periods (not the ulReload value which accounted for part + * ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; + + /* How many complete tick periods passed while the processor + * was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + * period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, + * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If + * the SysTick is not using the core clock, temporarily configure it to + * use the core clock. This configuration forces the SysTick to load + * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next + * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready + * to receive the standard value immediately. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) + { + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + #else + { + /* The temporary usage of the core clock has served its purpose, + * as described above. Resume usage of the other clock. */ + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; + + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + /* The partial tick period already ended. Be sure the SysTick + * counts it only once. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; + } + + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Step the tick to account for any tick periods that elapsed. */ + vTaskStepTick( ulCompleteTickPeriods ); + + /* Exit with interrupts enabled. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + } +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if ( configUSE_TICKLESS_IDLE == 1 ) + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Stop and reset the SysTick. */ + portNVIC_SYSTICK_CTRL_REG = 0UL; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + volatile uint32_t ulDummy = 0UL; + + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). Artificially force an assert() + * to be triggered if configASSERT() is defined, then stop here so + * application writers can catch the error. */ + configASSERT( ulCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + + while( ulDummy == 0 ) + { + /* This file calls prvTaskExitError() after the scheduler has been + * started to remove a compiler warning about the function being + * defined but never called. ulDummy is used purely to quieten other + * warnings about code appearing after this function is called - making + * ulDummy volatile makes the compiler think the function could return + * and therefore not output an 'unreachable code' warning for code that + * appears after it. */ + } +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + extern uint32_t * __unprivileged_flash_start__; + extern uint32_t * __unprivileged_flash_end__; + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + #else /* if defined( __ARMCC_VERSION ) */ + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + extern uint32_t __unprivileged_flash_start__[]; + extern uint32_t __unprivileged_flash_end__[]; + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + + /* The only permitted number of regions are 8 or 16. */ + configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); + + /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ + configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + + /* Check that the MPU is present. */ + if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) + { + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; + + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); + } + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* Enable non-secure access to the FPU. */ + SecureInit_EnableNSFPUAccess(); + } + #endif /* configENABLE_TRUSTZONE */ + + /* CP10 = 11 ==> Full access to FPU i.e. both privileged and + * unprivileged code should be able to access FPU. CP11 should be + * programmed to the same value as CP10. */ + *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | + ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) + ); + + /* ASPEN = 1 ==> Hardware should automatically preserve floating point + * context on exception entry and restore on exception return. + * LSPEN = 1 ==> Enable lazy context save of FP state. */ + *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); + } +#endif /* configENABLE_FPU */ +/*-----------------------------------------------------------*/ + +void vPortYield( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + portDISABLE_INTERRUPTS(); + ulCriticalNesting++; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + configASSERT( ulCriticalNesting ); + ulCriticalNesting--; + + if( ulCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulPreviousMask; + + ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ +{ + #if ( configENABLE_MPU == 1 ) + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + #endif /* configENABLE_MPU */ + + uint32_t ulPC; + + #if ( configENABLE_TRUSTZONE == 1 ) + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; + #if ( configENABLE_MPU == 1 ) + uint32_t ulControl, ulIsTaskPrivileged; + #endif /* configENABLE_MPU */ + #endif /* configENABLE_TRUSTZONE */ + uint8_t ucSVCNumber; + + /* Register are stored on the stack in the following order - R0, R1, R2, R3, + * R12, LR, PC, xPSR. */ + ulPC = pulCallerStackAddress[ 6 ]; + ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; + + switch( ucSVCNumber ) + { + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: + + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; + + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ + + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; + + case portSVC_FREE_SECURE_CONTEXT: + + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; + + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ + + case portSVC_START_SCHEDULER: + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* De-prioritize the non-secure exceptions so that the + * non-secure pendSV runs at the lowest priority. */ + SecureInit_DePrioritizeNSExceptions(); + + /* Initialize the secure context management system. */ + SecureContext_Init(); + } + #endif /* configENABLE_TRUSTZONE */ + + #if ( configENABLE_FPU == 1 ) + { + /* Setup the Floating Point Unit (FPU). */ + prvSetupFPU(); + } + #endif /* configENABLE_FPU */ + + /* Setup the context of the first task so that the first task starts + * executing. */ + vRestoreContextOfFirstTask(); + break; + + #if ( configENABLE_MPU == 1 ) + case portSVC_RAISE_PRIVILEGE: + + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* configENABLE_MPU */ + + default: + /* Incorrect SVC call. */ + configASSERT( pdFALSE ); + } +} +/*-----------------------------------------------------------*/ +/* *INDENT-OFF* */ +#if ( configENABLE_MPU == 1 ) + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ +#else + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +#endif /* configENABLE_MPU */ +/* *INDENT-ON* */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; + + #if ( configENABLE_MPU == 1 ) + { + pxTopOfStack--; + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + } + #endif /* configENABLE_MPU */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + + #if ( configENABLE_TRUSTZONE == 1 ) + { + pxTopOfStack--; + *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ + } + #endif /* configENABLE_TRUSTZONE */ + } + #else /* portPRELOAD_REGISTERS */ + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ + + #if ( configENABLE_MPU == 1 ) + { + pxTopOfStack--; + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + } + #endif /* configENABLE_MPU */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + + #if ( configENABLE_TRUSTZONE == 1 ) + { + pxTopOfStack--; + *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ + } + #endif /* configENABLE_TRUSTZONE */ + } + #endif /* portPRELOAD_REGISTERS */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ + portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; + portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; + + #if ( configENABLE_MPU == 1 ) + { + /* Setup the Memory Protection Unit (MPU). */ + prvSetupMPU(); + } + #endif /* configENABLE_MPU */ + + /* Start the timer that generates the tick ISR. Interrupts are disabled + * here already. */ + vPortSetupTimerInterrupt(); + + /* Initialize the critical nesting count ready for the first task. */ + ulCriticalNesting = 0; + + /* Start the first task. */ + vStartFirstTask(); + + /* Should never get here as the tasks will now be executing. Call the task + * exit error function to prevent compiler warnings about a static function + * not being called in the case that the application writer overrides this + * functionality by defining configTASK_RETURN_ADDRESS. Call + * vTaskSwitchContext() so link time optimization does not remove the + * symbol. */ + vTaskSwitchContext(); + prvTaskExitError(); + + /* Should not get here. */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( ulCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) + { + uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; + int32_t lIndex = 0; + + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + + /* Setup MAIR0. */ + xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + + /* This function is called automatically when the task is created - in + * which case the stack region parameters will be valid. At all other + * times the stack parameters will not be valid and it is assumed that + * the stack region has already been configured. */ + if( ulStackDepth > 0 ) + { + ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + + /* If the stack is within the privileged SRAM, do not protect it + * using a separate MPU region. This is needed because privileged + * SRAM is already protected using an MPU region and ARMv8-M does + * not allow overlapping MPU regions. */ + if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && + ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) + { + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; + xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; + } + else + { + /* Define the region that allows access to the stack. */ + ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; + ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; + + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + + xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + } + } + + /* User supplied configurable regions. */ + for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) + { + /* If xRegions is NULL i.e. the task has not specified any MPU + * region, the else part ensures that all the configurable MPU + * regions are invalidated. */ + if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) + { + /* Translate the generic region definition contained in xRegions + * into the ARMv8 specific MPU settings that are then stored in + * xMPUSettings. */ + ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; + ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; + ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; + + /* Start address. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | + ( portMPU_REGION_NON_SHAREABLE ); + + /* RO/RW. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); + } + else + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); + } + + /* XN. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); + } + + /* End Address. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Normal memory/ Device memory. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) + { + /* Attr1 in MAIR0 is configured as device memory. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; + } + else + { + /* Attr0 in MAIR0 is configured as normal memory. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; + } + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; + } + + lIndex++; + } + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. Interrupt Program + * Status Register (IPSR) holds the exception number of the currently-executing + * exception or zero for Thread mode.*/ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c new file mode 100644 index 00000000000..a78529d04d9 --- /dev/null +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c @@ -0,0 +1,365 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION + * is defined correctly and privileged functions are placed in correct sections. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Portasm includes. */ +#include "portasm.h" + +/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the + * header files. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ + " ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + " \n" + #if ( configENABLE_MPU == 1 ) + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + " str r4, [r2] \n"/* Disable MPU. */ + " \n" + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r3, [r2] \n"/* Program MAIR0. */ + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r3, #4 \n"/* r3 = 4. */ + " str r3, [r2] \n"/* Program RNR = 4. */ + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r3, #8 \n"/* r3 = 8. */ + " str r3, [r2] \n"/* Program RNR = 8. */ + " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r3, #12 \n"/* r3 = 12. */ + " str r3, [r2] \n"/* Program RNR = 12. */ + " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + " str r4, [r2] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ + #endif /* configENABLE_MPU */ + " \n" + #if ( configENABLE_MPU == 1 ) + " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " msr control, r2 \n"/* Set this task's CONTROL value. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n"/* Finally, branch to EXC_RETURN. */ + #else /* configENABLE_MPU */ + " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r2 \n"/* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + #if ( configENABLE_MPU == 1 ) + "xMPUCTRLConst2: .word 0xe000ed94 \n" + "xMAIR0Const2: .word 0xe000edc0 \n" + "xRNRConst2: .word 0xe000ed98 \n" + "xRBARConst2: .word 0xe000ed9c \n" + #endif /* configENABLE_MPU */ + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n"/* r0 = CONTROL. */ + " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ + " ite ne \n" + " movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ + " moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ + " bx lr \n"/* Return. */ + " \n" + " .align 4 \n" + ::: "r0", "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n"/* Read the CONTROL register. */ + " bic r0, #1 \n"/* Clear the bit 0. */ + " msr control, r0 \n"/* Write back the new CONTROL value. */ + " bx lr \n"/* Return to the caller. */ + ::: "r0", "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vResetPrivilege( void ) /* __attribute__ (( naked )) */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n"/* r0 = CONTROL. */ + " orr r0, #1 \n"/* r0 = r0 | 1. */ + " msr control, r0 \n"/* CONTROL = r0. */ + " bx lr \n"/* Return to the caller. */ + ::: "r0", "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */ + " ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */ + " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ + " cpsie i \n"/* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc %0 \n"/* System call to start the first task. */ + " nop \n" + " \n" + " .align 4 \n" + "xVTORConst: .word 0xe000ed08 \n" + ::"i" ( portSVC_START_SCHEDULER ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ + " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bx lr \n"/* Return. */ + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " msr basepri, r0 \n"/* basepri = ulMask. */ + " dsb \n" + " isb \n" + " bx lr \n"/* Return. */ + ::: "memory" + ); +} +/*-----------------------------------------------------------*/ + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, psp \n"/* Read PSP in r0. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( configENABLE_MPU == 1 ) + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r2, control \n"/* r2 = CONTROL. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ + #else /* configENABLE_MPU */ + " mrs r2, psplim \n"/* r2 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ + #endif /* configENABLE_MPU */ + " \n" + " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ + " str r0, [r1] \n"/* Save the new top of stack in TCB. */ + " \n" + " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n"/* r0 = 0. */ + " msr basepri, r0 \n"/* Enable interrupts. */ + " \n" + " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ + " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + " \n" + #if ( configENABLE_MPU == 1 ) + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + " str r4, [r2] \n"/* Disable MPU. */ + " \n" + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ + " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r3, [r2] \n"/* Program MAIR0. */ + " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r3, #4 \n"/* r3 = 4. */ + " str r3, [r2] \n"/* Program RNR = 4. */ + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r3, #8 \n"/* r3 = 8. */ + " str r3, [r2] \n"/* Program RNR = 8. */ + " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r3, #12 \n"/* r3 = 12. */ + " str r3, [r2] \n"/* Program RNR = 12. */ + " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + " str r4, [r2] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ + #endif /* configENABLE_MPU */ + " \n" + #if ( configENABLE_MPU == 1 ) + " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ + #else /* configENABLE_MPU */ + " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ + #endif /* configENABLE_MPU */ + " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + #if ( configENABLE_MPU == 1 ) + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ + #else /* configENABLE_MPU */ + " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ + #endif /* configENABLE_MPU */ + " msr psp, r0 \n"/* Remember the new top of stack for the task. */ + " bx r3 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + #if ( configENABLE_MPU == 1 ) + "xMPUCTRLConst: .word 0xe000ed94 \n" + "xMAIR0Const: .word 0xe000edc0 \n" + "xRNRConst: .word 0xe000ed98 \n" + "xRBARConst: .word 0xe000ed9c \n" + #endif /* configENABLE_MPU */ + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} +/*-----------------------------------------------------------*/ + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " tst lr, #4 \n" + " ite eq \n" + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r1, svchandler_address_const \n" + " bx r1 \n" + " \n" + " .align 4 \n" + "svchandler_address_const: .word vPortSVCHandler_C \n" + ); +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h new file mode 100644 index 00000000000..ecd86b97fd1 --- /dev/null +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h @@ -0,0 +1,114 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __PORT_ASM_H__ +#define __PORT_ASM_H__ + +/* Scheduler includes. */ +#include "FreeRTOS.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ +void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ +BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + +/** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kenrel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vResetPrivilege( void ) __attribute__( ( naked ) ); + +/** + * @brief Starts the first task. + */ +void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Disables interrupts. + */ +uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Enables interrupts. + */ +void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief PendSV Exception handler. + */ +void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief SVC Handler. + */ +void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ +void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + +/** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ +void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +#endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h new file mode 100644 index 00000000000..33bfb283461 --- /dev/null +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -0,0 +1,67 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "portmacrocommon.h" + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + +/** + * Architecture specifics. + */ +#define portARCH_NAME "Cortex-M35P" +#define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ +#define portDISABLE_INTERRUPTS() ulSetInterruptMask() +#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) +/*-----------------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif /* PORTMACRO_H */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h new file mode 100644 index 00000000000..ca7e9225c05 --- /dev/null +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -0,0 +1,313 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACROCOMMON_H + #define PORTMACROCOMMON_H + + #ifdef __cplusplus + extern "C" { + #endif + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + + #ifndef configENABLE_FPU + #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. + #endif /* configENABLE_FPU */ + + #ifndef configENABLE_MPU + #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. + #endif /* configENABLE_MPU */ + + #ifndef configENABLE_TRUSTZONE + #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. + #endif /* configENABLE_TRUSTZONE */ + +/*-----------------------------------------------------------*/ + +/** + * @brief Type definitions. + */ + #define portCHAR char + #define portFLOAT float + #define portDOUBLE double + #define portLONG long + #define portSHORT short + #define portSTACK_TYPE uint32_t + #define portBASE_TYPE long + + typedef portSTACK_TYPE StackType_t; + typedef long BaseType_t; + typedef unsigned long UBaseType_t; + + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + * not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. + #endif +/*-----------------------------------------------------------*/ + +/** + * Architecture specifics. + */ + #define portSTACK_GROWTH ( -1 ) + #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + #define portBYTE_ALIGNMENT 8 + #define portNOP() + #define portINLINE __inline + #ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) + #endif + #define portHAS_STACK_OVERFLOW_CHECKING 1 +/*-----------------------------------------------------------*/ + +/** + * @brief Extern declarations. + */ + extern BaseType_t xPortIsInsideInterrupt( void ); + + extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; + + extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; + extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; + + extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + + #if ( configENABLE_TRUSTZONE == 1 ) + extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ + extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; + #endif /* configENABLE_TRUSTZONE */ + + #if ( configENABLE_MPU == 1 ) + extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; + extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; + #endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief MPU specific constants. + */ + #if ( configENABLE_MPU == 1 ) + #define portUSING_MPU_WRAPPERS 1 + #define portPRIVILEGE_BIT ( 0x80000000UL ) + #else + #define portPRIVILEGE_BIT ( 0x0UL ) + #endif /* configENABLE_MPU */ + +/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +#ifndef configTOTAL_MPU_REGIONS + /* Define to 8 for backward compatibility. */ + #define configTOTAL_MPU_REGIONS ( 8UL ) +#endif + +/* MPU regions. */ + #define portPRIVILEGED_FLASH_REGION ( 0UL ) + #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) + #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) + #define portPRIVILEGED_RAM_REGION ( 3UL ) + #define portSTACK_REGION ( 4UL ) + #define portFIRST_CONFIGURABLE_REGION ( 5UL ) + #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) + #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) + #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +/* Device memory attributes used in MPU_MAIR registers. + * + * 8-bit values encoded as follows: + * Bit[7:4] - 0000 - Device Memory + * Bit[3:2] - 00 --> Device-nGnRnE + * 01 --> Device-nGnRE + * 10 --> Device-nGRE + * 11 --> Device-GRE + * Bit[1:0] - 00, Reserved. + */ + #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ + #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ + #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ + #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ + +/* Normal memory attributes used in MPU_MAIR registers. */ + #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ + #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ + +/* Attributes used in MPU_RBAR registers. */ + #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) + #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) + #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) + + #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) + #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) + #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) + #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) + + #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + +/** + * @brief MPU settings as stored in the TCB. + */ + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + } xMPU_SETTINGS; +/*-----------------------------------------------------------*/ + +/** + * @brief SVC numbers. + */ + #define portSVC_ALLOCATE_SECURE_CONTEXT 0 + #define portSVC_FREE_SECURE_CONTEXT 1 + #define portSVC_START_SCHEDULER 2 + #define portSVC_RAISE_PRIVILEGE 3 +/*-----------------------------------------------------------*/ + +/** + * @brief Scheduler utilities. + */ + #define portYIELD() vPortYield() + #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) + #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) + #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) + #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ + #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) + #define portENTER_CRITICAL() vPortEnterCritical() + #define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/** + * @brief Tickless idle/low power functionality. + */ + #ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) + #endif +/*-----------------------------------------------------------*/ + +/** + * @brief Task function macros as described on the FreeRTOS.org WEB site. + */ + #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) + #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +/*-----------------------------------------------------------*/ + + #if ( configENABLE_TRUSTZONE == 1 ) + +/** + * @brief Allocate a secure context for the task. + * + * Tasks are not created with a secure context. Any task that is going to call + * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a + * secure context before it calls any secure function. + * + * @param[in] ulSecureStackSize The size of the secure stack to be allocated. + */ + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) + +/** + * @brief Called when a task is deleted to delete the task's secure context, + * if it has one. + * + * @param[in] pxTCB The TCB of the task being deleted. + */ + #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) + #endif /* configENABLE_TRUSTZONE */ +/*-----------------------------------------------------------*/ + + #if ( configENABLE_MPU == 1 ) + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + #define portIS_PRIVILEGED() xIsPrivileged() + +/** + * @brief Raise an SVC request to raise privilege. + * + * The SVC handler checks that the SVC was raised from a system call and only + * then it raises the privilege. If this is called from any other place, + * the privilege is not raised. + */ + #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + */ + #define portRESET_PRIVILEGE() vResetPrivilege() + #else + #define portIS_PRIVILEGED() + #define portRAISE_PRIVILEGE() + #define portRESET_PRIVILEGE() + #endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief Barriers. + */ + #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) +/*-----------------------------------------------------------*/ + + #ifdef __cplusplus + } + #endif + +#endif /* PORTMACROCOMMON_H */ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacro.h b/portable/GCC/ARM_CM55/non_secure/portmacro.h index 35c160f3407..adb47d8420f 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacro.h @@ -55,7 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h index 35c160f3407..adb47d8420f 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h @@ -55,7 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM85/non_secure/portmacro.h b/portable/GCC/ARM_CM85/non_secure/portmacro.h index 69d32d7f57a..fec6923394c 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacro.h @@ -55,7 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h index 69d32d7f57a..fec6923394c 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h @@ -55,7 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c new file mode 100644 index 00000000000..9976daee49a --- /dev/null +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -0,0 +1,1261 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/* Portasm includes. */ +#include "portasm.h" + +#if ( configENABLE_TRUSTZONE == 1 ) + /* Secure components includes. */ + #include "secure_context.h" + #include "secure_init.h" +#endif /* configENABLE_TRUSTZONE */ + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/** + * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only + * i.e. the processor boots as secure and never jumps to the non-secure side. + * The Trust Zone support in the port must be disabled in order to run FreeRTOS + * on the secure side. The following are the valid configuration seetings: + * + * 1. Run FreeRTOS on the Secure Side: + * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 + * + * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 + * + * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 + */ +#if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) + #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the NVIC. + */ +#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) +#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) +#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the SCB. + */ +#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) +#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the FPU. + */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR_CP10_VALUE ( 3UL ) +#define portCPACR_CP11_VALUE portCPACR_CP10_VALUE +#define portCPACR_CP10_POS ( 20UL ) +#define portCPACR_CP11_POS ( 22UL ) + +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR_ASPEN_POS ( 31UL ) +#define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) +#define portFPCCR_LSPEN_POS ( 30UL ) +#define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the MPU. + */ +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) + +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) + +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) + +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) + +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) + +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) + +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ + +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) + +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) + +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) + +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) + +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) + +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) + +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) + +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) + +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) + +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) + +/* Enable privileged access to unmapped region. */ +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) + +/* Enable MPU. */ +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) + +/* Expected value of the portMPU_TYPE register. */ +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief The maximum 24-bit number. + * + * It is needed because the systick is a 24-bit counter. + */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/** + * @brief A fiddle factor to estimate the number of SysTick counts that would + * have occurred while the SysTick counter is stopped during tickless idle + * calculations. + */ +#define portMISSED_COUNTS_FACTOR ( 94UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to set up the initial stack. + */ +#define portINITIAL_XPSR ( 0x01000000 ) + +#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ + #define portINITIAL_EXC_RETURN ( 0xfffffffd ) +#else + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ + #define portINITIAL_EXC_RETURN ( 0xffffffbc ) +#endif /* configRUN_FREERTOS_SECURE_ONLY */ + +/** + * @brief CONTROL register privileged bit mask. + * + * Bit[0] in CONTROL register tells the privilege: + * Bit[0] = 0 ==> The task is privileged. + * Bit[0] = 1 ==> The task is not privileged. + */ +#define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) + +/** + * @brief Initial CONTROL register values. + */ +#define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) +#define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) + +/** + * @brief Let the user override the default SysTick clock rate. If defined by the + * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the + * configuration register. + */ +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) +#else + /* Select the option to clock SysTick not at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) +#endif + +/** + * @brief Let the user override the pre-loading of the initial LR with the + * address of prvTaskExitError() in case it messes up unwinding of the stack + * in the debugger. + */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/** + * @brief If portPRELOAD_REGISTERS then registers will be given an initial value + * when a task is created. This helps in debugging at the cost of code size. + */ +#define portPRELOAD_REGISTERS 1 + +/** + * @brief A task is created without a secure context, and must call + * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes + * any secure calls. + */ +#define portNO_SECURE_CONTEXT 0 +/*-----------------------------------------------------------*/ + +/** + * @brief Used to catch tasks that attempt to return from their implementing + * function. + */ +static void prvTaskExitError( void ); + +#if ( configENABLE_MPU == 1 ) + +/** + * @brief Setup the Memory Protection Unit (MPU). + */ + static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_FPU == 1 ) + +/** + * @brief Setup the Floating Point Unit (FPU). + */ + static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_FPU */ + +/** + * @brief Setup the timer to generate the tick interrupts. + * + * The implementation in this file is weak to allow application writers to + * change the timer used to generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether the current execution context is interrupt. + * + * @return pdTRUE if the current execution context is interrupt, pdFALSE + * otherwise. + */ +BaseType_t xPortIsInsideInterrupt( void ); + +/** + * @brief Yield the processor. + */ +void vPortYield( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Enter critical section. + */ +void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Exit from critical section. + */ +void vPortExitCritical( void ) PRIVILEGED_FUNCTION; + +/** + * @brief SysTick handler. + */ +void SysTick_Handler( void ) PRIVILEGED_FUNCTION; + +/** + * @brief C part of SVC handler. + */ +portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +/** + * @brief Each task maintains its own interrupt status in the critical nesting + * variable. + */ +PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; + +#if ( configENABLE_TRUSTZONE == 1 ) + +/** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ + PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; +#endif /* configENABLE_TRUSTZONE */ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + +/** + * @brief The number of SysTick increments that make up one tick period. + */ + PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; + +/** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ + PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; + +/** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ + PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + * method as that will mask interrupts that should exit sleep mode. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* If a context switch is pending or a task is waiting for the scheduler + * to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Re-enable interrupts - see comments above the cpsid instruction + * above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + else + { + /* Stop the SysTick momentarily. The time the SysTick is stopped for + * is accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Use the SysTick current-value register to determine the number of + * SysTick decrements remaining until the next tick interrupt. If the + * current-value register is zero, then there are actually + * ulTimerCountsForOneTick decrements remaining, not zero, because the + * SysTick requests the interrupt when decrementing from 1 to 0. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulTimerCountsForOneTick; + } + + /* Calculate the reload value required to wait xExpectedIdleTime + * tick periods. -1 is used because this code normally executes part + * way through the first tick period. But if the SysTick IRQ is now + * pending, then clear the IRQ, suppressing the first tick, and correct + * the reload value to reflect that the second tick period is already + * underway. The expected idle time is always at least two ticks. */ + ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + + if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) + { + portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; + ulReloadValue -= ulTimerCountsForOneTick; + } + + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + * zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + * set its parameter to 0 to indicate that its implementation contains + * its own wait for interrupt or wait for event instruction, and so wfi + * should not be executed again. However, the original expected idle + * time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + + if( xModifiableIdleTime > 0 ) + { + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "wfi" ); + __asm volatile ( "isb" ); + } + + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Re-enable interrupts to allow the interrupt that brought the MCU + * out of sleep mode to execute immediately. See comments above + * the cpsid instruction above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable interrupts again because the clock is about to be stopped + * and interrupts that execute while the clock is stopped will increase + * any slippage between the time maintained by the RTOS and calendar + * time. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable the SysTick clock without reading the + * portNVIC_SYSTICK_CTRL_REG register to ensure the + * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, + * the time the SysTick is stopped for is accounted for as best it can + * be, but using the tickless mode will inevitably result in some tiny + * drift of the time maintained by the kernel with respect to calendar + * time*/ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Determine whether the SysTick has already counted to zero. */ + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt ended the sleep (or is now pending), and + * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG + * with whatever remains of the new tick period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + * underflowed because the post sleep hook did something + * that took too long or because the SysTick current-value register + * is zero. */ + if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* As the pending tick will be processed as soon as this + * function exits, the tick value maintained by the tick is stepped + * forward by one less than the time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. */ + + /* Use the SysTick current-value register to determine the + * number of SysTick decrements remaining until the expected idle + * time would have ended. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) + { + /* If the SysTick is not using the core clock, the current- + * value register might still be zero here. In that case, the + * SysTick didn't load from the reload register, and there are + * ulReloadValue decrements remaining in the expected idle + * time, not zero. */ + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulReloadValue; + } + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Work out how long the sleep lasted rounded to complete tick + * periods (not the ulReload value which accounted for part + * ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; + + /* How many complete tick periods passed while the processor + * was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + * period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, + * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If + * the SysTick is not using the core clock, temporarily configure it to + * use the core clock. This configuration forces the SysTick to load + * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next + * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready + * to receive the standard value immediately. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) + { + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + #else + { + /* The temporary usage of the core clock has served its purpose, + * as described above. Resume usage of the other clock. */ + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; + + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + /* The partial tick period already ended. Be sure the SysTick + * counts it only once. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; + } + + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Step the tick to account for any tick periods that elapsed. */ + vTaskStepTick( ulCompleteTickPeriods ); + + /* Exit with interrupts enabled. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + } +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if ( configUSE_TICKLESS_IDLE == 1 ) + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Stop and reset the SysTick. */ + portNVIC_SYSTICK_CTRL_REG = 0UL; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + volatile uint32_t ulDummy = 0UL; + + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). Artificially force an assert() + * to be triggered if configASSERT() is defined, then stop here so + * application writers can catch the error. */ + configASSERT( ulCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + + while( ulDummy == 0 ) + { + /* This file calls prvTaskExitError() after the scheduler has been + * started to remove a compiler warning about the function being + * defined but never called. ulDummy is used purely to quieten other + * warnings about code appearing after this function is called - making + * ulDummy volatile makes the compiler think the function could return + * and therefore not output an 'unreachable code' warning for code that + * appears after it. */ + } +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + extern uint32_t * __unprivileged_flash_start__; + extern uint32_t * __unprivileged_flash_end__; + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + #else /* if defined( __ARMCC_VERSION ) */ + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + extern uint32_t __unprivileged_flash_start__[]; + extern uint32_t __unprivileged_flash_end__[]; + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + + /* The only permitted number of regions are 8 or 16. */ + configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); + + /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ + configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + + /* Check that the MPU is present. */ + if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) + { + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; + + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); + } + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* Enable non-secure access to the FPU. */ + SecureInit_EnableNSFPUAccess(); + } + #endif /* configENABLE_TRUSTZONE */ + + /* CP10 = 11 ==> Full access to FPU i.e. both privileged and + * unprivileged code should be able to access FPU. CP11 should be + * programmed to the same value as CP10. */ + *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | + ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) + ); + + /* ASPEN = 1 ==> Hardware should automatically preserve floating point + * context on exception entry and restore on exception return. + * LSPEN = 1 ==> Enable lazy context save of FP state. */ + *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); + } +#endif /* configENABLE_FPU */ +/*-----------------------------------------------------------*/ + +void vPortYield( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + portDISABLE_INTERRUPTS(); + ulCriticalNesting++; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + configASSERT( ulCriticalNesting ); + ulCriticalNesting--; + + if( ulCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulPreviousMask; + + ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ +{ + #if ( configENABLE_MPU == 1 ) + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + #endif /* configENABLE_MPU */ + + uint32_t ulPC; + + #if ( configENABLE_TRUSTZONE == 1 ) + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; + #if ( configENABLE_MPU == 1 ) + uint32_t ulControl, ulIsTaskPrivileged; + #endif /* configENABLE_MPU */ + #endif /* configENABLE_TRUSTZONE */ + uint8_t ucSVCNumber; + + /* Register are stored on the stack in the following order - R0, R1, R2, R3, + * R12, LR, PC, xPSR. */ + ulPC = pulCallerStackAddress[ 6 ]; + ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; + + switch( ucSVCNumber ) + { + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: + + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; + + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ + + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; + + case portSVC_FREE_SECURE_CONTEXT: + + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; + + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ + + case portSVC_START_SCHEDULER: + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* De-prioritize the non-secure exceptions so that the + * non-secure pendSV runs at the lowest priority. */ + SecureInit_DePrioritizeNSExceptions(); + + /* Initialize the secure context management system. */ + SecureContext_Init(); + } + #endif /* configENABLE_TRUSTZONE */ + + #if ( configENABLE_FPU == 1 ) + { + /* Setup the Floating Point Unit (FPU). */ + prvSetupFPU(); + } + #endif /* configENABLE_FPU */ + + /* Setup the context of the first task so that the first task starts + * executing. */ + vRestoreContextOfFirstTask(); + break; + + #if ( configENABLE_MPU == 1 ) + case portSVC_RAISE_PRIVILEGE: + + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* configENABLE_MPU */ + + default: + /* Incorrect SVC call. */ + configASSERT( pdFALSE ); + } +} +/*-----------------------------------------------------------*/ +/* *INDENT-OFF* */ +#if ( configENABLE_MPU == 1 ) + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ +#else + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +#endif /* configENABLE_MPU */ +/* *INDENT-ON* */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; + + #if ( configENABLE_MPU == 1 ) + { + pxTopOfStack--; + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + } + #endif /* configENABLE_MPU */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + + #if ( configENABLE_TRUSTZONE == 1 ) + { + pxTopOfStack--; + *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ + } + #endif /* configENABLE_TRUSTZONE */ + } + #else /* portPRELOAD_REGISTERS */ + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ + + #if ( configENABLE_MPU == 1 ) + { + pxTopOfStack--; + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + } + #endif /* configENABLE_MPU */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + + #if ( configENABLE_TRUSTZONE == 1 ) + { + pxTopOfStack--; + *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ + } + #endif /* configENABLE_TRUSTZONE */ + } + #endif /* portPRELOAD_REGISTERS */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ + portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; + portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; + + #if ( configENABLE_MPU == 1 ) + { + /* Setup the Memory Protection Unit (MPU). */ + prvSetupMPU(); + } + #endif /* configENABLE_MPU */ + + /* Start the timer that generates the tick ISR. Interrupts are disabled + * here already. */ + vPortSetupTimerInterrupt(); + + /* Initialize the critical nesting count ready for the first task. */ + ulCriticalNesting = 0; + + /* Start the first task. */ + vStartFirstTask(); + + /* Should never get here as the tasks will now be executing. Call the task + * exit error function to prevent compiler warnings about a static function + * not being called in the case that the application writer overrides this + * functionality by defining configTASK_RETURN_ADDRESS. Call + * vTaskSwitchContext() so link time optimization does not remove the + * symbol. */ + vTaskSwitchContext(); + prvTaskExitError(); + + /* Should not get here. */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( ulCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) + { + uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; + int32_t lIndex = 0; + + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + + /* Setup MAIR0. */ + xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + + /* This function is called automatically when the task is created - in + * which case the stack region parameters will be valid. At all other + * times the stack parameters will not be valid and it is assumed that + * the stack region has already been configured. */ + if( ulStackDepth > 0 ) + { + ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + + /* If the stack is within the privileged SRAM, do not protect it + * using a separate MPU region. This is needed because privileged + * SRAM is already protected using an MPU region and ARMv8-M does + * not allow overlapping MPU regions. */ + if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && + ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) + { + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; + xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; + } + else + { + /* Define the region that allows access to the stack. */ + ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; + ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; + + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + + xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + } + } + + /* User supplied configurable regions. */ + for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) + { + /* If xRegions is NULL i.e. the task has not specified any MPU + * region, the else part ensures that all the configurable MPU + * regions are invalidated. */ + if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) + { + /* Translate the generic region definition contained in xRegions + * into the ARMv8 specific MPU settings that are then stored in + * xMPUSettings. */ + ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; + ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; + ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; + + /* Start address. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | + ( portMPU_REGION_NON_SHAREABLE ); + + /* RO/RW. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); + } + else + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); + } + + /* XN. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); + } + + /* End Address. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Normal memory/ Device memory. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) + { + /* Attr1 in MAIR0 is configured as device memory. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; + } + else + { + /* Attr0 in MAIR0 is configured as normal memory. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; + } + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; + } + + lIndex++; + } + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. Interrupt Program + * Status Register (IPSR) holds the exception number of the currently-executing + * exception or zero for Thread mode.*/ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.h b/portable/IAR/ARM_CM35P/non_secure/portasm.h new file mode 100644 index 00000000000..ecd86b97fd1 --- /dev/null +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.h @@ -0,0 +1,114 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __PORT_ASM_H__ +#define __PORT_ASM_H__ + +/* Scheduler includes. */ +#include "FreeRTOS.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ +void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ +BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + +/** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kenrel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vResetPrivilege( void ) __attribute__( ( naked ) ); + +/** + * @brief Starts the first task. + */ +void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Disables interrupts. + */ +uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Enables interrupts. + */ +void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief PendSV Exception handler. + */ +void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief SVC Handler. + */ +void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ +void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + +/** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ +void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +#endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.s b/portable/IAR/ARM_CM35P/non_secure/portasm.s new file mode 100644 index 00000000000..a193cd7b80e --- /dev/null +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.s @@ -0,0 +1,353 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + + EXTERN pxCurrentTCB + EXTERN xSecureContext + EXTERN vTaskSwitchContext + EXTERN vPortSVCHandler_C + EXTERN SecureContext_SaveContext + EXTERN SecureContext_LoadContext + + PUBLIC xIsPrivileged + PUBLIC vResetPrivilege + PUBLIC vPortAllocateSecureContext + PUBLIC vRestoreContextOfFirstTask + PUBLIC vRaisePrivilege + PUBLIC vStartFirstTask + PUBLIC ulSetInterruptMask + PUBLIC vClearInterruptMask + PUBLIC PendSV_Handler + PUBLIC SVC_Handler + PUBLIC vPortFreeSecureContext +/*-----------------------------------------------------------*/ + +/*---------------- Unprivileged Functions -------------------*/ + +/*-----------------------------------------------------------*/ + + SECTION .text:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +xIsPrivileged: + mrs r0, control /* r0 = CONTROL. */ + tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ + ite ne + movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ + moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ + bx lr /* Return. */ +/*-----------------------------------------------------------*/ + +vResetPrivilege: + mrs r0, control /* r0 = CONTROL. */ + orr r0, r0, #1 /* r0 = r0 | 1. */ + msr control, r0 /* CONTROL = r0. */ + bx lr /* Return to the caller. */ +/*-----------------------------------------------------------*/ + +vPortAllocateSecureContext: + svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ + bx lr /* Return. */ +/*-----------------------------------------------------------*/ + +/*----------------- Privileged Functions --------------------*/ + +/*-----------------------------------------------------------*/ + + SECTION privileged_functions:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +vRestoreContextOfFirstTask: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r3, [r2] /* Read pxCurrentTCB. */ + ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + +#if ( configENABLE_MPU == 1 ) + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r2] /* Read the value of MPU_CTRL. */ + bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + str r4, [r2] /* Disable MPU. */ + + adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ + ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r4, [r2] /* Program MAIR0. */ + ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ + movs r4, #4 /* r4 = 4. */ + str r4, [r2] /* Program RNR = 4. */ + adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r2] /* Read the value of MPU_CTRL. */ + orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + str r4, [r2] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ + ldr r5, =xSecureContext + str r1, [r5] /* Set xSecureContext to this task's value for the same. */ + msr psplim, r2 /* Set this task's PSPLIM value. */ + msr control, r3 /* Set this task's CONTROL value. */ + adds r0, #32 /* Discard everything up to r0. */ + msr psp, r0 /* This is now the new top of stack to use in the task. */ + isb + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx r4 /* Finally, branch to EXC_RETURN. */ +#else /* configENABLE_MPU */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + ldr r4, =xSecureContext + str r1, [r4] /* Set xSecureContext to this task's value for the same. */ + msr psplim, r2 /* Set this task's PSPLIM value. */ + movs r1, #2 /* r1 = 2. */ + msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + adds r0, #32 /* Discard everything up to r0. */ + msr psp, r0 /* This is now the new top of stack to use in the task. */ + isb + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx r3 /* Finally, branch to EXC_RETURN. */ +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +vRaisePrivilege: + mrs r0, control /* Read the CONTROL register. */ + bic r0, r0, #1 /* Clear the bit 0. */ + msr control, r0 /* Write back the new CONTROL value. */ + bx lr /* Return to the caller. */ +/*-----------------------------------------------------------*/ + +vStartFirstTask: + ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ + ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ + ldr r0, [r0] /* The first entry in vector table is stack pointer. */ + msr msp, r0 /* Set the MSP back to the start of the stack. */ + cpsie i /* Globally enable interrupts. */ + cpsie f + dsb + isb + svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ +/*-----------------------------------------------------------*/ + +ulSetInterruptMask: + mrs r0, basepri /* r0 = basepri. Return original basepri value. */ + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bx lr /* Return. */ +/*-----------------------------------------------------------*/ + +vClearInterruptMask: + msr basepri, r0 /* basepri = ulMask. */ + dsb + isb + bx lr /* Return. */ +/*-----------------------------------------------------------*/ + +PendSV_Handler: + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + mrs r2, psp /* Read PSP in r2. */ + + cbz r0, save_ns_context /* No secure context to save. */ + push {r0-r2, r14} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r3} /* LR is now in r3. */ + mov lr, r3 /* LR = r3. */ + lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ +#if ( configENABLE_MPU == 1 ) + subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ + mrs r3, control /* r3 = CONTROL. */ + mov r4, lr /* r4 = LR/EXC_RETURN. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ +#else /* configENABLE_MPU */ + subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ + mov r3, lr /* r3 = LR/EXC_RETURN. */ + stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ +#endif /* configENABLE_MPU */ + b select_next_task + + save_ns_context: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + it eq + vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( configENABLE_MPU == 1 ) + subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + adds r2, r2, #16 /* r2 = r2 + 16. */ + stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + mrs r1, psplim /* r1 = PSPLIM. */ + mrs r3, control /* r3 = CONTROL. */ + mov r4, lr /* r4 = LR/EXC_RETURN. */ + subs r2, r2, #16 /* r2 = r2 - 16. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + #else /* configENABLE_MPU */ + subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + adds r2, r2, #12 /* r2 = r2 + 12. */ + stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + mrs r1, psplim /* r1 = PSPLIM. */ + mov r3, lr /* r3 = LR/EXC_RETURN. */ + subs r2, r2, #12 /* r2 = r2 - 12. */ + stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #endif /* configENABLE_MPU */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + + #if ( configENABLE_MPU == 1 ) + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ + bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + str r4, [r3] /* Disable MPU. */ + + adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ + ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ + str r4, [r3] /* Program MAIR0. */ + ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ + movs r4, #4 /* r4 = 4. */ + str r4, [r3] /* Program RNR = 4. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ + orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + str r4, [r3] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + #endif /* configENABLE_MPU */ + + #if ( configENABLE_MPU == 1 ) + ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ + msr control, r3 /* Restore the CONTROL register value for the task. */ + mov lr, r4 /* LR = r4. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ + cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} + mov lr, r4 /* LR = r4. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ + bx lr + #else /* configENABLE_MPU */ + ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ + mov lr, r4 /* LR = r4. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ + cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} + mov lr, r4 /* LR = r4. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ + bx lr + #endif /* configENABLE_MPU */ + + restore_ns_context: + ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + it eq + vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + msr psp, r2 /* Remember the new top of stack for the task. */ + bx lr +/*-----------------------------------------------------------*/ + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b vPortSVCHandler_C +/*-----------------------------------------------------------*/ + +vPortFreeSecureContext: + /* r0 = uint32_t *pulTCB. */ + ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ + ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ + it ne + svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ + bx lr /* Return. */ +/*-----------------------------------------------------------*/ + + END diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacro.h b/portable/IAR/ARM_CM35P/non_secure/portmacro.h new file mode 100644 index 00000000000..a0efc1f9dcf --- /dev/null +++ b/portable/IAR/ARM_CM35P/non_secure/portmacro.h @@ -0,0 +1,78 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "portmacrocommon.h" + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + +/** + * Architecture specifics. + */ +#define portARCH_NAME "Cortex-M35P" +#define portDONT_DISCARD __root +/*-----------------------------------------------------------*/ + +#if( configTOTAL_MPU_REGIONS == 16 ) + #error 16 MPU regions are not yet supported for this port. +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ +#define portDISABLE_INTERRUPTS() ulSetInterruptMask() +#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) +/*-----------------------------------------------------------*/ + +/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in + * the source code because to do so would cause other compilers to generate + * warnings. */ +#pragma diag_suppress=Be006 +#pragma diag_suppress=Pa082 +/*-----------------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif /* PORTMACRO_H */ diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h new file mode 100644 index 00000000000..ca7e9225c05 --- /dev/null +++ b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h @@ -0,0 +1,313 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACROCOMMON_H + #define PORTMACROCOMMON_H + + #ifdef __cplusplus + extern "C" { + #endif + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + + #ifndef configENABLE_FPU + #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. + #endif /* configENABLE_FPU */ + + #ifndef configENABLE_MPU + #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. + #endif /* configENABLE_MPU */ + + #ifndef configENABLE_TRUSTZONE + #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. + #endif /* configENABLE_TRUSTZONE */ + +/*-----------------------------------------------------------*/ + +/** + * @brief Type definitions. + */ + #define portCHAR char + #define portFLOAT float + #define portDOUBLE double + #define portLONG long + #define portSHORT short + #define portSTACK_TYPE uint32_t + #define portBASE_TYPE long + + typedef portSTACK_TYPE StackType_t; + typedef long BaseType_t; + typedef unsigned long UBaseType_t; + + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + * not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. + #endif +/*-----------------------------------------------------------*/ + +/** + * Architecture specifics. + */ + #define portSTACK_GROWTH ( -1 ) + #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + #define portBYTE_ALIGNMENT 8 + #define portNOP() + #define portINLINE __inline + #ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) + #endif + #define portHAS_STACK_OVERFLOW_CHECKING 1 +/*-----------------------------------------------------------*/ + +/** + * @brief Extern declarations. + */ + extern BaseType_t xPortIsInsideInterrupt( void ); + + extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; + + extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; + extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; + + extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + + #if ( configENABLE_TRUSTZONE == 1 ) + extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ + extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; + #endif /* configENABLE_TRUSTZONE */ + + #if ( configENABLE_MPU == 1 ) + extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; + extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; + #endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief MPU specific constants. + */ + #if ( configENABLE_MPU == 1 ) + #define portUSING_MPU_WRAPPERS 1 + #define portPRIVILEGE_BIT ( 0x80000000UL ) + #else + #define portPRIVILEGE_BIT ( 0x0UL ) + #endif /* configENABLE_MPU */ + +/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +#ifndef configTOTAL_MPU_REGIONS + /* Define to 8 for backward compatibility. */ + #define configTOTAL_MPU_REGIONS ( 8UL ) +#endif + +/* MPU regions. */ + #define portPRIVILEGED_FLASH_REGION ( 0UL ) + #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) + #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) + #define portPRIVILEGED_RAM_REGION ( 3UL ) + #define portSTACK_REGION ( 4UL ) + #define portFIRST_CONFIGURABLE_REGION ( 5UL ) + #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) + #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) + #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +/* Device memory attributes used in MPU_MAIR registers. + * + * 8-bit values encoded as follows: + * Bit[7:4] - 0000 - Device Memory + * Bit[3:2] - 00 --> Device-nGnRnE + * 01 --> Device-nGnRE + * 10 --> Device-nGRE + * 11 --> Device-GRE + * Bit[1:0] - 00, Reserved. + */ + #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ + #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ + #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ + #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ + +/* Normal memory attributes used in MPU_MAIR registers. */ + #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ + #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ + +/* Attributes used in MPU_RBAR registers. */ + #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) + #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) + #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) + + #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) + #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) + #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) + #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) + + #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + +/** + * @brief MPU settings as stored in the TCB. + */ + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + } xMPU_SETTINGS; +/*-----------------------------------------------------------*/ + +/** + * @brief SVC numbers. + */ + #define portSVC_ALLOCATE_SECURE_CONTEXT 0 + #define portSVC_FREE_SECURE_CONTEXT 1 + #define portSVC_START_SCHEDULER 2 + #define portSVC_RAISE_PRIVILEGE 3 +/*-----------------------------------------------------------*/ + +/** + * @brief Scheduler utilities. + */ + #define portYIELD() vPortYield() + #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) + #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) + #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) + #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ + #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) + #define portENTER_CRITICAL() vPortEnterCritical() + #define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/** + * @brief Tickless idle/low power functionality. + */ + #ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) + #endif +/*-----------------------------------------------------------*/ + +/** + * @brief Task function macros as described on the FreeRTOS.org WEB site. + */ + #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) + #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +/*-----------------------------------------------------------*/ + + #if ( configENABLE_TRUSTZONE == 1 ) + +/** + * @brief Allocate a secure context for the task. + * + * Tasks are not created with a secure context. Any task that is going to call + * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a + * secure context before it calls any secure function. + * + * @param[in] ulSecureStackSize The size of the secure stack to be allocated. + */ + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) + +/** + * @brief Called when a task is deleted to delete the task's secure context, + * if it has one. + * + * @param[in] pxTCB The TCB of the task being deleted. + */ + #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) + #endif /* configENABLE_TRUSTZONE */ +/*-----------------------------------------------------------*/ + + #if ( configENABLE_MPU == 1 ) + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + #define portIS_PRIVILEGED() xIsPrivileged() + +/** + * @brief Raise an SVC request to raise privilege. + * + * The SVC handler checks that the SVC was raised from a system call and only + * then it raises the privilege. If this is called from any other place, + * the privilege is not raised. + */ + #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + */ + #define portRESET_PRIVILEGE() vResetPrivilege() + #else + #define portIS_PRIVILEGED() + #define portRAISE_PRIVILEGE() + #define portRESET_PRIVILEGE() + #endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief Barriers. + */ + #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) +/*-----------------------------------------------------------*/ + + #ifdef __cplusplus + } + #endif + +#endif /* PORTMACROCOMMON_H */ diff --git a/portable/IAR/ARM_CM35P/secure/secure_context.c b/portable/IAR/ARM_CM35P/secure/secure_context.c new file mode 100644 index 00000000000..0730d574dd0 --- /dev/null +++ b/portable/IAR/ARM_CM35P/secure/secure_context.c @@ -0,0 +1,351 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Secure context includes. */ +#include "secure_context.h" + +/* Secure heap includes. */ +#include "secure_heap.h" + +/* Secure port macros. */ +#include "secure_port_macros.h" + +/** + * @brief CONTROL value for privileged tasks. + * + * Bit[0] - 0 --> Thread mode is privileged. + * Bit[1] - 1 --> Thread mode uses PSP. + */ +#define securecontextCONTROL_VALUE_PRIVILEGED 0x02 + +/** + * @brief CONTROL value for un-privileged tasks. + * + * Bit[0] - 1 --> Thread mode is un-privileged. + * Bit[1] - 1 --> Thread mode uses PSP. + */ +#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 + +/** + * @brief Size of stack seal values in bytes. + */ +#define securecontextSTACK_SEAL_SIZE 8 + +/** + * @brief Stack seal value as recommended by ARM. + */ +#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 + +/** + * @brief Maximum number of secure contexts. + */ +#ifndef secureconfigMAX_SECURE_CONTEXTS + #define secureconfigMAX_SECURE_CONTEXTS 8UL +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Pre-allocated array of secure contexts. + */ +SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; +/*-----------------------------------------------------------*/ + +/** + * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). + * + * This function ensures that only one secure context is allocated for a task. + * + * @param[in] pvTaskHandle The task handle for which the secure context is allocated. + * + * @return Index of a free secure context in the xSecureContexts array. + */ +static uint32_t ulGetSecureContext( void * pvTaskHandle ); + +/** + * @brief Return the secure context to the secure context pool (xSecureContexts). + * + * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. + */ +static void vReturnSecureContext( uint32_t ulSecureContextIndex ); + +/* These are implemented in assembly. */ +extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); +extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); +/*-----------------------------------------------------------*/ + +static uint32_t ulGetSecureContext( void * pvTaskHandle ) +{ + /* Start with invalid index. */ + uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; + + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) + { + if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && + ( xSecureContexts[ i ].pucStackLimit == NULL ) && + ( xSecureContexts[ i ].pucStackStart == NULL ) && + ( xSecureContexts[ i ].pvTaskHandle == NULL ) && + ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) + { + ulSecureContextIndex = i; + } + else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) + { + /* A task can only have one secure context. Do not allocate a second + * context for the same task. */ + ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; + break; + } + } + + return ulSecureContextIndex; +} +/*-----------------------------------------------------------*/ + +static void vReturnSecureContext( uint32_t ulSecureContextIndex ) +{ + xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; + xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; + xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) +{ + uint32_t ulIPSR, i; + static uint32_t ulSecureContextsInitialized = 0; + + /* Read the Interrupt Program Status Register (IPSR) value. */ + secureportREAD_IPSR( ulIPSR ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. */ + if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) + { + /* Ensure to initialize secure contexts only once. */ + ulSecureContextsInitialized = 1; + + /* No stack for thread mode until a task's context is loaded. */ + secureportSET_PSPLIM( securecontextNO_STACK ); + secureportSET_PSP( securecontextNO_STACK ); + + /* Initialize all secure contexts. */ + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) + { + xSecureContexts[ i ].pucCurrentStackPointer = NULL; + xSecureContexts[ i ].pucStackLimit = NULL; + xSecureContexts[ i ].pucStackStart = NULL; + xSecureContexts[ i ].pvTaskHandle = NULL; + } + + #if ( configENABLE_MPU == 1 ) + { + /* Configure thread mode to use PSP and to be unprivileged. */ + secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); + } + #else /* configENABLE_MPU */ + { + /* Configure thread mode to use PSP and to be privileged. */ + secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); + } + #endif /* configENABLE_MPU */ + } +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ) +#else /* configENABLE_MPU */ + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ) +#endif /* configENABLE_MPU */ +{ + uint8_t * pucStackMemory = NULL; + uint8_t * pucStackLimit; + uint32_t ulIPSR, ulSecureContextIndex; + SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; + + #if ( configENABLE_MPU == 1 ) + uint32_t * pulCurrentStackPointer = NULL; + #endif /* configENABLE_MPU */ + + /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit + * Register (PSPLIM) value. */ + secureportREAD_IPSR( ulIPSR ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. + * Also do nothing, if a secure context us already loaded. PSPLIM is set to + * securecontextNO_STACK when no secure context is loaded. */ + if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) + { + /* Ontain a free secure context. */ + ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); + + /* Were we able to get a free context? */ + if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) + { + /* Allocate the stack space. */ + pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); + + if( pucStackMemory != NULL ) + { + /* Since stack grows down, the starting point will be the last + * location. Note that this location is next to the last + * allocated byte for stack (excluding the space for seal values) + * because the hardware decrements the stack pointer before + * writing i.e. if stack pointer is 0x2, a push operation will + * decrement the stack pointer to 0x1 and then write at 0x1. */ + xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; + + /* Seal the created secure process stack. */ + *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; + *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; + + /* The stack cannot go beyond this location. This value is + * programmed in the PSPLIM register on context switch.*/ + xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; + + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; + + #if ( configENABLE_MPU == 1 ) + { + /* Store the correct CONTROL value for the task on the stack. + * This value is programmed in the CONTROL register on + * context switch. */ + pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart; + pulCurrentStackPointer--; + + if( ulIsTaskPrivileged ) + { + *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED; + } + else + { + *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED; + } + + /* Store the current stack pointer. This value is programmed in + * the PSP register on context switch. */ + xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer; + } + #else /* configENABLE_MPU */ + { + /* Current SP is set to the starting of the stack. This + * value programmed in the PSP register on context switch. */ + xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; + } + #endif /* configENABLE_MPU */ + + /* Ensure to never return 0 as a valid context handle. */ + xSecureContextHandle = ulSecureContextIndex + 1UL; + } + } + } + + return xSecureContextHandle; +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) +{ + uint32_t ulIPSR, ulSecureContextIndex; + + /* Read the Interrupt Program Status Register (IPSR) value. */ + secureportREAD_IPSR( ulIPSR ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. */ + if( ulIPSR != 0 ) + { + /* Only free if a valid context handle is passed. */ + if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) + { + ulSecureContextIndex = xSecureContextHandle - 1UL; + + /* Ensure that the secure context being deleted is associated with + * the task. */ + if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) + { + /* Free the stack space. */ + vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); + + /* Return the secure context back to the free secure contexts pool. */ + vReturnSecureContext( ulSecureContextIndex ); + } + } + } +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) +{ + uint8_t * pucStackLimit; + uint32_t ulSecureContextIndex; + + if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) + { + ulSecureContextIndex = xSecureContextHandle - 1UL; + + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that no secure context is loaded and the task is loading it's + * own context. */ + if( ( pucStackLimit == securecontextNO_STACK ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } + } +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) +{ + uint8_t * pucStackLimit; + uint32_t ulSecureContextIndex; + + if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) + { + ulSecureContextIndex = xSecureContextHandle - 1UL; + + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that task's context is loaded and the task is saving it's own + * context. */ + if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } + } +} +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/secure/secure_context.h b/portable/IAR/ARM_CM35P/secure/secure_context.h new file mode 100644 index 00000000000..d0adbaf018f --- /dev/null +++ b/portable/IAR/ARM_CM35P/secure/secure_context.h @@ -0,0 +1,135 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __SECURE_CONTEXT_H__ +#define __SECURE_CONTEXT_H__ + +/* Standard includes. */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOSConfig.h" + +/** + * @brief PSP value when no secure context is loaded. + */ +#define securecontextNO_STACK 0x0 + +/** + * @brief Invalid context ID. + */ +#define securecontextINVALID_CONTEXT_ID 0UL +/*-----------------------------------------------------------*/ + +/** + * @brief Structure to represent a secure context. + * + * @note Since stack grows down, pucStackStart is the highest address while + * pucStackLimit is the first address of the allocated memory. + */ +typedef struct SecureContext +{ + uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ + uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ + uint8_t * pucStackStart; /**< First location of the stack memory. */ + void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ +} SecureContext_t; +/*-----------------------------------------------------------*/ + +/** + * @brief Opaque handle for a secure context. + */ +typedef uint32_t SecureContextHandle_t; +/*-----------------------------------------------------------*/ + +/** + * @brief Initializes the secure context management system. + * + * PSP is set to NULL and therefore a task must allocate and load a context + * before calling any secure side function in the thread mode. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + */ +void SecureContext_Init( void ); + +/** + * @brief Allocates a context on the secure side. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + * + * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. + * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. + * + * @return Opaque context handle if context is successfully allocated, NULL + * otherwise. + */ +#if ( configENABLE_MPU == 1 ) + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ); +#else /* configENABLE_MPU */ + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ); +#endif /* configENABLE_MPU */ + +/** + * @brief Frees the given context. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + * + * @param[in] xSecureContextHandle Context handle corresponding to the + * context to be freed. + */ +void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); + +/** + * @brief Loads the given context. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + * + * @param[in] xSecureContextHandle Context handle corresponding to the context + * to be loaded. + */ +void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); + +/** + * @brief Saves the given context. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + * + * @param[in] xSecureContextHandle Context handle corresponding to the context + * to be saved. + */ +void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); + +#endif /* __SECURE_CONTEXT_H__ */ diff --git a/portable/IAR/ARM_CM35P/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM35P/secure/secure_context_port_asm.s new file mode 100644 index 00000000000..400bd0107a3 --- /dev/null +++ b/portable/IAR/ARM_CM35P/secure/secure_context_port_asm.s @@ -0,0 +1,86 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + + SECTION .text:CODE:NOROOT(2) + THUMB + +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + + PUBLIC SecureContext_LoadContextAsm + PUBLIC SecureContext_SaveContextAsm +/*-----------------------------------------------------------*/ + +SecureContext_LoadContextAsm: + /* pxSecureContext value is in r0. */ + mrs r1, ipsr /* r1 = IPSR. */ + cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ + ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ + +#if ( configENABLE_MPU == 1 ) + ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ + msr control, r3 /* CONTROL = r3. */ +#endif /* configENABLE_MPU */ + + msr psplim, r2 /* PSPLIM = r2. */ + msr psp, r1 /* PSP = r1. */ + + load_ctx_therad_mode: + bx lr +/*-----------------------------------------------------------*/ + +SecureContext_SaveContextAsm: + /* pxSecureContext value is in r0. */ + mrs r1, ipsr /* r1 = IPSR. */ + cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ + mrs r1, psp /* r1 = PSP. */ + +#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + vstmdb r1!, {s0} /* Trigger the deferred stacking of FPU registers. */ + vldmia r1!, {s0} /* Nullify the effect of the previous statement. */ +#endif /* configENABLE_FPU || configENABLE_MVE */ + +#if ( configENABLE_MPU == 1 ) + mrs r2, control /* r2 = CONTROL. */ + stmdb r1!, {r2} /* Store CONTROL value on the stack. */ +#endif /* configENABLE_MPU */ + + str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ + movs r1, #0 /* r1 = securecontextNO_STACK. */ + msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ + msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ + + save_ctx_therad_mode: + bx lr +/*-----------------------------------------------------------*/ + + END diff --git a/portable/IAR/ARM_CM35P/secure/secure_heap.c b/portable/IAR/ARM_CM35P/secure/secure_heap.c new file mode 100644 index 00000000000..157fdbf0eec --- /dev/null +++ b/portable/IAR/ARM_CM35P/secure/secure_heap.c @@ -0,0 +1,454 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Standard includes. */ +#include + +/* Secure context heap includes. */ +#include "secure_heap.h" + +/* Secure port macros. */ +#include "secure_port_macros.h" + +/** + * @brief Total heap size. + */ +#ifndef secureconfigTOTAL_HEAP_SIZE + #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) +#endif + +/* No test marker by default. */ +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +/* No tracing by default. */ +#ifndef traceMALLOC + #define traceMALLOC( pvReturn, xWantedSize ) +#endif + +/* No tracing by default. */ +#ifndef traceFREE + #define traceFREE( pv, xBlockSize ) +#endif + +/* Block sizes must not get too small. */ +#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) +/*-----------------------------------------------------------*/ + +/* Allocate the memory for the heap. */ +#if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) + +/* The application writer has already defined the array used for the RTOS +* heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; +#else /* configAPPLICATION_ALLOCATED_HEAP */ + static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/** + * @brief The linked list structure. + * + * This is used to link free blocks in order of their memory address. + */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ + size_t xBlockSize; /**< The size of the free block. */ +} BlockLink_t; +/*-----------------------------------------------------------*/ + +/** + * @brief Called automatically to setup the required heap structures the first + * time pvPortMalloc() is called. + */ +static void prvHeapInit( void ); + +/** + * @brief Inserts a block of memory that is being freed into the correct + * position in the list of free memory blocks. + * + * The block being freed will be merged with the block in front it and/or the + * block behind it if the memory blocks are adjacent to each other. + * + * @param[in] pxBlockToInsert The block being freed. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); +/*-----------------------------------------------------------*/ + +/** + * @brief The size of the structure placed at the beginning of each allocated + * memory block must by correctly byte aligned. + */ +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); + +/** + * @brief Create a couple of list links to mark the start and end of the list. + */ +static BlockLink_t xStart; +static BlockLink_t * pxEnd = NULL; + +/** + * @brief Keeps track of the number of free bytes remaining, but says nothing + * about fragmentation. + */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/** + * @brief Gets set to the top bit of an size_t type. + * + * When this bit in the xBlockSize member of an BlockLink_t structure is set + * then the block belongs to the application. When the bit is free the block is + * still part of the free heap space. + */ +static size_t xBlockAllocatedBit = 0; +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ + BlockLink_t * pxFirstFreeBlock; + uint8_t * pucAlignedHeap; + size_t uxAddress; + size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; + + /* Ensure the heap starts on a correctly aligned boundary. */ + uxAddress = ( size_t ) ucHeap; + + if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) + { + uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); + uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); + xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; + } + + pucAlignedHeap = ( uint8_t * ) uxAddress; + + /* xStart is used to hold a pointer to the first item in the list of free + * blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + * at the end of the heap space. */ + uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; + uxAddress -= xHeapStructSize; + uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); + pxEnd = ( void * ) uxAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + * entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* Only one block exists - and it covers the entire usable heap space. */ + xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) +{ + BlockLink_t * pxIterator; + uint8_t * puc; + + /* Iterate through the list until a block is found that has a higher address + * than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + * make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + * make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + * before and the block after, then it's pxNextFreeBlock pointer will have + * already been set, and should not be set here as that would make it point + * to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +void * pvPortMalloc( size_t xWantedSize ) +{ + BlockLink_t * pxBlock; + BlockLink_t * pxPreviousBlock; + BlockLink_t * pxNewBlockLink; + void * pvReturn = NULL; + + /* If this is the first call to malloc then the heap will require + * initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Check the requested block size is not so large that the top bit is set. + * The top bit of the block size member of the BlockLink_t structure is used + * to determine who owns the block - the application or the kernel, so it + * must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + * structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number of + * bytes. */ + if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); + secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + * one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size was + * not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + * BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + * of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + * two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + * block following the number of bytes requested. The void + * cast is used to prevent byte alignment warnings from the + * compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); + + /* Calculate the sizes of two blocks split from the single + * block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( pxNewBlockLink ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned by + * the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + + #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ + + secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void * pv ) +{ + uint8_t * puc = ( uint8_t * ) pv; + BlockLink_t * pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + * before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + secureportASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + * allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + secureportDISABLE_NON_SECURE_INTERRUPTS(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + secureportENABLE_NON_SECURE_INTERRUPTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/secure/secure_heap.h b/portable/IAR/ARM_CM35P/secure/secure_heap.h new file mode 100644 index 00000000000..c13590f86ad --- /dev/null +++ b/portable/IAR/ARM_CM35P/secure/secure_heap.h @@ -0,0 +1,66 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __SECURE_HEAP_H__ +#define __SECURE_HEAP_H__ + +/* Standard includes. */ +#include + +/** + * @brief Allocates memory from heap. + * + * @param[in] xWantedSize The size of the memory to be allocated. + * + * @return Pointer to the memory region if the allocation is successful, NULL + * otherwise. + */ +void * pvPortMalloc( size_t xWantedSize ); + +/** + * @brief Frees the previously allocated memory. + * + * @param[in] pv Pointer to the memory to be freed. + */ +void vPortFree( void * pv ); + +/** + * @brief Get the free heap size. + * + * @return Free heap size. + */ +size_t xPortGetFreeHeapSize( void ); + +/** + * @brief Get the minimum ever free heap size. + * + * @return Minimum ever free heap size. + */ +size_t xPortGetMinimumEverFreeHeapSize( void ); + +#endif /* __SECURE_HEAP_H__ */ diff --git a/portable/IAR/ARM_CM35P/secure/secure_init.c b/portable/IAR/ARM_CM35P/secure/secure_init.c new file mode 100644 index 00000000000..dc19ebc7d5e --- /dev/null +++ b/portable/IAR/ARM_CM35P/secure/secure_init.c @@ -0,0 +1,106 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Standard includes. */ +#include + +/* Secure init includes. */ +#include "secure_init.h" + +/* Secure port macros. */ +#include "secure_port_macros.h" + +/** + * @brief Constants required to manipulate the SCB. + */ +#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ +#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) +#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) +#define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) +#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) + +/** + * @brief Constants required to manipulate the FPU. + */ +#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define secureinitFPCCR_LSPENS_POS ( 29UL ) +#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) +#define secureinitFPCCR_TS_POS ( 26UL ) +#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) + +#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ +#define secureinitNSACR_CP10_POS ( 10UL ) +#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) +#define secureinitNSACR_CP11_POS ( 11UL ) +#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) +{ + uint32_t ulIPSR; + + /* Read the Interrupt Program Status Register (IPSR) value. */ + secureportREAD_IPSR( ulIPSR ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. */ + if( ulIPSR != 0 ) + { + *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | + ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | + ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); + } +} +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) +{ + uint32_t ulIPSR; + + /* Read the Interrupt Program Status Register (IPSR) value. */ + secureportREAD_IPSR( ulIPSR ); + + /* Do nothing if the processor is running in the Thread Mode. IPSR is zero + * when the processor is running in the Thread Mode. */ + if( ulIPSR != 0 ) + { + /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is + * permitted. CP11 should be programmed to the same value as CP10. */ + *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); + + /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures + * that we can enable/disable lazy stacking in port.c file. */ + *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); + + /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP + * registers (S16-S31) are also pushed to stack on exception entry and + * restored on exception return. */ + *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); + } +} +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/secure/secure_init.h b/portable/IAR/ARM_CM35P/secure/secure_init.h new file mode 100644 index 00000000000..21daeda6b89 --- /dev/null +++ b/portable/IAR/ARM_CM35P/secure/secure_init.h @@ -0,0 +1,54 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __SECURE_INIT_H__ +#define __SECURE_INIT_H__ + +/** + * @brief De-prioritizes the non-secure exceptions. + * + * This is needed to ensure that the non-secure PendSV runs at the lowest + * priority. Context switch is done in the non-secure PendSV handler. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + */ +void SecureInit_DePrioritizeNSExceptions( void ); + +/** + * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. + * + * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point + * Registers are not leaked to the non-secure side. + * + * @note This function must be called in the handler mode. It is no-op if called + * in the thread mode. + */ +void SecureInit_EnableNSFPUAccess( void ); + +#endif /* __SECURE_INIT_H__ */ diff --git a/portable/IAR/ARM_CM35P/secure/secure_port_macros.h b/portable/IAR/ARM_CM35P/secure/secure_port_macros.h new file mode 100644 index 00000000000..304913b8dbf --- /dev/null +++ b/portable/IAR/ARM_CM35P/secure/secure_port_macros.h @@ -0,0 +1,140 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __SECURE_PORT_MACROS_H__ +#define __SECURE_PORT_MACROS_H__ + +/** + * @brief Byte alignment requirements. + */ +#define secureportBYTE_ALIGNMENT 8 +#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) + +/** + * @brief Macro to declare a function as non-secure callable. + */ +#if defined( __IAR_SYSTEMS_ICC__ ) + #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root +#else + #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) +#endif + +/** + * @brief Set the secure PRIMASK value. + */ +#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ + __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) + +/** + * @brief Set the non-secure PRIMASK value. + */ +#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ + __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) + +/** + * @brief Read the PSP value in the given variable. + */ +#define secureportREAD_PSP( pucOutCurrentStackPointer ) \ + __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) + +/** + * @brief Set the PSP to the given value. + */ +#define secureportSET_PSP( pucCurrentStackPointer ) \ + __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) + +/** + * @brief Read the PSPLIM value in the given variable. + */ +#define secureportREAD_PSPLIM( pucOutStackLimit ) \ + __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) + +/** + * @brief Set the PSPLIM to the given value. + */ +#define secureportSET_PSPLIM( pucStackLimit ) \ + __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) + +/** + * @brief Set the NonSecure MSP to the given value. + */ +#define secureportSET_MSP_NS( pucMainStackPointer ) \ + __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) + +/** + * @brief Set the CONTROL register to the given value. + */ +#define secureportSET_CONTROL( ulControl ) \ + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) + +/** + * @brief Read the Interrupt Program Status Register (IPSR) value in the given + * variable. + */ +#define secureportREAD_IPSR( ulIPSR ) \ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) + +/** + * @brief PRIMASK value to enable interrupts. + */ +#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 + +/** + * @brief PRIMASK value to disable interrupts. + */ +#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 + +/** + * @brief Disable secure interrupts. + */ +#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) + +/** + * @brief Disable non-secure interrupts. + * + * This effectively disables context switches. + */ +#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) + +/** + * @brief Enable non-secure interrupts. + */ +#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) + +/** + * @brief Assert definition. + */ +#define secureportASSERT( x ) \ + if( ( x ) == 0 ) \ + { \ + secureportDISABLE_SECURE_INTERRUPTS(); \ + secureportDISABLE_NON_SECURE_INTERRUPTS(); \ + for( ; ; ) {; } \ + } + +#endif /* __SECURE_PORT_MACROS_H__ */ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c new file mode 100644 index 00000000000..9976daee49a --- /dev/null +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -0,0 +1,1261 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/* Portasm includes. */ +#include "portasm.h" + +#if ( configENABLE_TRUSTZONE == 1 ) + /* Secure components includes. */ + #include "secure_context.h" + #include "secure_init.h" +#endif /* configENABLE_TRUSTZONE */ + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/** + * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only + * i.e. the processor boots as secure and never jumps to the non-secure side. + * The Trust Zone support in the port must be disabled in order to run FreeRTOS + * on the secure side. The following are the valid configuration seetings: + * + * 1. Run FreeRTOS on the Secure Side: + * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 + * + * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 + * + * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 + */ +#if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) + #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the NVIC. + */ +#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) +#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) +#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the SCB. + */ +#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) +#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the FPU. + */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR_CP10_VALUE ( 3UL ) +#define portCPACR_CP11_VALUE portCPACR_CP10_VALUE +#define portCPACR_CP10_POS ( 20UL ) +#define portCPACR_CP11_POS ( 22UL ) + +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR_ASPEN_POS ( 31UL ) +#define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) +#define portFPCCR_LSPEN_POS ( 30UL ) +#define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the MPU. + */ +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) + +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) + +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) + +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) + +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) + +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) + +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ + +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) + +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) + +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) + +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) + +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) + +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) + +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) + +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) + +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) + +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) + +/* Enable privileged access to unmapped region. */ +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) + +/* Enable MPU. */ +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) + +/* Expected value of the portMPU_TYPE register. */ +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief The maximum 24-bit number. + * + * It is needed because the systick is a 24-bit counter. + */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/** + * @brief A fiddle factor to estimate the number of SysTick counts that would + * have occurred while the SysTick counter is stopped during tickless idle + * calculations. + */ +#define portMISSED_COUNTS_FACTOR ( 94UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to set up the initial stack. + */ +#define portINITIAL_XPSR ( 0x01000000 ) + +#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ + #define portINITIAL_EXC_RETURN ( 0xfffffffd ) +#else + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ + #define portINITIAL_EXC_RETURN ( 0xffffffbc ) +#endif /* configRUN_FREERTOS_SECURE_ONLY */ + +/** + * @brief CONTROL register privileged bit mask. + * + * Bit[0] in CONTROL register tells the privilege: + * Bit[0] = 0 ==> The task is privileged. + * Bit[0] = 1 ==> The task is not privileged. + */ +#define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) + +/** + * @brief Initial CONTROL register values. + */ +#define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) +#define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) + +/** + * @brief Let the user override the default SysTick clock rate. If defined by the + * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the + * configuration register. + */ +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) +#else + /* Select the option to clock SysTick not at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) +#endif + +/** + * @brief Let the user override the pre-loading of the initial LR with the + * address of prvTaskExitError() in case it messes up unwinding of the stack + * in the debugger. + */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/** + * @brief If portPRELOAD_REGISTERS then registers will be given an initial value + * when a task is created. This helps in debugging at the cost of code size. + */ +#define portPRELOAD_REGISTERS 1 + +/** + * @brief A task is created without a secure context, and must call + * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes + * any secure calls. + */ +#define portNO_SECURE_CONTEXT 0 +/*-----------------------------------------------------------*/ + +/** + * @brief Used to catch tasks that attempt to return from their implementing + * function. + */ +static void prvTaskExitError( void ); + +#if ( configENABLE_MPU == 1 ) + +/** + * @brief Setup the Memory Protection Unit (MPU). + */ + static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_FPU == 1 ) + +/** + * @brief Setup the Floating Point Unit (FPU). + */ + static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_FPU */ + +/** + * @brief Setup the timer to generate the tick interrupts. + * + * The implementation in this file is weak to allow application writers to + * change the timer used to generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether the current execution context is interrupt. + * + * @return pdTRUE if the current execution context is interrupt, pdFALSE + * otherwise. + */ +BaseType_t xPortIsInsideInterrupt( void ); + +/** + * @brief Yield the processor. + */ +void vPortYield( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Enter critical section. + */ +void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Exit from critical section. + */ +void vPortExitCritical( void ) PRIVILEGED_FUNCTION; + +/** + * @brief SysTick handler. + */ +void SysTick_Handler( void ) PRIVILEGED_FUNCTION; + +/** + * @brief C part of SVC handler. + */ +portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +/** + * @brief Each task maintains its own interrupt status in the critical nesting + * variable. + */ +PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; + +#if ( configENABLE_TRUSTZONE == 1 ) + +/** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ + PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; +#endif /* configENABLE_TRUSTZONE */ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + +/** + * @brief The number of SysTick increments that make up one tick period. + */ + PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; + +/** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ + PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; + +/** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ + PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + * method as that will mask interrupts that should exit sleep mode. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* If a context switch is pending or a task is waiting for the scheduler + * to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Re-enable interrupts - see comments above the cpsid instruction + * above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + else + { + /* Stop the SysTick momentarily. The time the SysTick is stopped for + * is accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Use the SysTick current-value register to determine the number of + * SysTick decrements remaining until the next tick interrupt. If the + * current-value register is zero, then there are actually + * ulTimerCountsForOneTick decrements remaining, not zero, because the + * SysTick requests the interrupt when decrementing from 1 to 0. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulTimerCountsForOneTick; + } + + /* Calculate the reload value required to wait xExpectedIdleTime + * tick periods. -1 is used because this code normally executes part + * way through the first tick period. But if the SysTick IRQ is now + * pending, then clear the IRQ, suppressing the first tick, and correct + * the reload value to reflect that the second tick period is already + * underway. The expected idle time is always at least two ticks. */ + ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + + if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) + { + portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; + ulReloadValue -= ulTimerCountsForOneTick; + } + + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + * zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + * set its parameter to 0 to indicate that its implementation contains + * its own wait for interrupt or wait for event instruction, and so wfi + * should not be executed again. However, the original expected idle + * time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + + if( xModifiableIdleTime > 0 ) + { + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "wfi" ); + __asm volatile ( "isb" ); + } + + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Re-enable interrupts to allow the interrupt that brought the MCU + * out of sleep mode to execute immediately. See comments above + * the cpsid instruction above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable interrupts again because the clock is about to be stopped + * and interrupts that execute while the clock is stopped will increase + * any slippage between the time maintained by the RTOS and calendar + * time. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable the SysTick clock without reading the + * portNVIC_SYSTICK_CTRL_REG register to ensure the + * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, + * the time the SysTick is stopped for is accounted for as best it can + * be, but using the tickless mode will inevitably result in some tiny + * drift of the time maintained by the kernel with respect to calendar + * time*/ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Determine whether the SysTick has already counted to zero. */ + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt ended the sleep (or is now pending), and + * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG + * with whatever remains of the new tick period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + * underflowed because the post sleep hook did something + * that took too long or because the SysTick current-value register + * is zero. */ + if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* As the pending tick will be processed as soon as this + * function exits, the tick value maintained by the tick is stepped + * forward by one less than the time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. */ + + /* Use the SysTick current-value register to determine the + * number of SysTick decrements remaining until the expected idle + * time would have ended. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) + { + /* If the SysTick is not using the core clock, the current- + * value register might still be zero here. In that case, the + * SysTick didn't load from the reload register, and there are + * ulReloadValue decrements remaining in the expected idle + * time, not zero. */ + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulReloadValue; + } + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Work out how long the sleep lasted rounded to complete tick + * periods (not the ulReload value which accounted for part + * ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; + + /* How many complete tick periods passed while the processor + * was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + * period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, + * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If + * the SysTick is not using the core clock, temporarily configure it to + * use the core clock. This configuration forces the SysTick to load + * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next + * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready + * to receive the standard value immediately. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) + { + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + #else + { + /* The temporary usage of the core clock has served its purpose, + * as described above. Resume usage of the other clock. */ + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; + + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + /* The partial tick period already ended. Be sure the SysTick + * counts it only once. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; + } + + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Step the tick to account for any tick periods that elapsed. */ + vTaskStepTick( ulCompleteTickPeriods ); + + /* Exit with interrupts enabled. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + } +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if ( configUSE_TICKLESS_IDLE == 1 ) + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Stop and reset the SysTick. */ + portNVIC_SYSTICK_CTRL_REG = 0UL; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + volatile uint32_t ulDummy = 0UL; + + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). Artificially force an assert() + * to be triggered if configASSERT() is defined, then stop here so + * application writers can catch the error. */ + configASSERT( ulCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + + while( ulDummy == 0 ) + { + /* This file calls prvTaskExitError() after the scheduler has been + * started to remove a compiler warning about the function being + * defined but never called. ulDummy is used purely to quieten other + * warnings about code appearing after this function is called - making + * ulDummy volatile makes the compiler think the function could return + * and therefore not output an 'unreachable code' warning for code that + * appears after it. */ + } +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + extern uint32_t * __unprivileged_flash_start__; + extern uint32_t * __unprivileged_flash_end__; + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + #else /* if defined( __ARMCC_VERSION ) */ + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + extern uint32_t __unprivileged_flash_start__[]; + extern uint32_t __unprivileged_flash_end__[]; + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + + /* The only permitted number of regions are 8 or 16. */ + configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); + + /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ + configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + + /* Check that the MPU is present. */ + if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) + { + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; + + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); + } + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* Enable non-secure access to the FPU. */ + SecureInit_EnableNSFPUAccess(); + } + #endif /* configENABLE_TRUSTZONE */ + + /* CP10 = 11 ==> Full access to FPU i.e. both privileged and + * unprivileged code should be able to access FPU. CP11 should be + * programmed to the same value as CP10. */ + *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | + ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) + ); + + /* ASPEN = 1 ==> Hardware should automatically preserve floating point + * context on exception entry and restore on exception return. + * LSPEN = 1 ==> Enable lazy context save of FP state. */ + *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); + } +#endif /* configENABLE_FPU */ +/*-----------------------------------------------------------*/ + +void vPortYield( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + portDISABLE_INTERRUPTS(); + ulCriticalNesting++; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + configASSERT( ulCriticalNesting ); + ulCriticalNesting--; + + if( ulCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulPreviousMask; + + ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ +{ + #if ( configENABLE_MPU == 1 ) + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + #endif /* configENABLE_MPU */ + + uint32_t ulPC; + + #if ( configENABLE_TRUSTZONE == 1 ) + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; + #if ( configENABLE_MPU == 1 ) + uint32_t ulControl, ulIsTaskPrivileged; + #endif /* configENABLE_MPU */ + #endif /* configENABLE_TRUSTZONE */ + uint8_t ucSVCNumber; + + /* Register are stored on the stack in the following order - R0, R1, R2, R3, + * R12, LR, PC, xPSR. */ + ulPC = pulCallerStackAddress[ 6 ]; + ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; + + switch( ucSVCNumber ) + { + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: + + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; + + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ + + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; + + case portSVC_FREE_SECURE_CONTEXT: + + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; + + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ + + case portSVC_START_SCHEDULER: + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* De-prioritize the non-secure exceptions so that the + * non-secure pendSV runs at the lowest priority. */ + SecureInit_DePrioritizeNSExceptions(); + + /* Initialize the secure context management system. */ + SecureContext_Init(); + } + #endif /* configENABLE_TRUSTZONE */ + + #if ( configENABLE_FPU == 1 ) + { + /* Setup the Floating Point Unit (FPU). */ + prvSetupFPU(); + } + #endif /* configENABLE_FPU */ + + /* Setup the context of the first task so that the first task starts + * executing. */ + vRestoreContextOfFirstTask(); + break; + + #if ( configENABLE_MPU == 1 ) + case portSVC_RAISE_PRIVILEGE: + + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* configENABLE_MPU */ + + default: + /* Incorrect SVC call. */ + configASSERT( pdFALSE ); + } +} +/*-----------------------------------------------------------*/ +/* *INDENT-OFF* */ +#if ( configENABLE_MPU == 1 ) + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ +#else + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +#endif /* configENABLE_MPU */ +/* *INDENT-ON* */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; + + #if ( configENABLE_MPU == 1 ) + { + pxTopOfStack--; + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + } + #endif /* configENABLE_MPU */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + + #if ( configENABLE_TRUSTZONE == 1 ) + { + pxTopOfStack--; + *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ + } + #endif /* configENABLE_TRUSTZONE */ + } + #else /* portPRELOAD_REGISTERS */ + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ + + #if ( configENABLE_MPU == 1 ) + { + pxTopOfStack--; + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + } + } + #endif /* configENABLE_MPU */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + + #if ( configENABLE_TRUSTZONE == 1 ) + { + pxTopOfStack--; + *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ + } + #endif /* configENABLE_TRUSTZONE */ + } + #endif /* portPRELOAD_REGISTERS */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ + portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; + portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; + + #if ( configENABLE_MPU == 1 ) + { + /* Setup the Memory Protection Unit (MPU). */ + prvSetupMPU(); + } + #endif /* configENABLE_MPU */ + + /* Start the timer that generates the tick ISR. Interrupts are disabled + * here already. */ + vPortSetupTimerInterrupt(); + + /* Initialize the critical nesting count ready for the first task. */ + ulCriticalNesting = 0; + + /* Start the first task. */ + vStartFirstTask(); + + /* Should never get here as the tasks will now be executing. Call the task + * exit error function to prevent compiler warnings about a static function + * not being called in the case that the application writer overrides this + * functionality by defining configTASK_RETURN_ADDRESS. Call + * vTaskSwitchContext() so link time optimization does not remove the + * symbol. */ + vTaskSwitchContext(); + prvTaskExitError(); + + /* Should not get here. */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( ulCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) + { + uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; + int32_t lIndex = 0; + + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + #endif /* defined( __ARMCC_VERSION ) */ + + /* Setup MAIR0. */ + xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + + /* This function is called automatically when the task is created - in + * which case the stack region parameters will be valid. At all other + * times the stack parameters will not be valid and it is assumed that + * the stack region has already been configured. */ + if( ulStackDepth > 0 ) + { + ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + + /* If the stack is within the privileged SRAM, do not protect it + * using a separate MPU region. This is needed because privileged + * SRAM is already protected using an MPU region and ARMv8-M does + * not allow overlapping MPU regions. */ + if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && + ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) + { + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; + xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; + } + else + { + /* Define the region that allows access to the stack. */ + ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; + ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; + + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + + xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); + } + } + + /* User supplied configurable regions. */ + for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) + { + /* If xRegions is NULL i.e. the task has not specified any MPU + * region, the else part ensures that all the configurable MPU + * regions are invalidated. */ + if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) + { + /* Translate the generic region definition contained in xRegions + * into the ARMv8 specific MPU settings that are then stored in + * xMPUSettings. */ + ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; + ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; + ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; + + /* Start address. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | + ( portMPU_REGION_NON_SHAREABLE ); + + /* RO/RW. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); + } + else + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); + } + + /* XN. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); + } + + /* End Address. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | + ( portMPU_RLAR_REGION_ENABLE ); + + /* Normal memory/ Device memory. */ + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) + { + /* Attr1 in MAIR0 is configured as device memory. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; + } + else + { + /* Attr0 in MAIR0 is configured as normal memory. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; + } + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; + } + + lIndex++; + } + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. Interrupt Program + * Status Register (IPSR) holds the exception number of the currently-executing + * exception or zero for Thread mode.*/ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h new file mode 100644 index 00000000000..ecd86b97fd1 --- /dev/null +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h @@ -0,0 +1,114 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 __PORT_ASM_H__ +#define __PORT_ASM_H__ + +/* Scheduler includes. */ +#include "FreeRTOS.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ +void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ +BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + +/** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kenrel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vResetPrivilege( void ) __attribute__( ( naked ) ); + +/** + * @brief Starts the first task. + */ +void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Disables interrupts. + */ +uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Enables interrupts. + */ +void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief PendSV Exception handler. + */ +void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief SVC Handler. + */ +void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ +void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + +/** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ +void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +#endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s new file mode 100644 index 00000000000..581b84d4951 --- /dev/null +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s @@ -0,0 +1,262 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + EXTERN vPortSVCHandler_C + + PUBLIC xIsPrivileged + PUBLIC vResetPrivilege + PUBLIC vRestoreContextOfFirstTask + PUBLIC vRaisePrivilege + PUBLIC vStartFirstTask + PUBLIC ulSetInterruptMask + PUBLIC vClearInterruptMask + PUBLIC PendSV_Handler + PUBLIC SVC_Handler +/*-----------------------------------------------------------*/ + +/*---------------- Unprivileged Functions -------------------*/ + +/*-----------------------------------------------------------*/ + + SECTION .text:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +xIsPrivileged: + mrs r0, control /* r0 = CONTROL. */ + tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ + ite ne + movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ + moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ + bx lr /* Return. */ +/*-----------------------------------------------------------*/ + +vResetPrivilege: + mrs r0, control /* r0 = CONTROL. */ + orr r0, r0, #1 /* r0 = r0 | 1. */ + msr control, r0 /* CONTROL = r0. */ + bx lr /* Return to the caller. */ +/*-----------------------------------------------------------*/ + +/*----------------- Privileged Functions --------------------*/ + +/*-----------------------------------------------------------*/ + + SECTION privileged_functions:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +vRestoreContextOfFirstTask: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r2] /* Read pxCurrentTCB. */ + ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + +#if ( configENABLE_MPU == 1 ) + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r2] /* Read the value of MPU_CTRL. */ + bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + str r4, [r2] /* Disable MPU. */ + + adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r3, [r2] /* Program MAIR0. */ + ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ + movs r3, #4 /* r3 = 4. */ + str r3, [r2] /* Program RNR = 4. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r2] /* Read the value of MPU_CTRL. */ + orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + str r4, [r2] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ + msr psplim, r1 /* Set this task's PSPLIM value. */ + msr control, r2 /* Set this task's CONTROL value. */ + adds r0, #32 /* Discard everything up to r0. */ + msr psp, r0 /* This is now the new top of stack to use in the task. */ + isb + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx r3 /* Finally, branch to EXC_RETURN. */ +#else /* configENABLE_MPU */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + msr psplim, r1 /* Set this task's PSPLIM value. */ + movs r1, #2 /* r1 = 2. */ + msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + adds r0, #32 /* Discard everything up to r0. */ + msr psp, r0 /* This is now the new top of stack to use in the task. */ + isb + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx r2 /* Finally, branch to EXC_RETURN. */ +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +vRaisePrivilege: + mrs r0, control /* Read the CONTROL register. */ + bic r0, r0, #1 /* Clear the bit 0. */ + msr control, r0 /* Write back the new CONTROL value. */ + bx lr /* Return to the caller. */ +/*-----------------------------------------------------------*/ + +vStartFirstTask: + ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ + ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ + ldr r0, [r0] /* The first entry in vector table is stack pointer. */ + msr msp, r0 /* Set the MSP back to the start of the stack. */ + cpsie i /* Globally enable interrupts. */ + cpsie f + dsb + isb + svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ +/*-----------------------------------------------------------*/ + +ulSetInterruptMask: + mrs r0, basepri /* r0 = basepri. Return original basepri value. */ + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bx lr /* Return. */ +/*-----------------------------------------------------------*/ + +vClearInterruptMask: + msr basepri, r0 /* basepri = ulMask. */ + dsb + isb + bx lr /* Return. */ +/*-----------------------------------------------------------*/ + +PendSV_Handler: + mrs r0, psp /* Read PSP in r0. */ +#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + it eq + vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ +#endif /* configENABLE_FPU || configENABLE_MVE */ +#if ( configENABLE_MPU == 1 ) + mrs r1, psplim /* r1 = PSPLIM. */ + mrs r2, control /* r2 = CONTROL. */ + mov r3, lr /* r3 = LR/EXC_RETURN. */ + stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ +#else /* configENABLE_MPU */ + mrs r2, psplim /* r2 = PSPLIM. */ + mov r3, lr /* r3 = LR/EXC_RETURN. */ + stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ +#endif /* configENABLE_MPU */ + + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r2] /* Read pxCurrentTCB. */ + str r0, [r1] /* Save the new top of stack in TCB. */ + + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r2] /* Read pxCurrentTCB. */ + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + +#if ( configENABLE_MPU == 1 ) + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r2] /* Read the value of MPU_CTRL. */ + bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + str r4, [r2] /* Disable MPU. */ + + adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r3, [r2] /* Program MAIR0. */ + ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ + movs r3, #4 /* r3 = 4. */ + str r3, [r2] /* Program RNR = 4. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r2] /* Read the value of MPU_CTRL. */ + orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + str r4, [r2] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ +#else /* configENABLE_MPU */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ +#endif /* configENABLE_MPU */ + +#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + it eq + vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ +#endif /* configENABLE_FPU || configENABLE_MVE */ + + #if ( configENABLE_MPU == 1 ) + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ + msr control, r2 /* Restore the CONTROL register value for the task. */ +#else /* configENABLE_MPU */ + msr psplim, r2 /* Restore the PSPLIM register value for the task. */ +#endif /* configENABLE_MPU */ + msr psp, r0 /* Remember the new top of stack for the task. */ + bx r3 +/*-----------------------------------------------------------*/ + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b vPortSVCHandler_C +/*-----------------------------------------------------------*/ + + END diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h new file mode 100644 index 00000000000..a0efc1f9dcf --- /dev/null +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -0,0 +1,78 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "portmacrocommon.h" + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + +/** + * Architecture specifics. + */ +#define portARCH_NAME "Cortex-M35P" +#define portDONT_DISCARD __root +/*-----------------------------------------------------------*/ + +#if( configTOTAL_MPU_REGIONS == 16 ) + #error 16 MPU regions are not yet supported for this port. +#endif +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ +#define portDISABLE_INTERRUPTS() ulSetInterruptMask() +#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) +/*-----------------------------------------------------------*/ + +/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in + * the source code because to do so would cause other compilers to generate + * warnings. */ +#pragma diag_suppress=Be006 +#pragma diag_suppress=Pa082 +/*-----------------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif /* PORTMACRO_H */ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h new file mode 100644 index 00000000000..ca7e9225c05 --- /dev/null +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -0,0 +1,313 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 PORTMACROCOMMON_H + #define PORTMACROCOMMON_H + + #ifdef __cplusplus + extern "C" { + #endif + +/*------------------------------------------------------------------------------ + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *------------------------------------------------------------------------------ + */ + + #ifndef configENABLE_FPU + #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. + #endif /* configENABLE_FPU */ + + #ifndef configENABLE_MPU + #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. + #endif /* configENABLE_MPU */ + + #ifndef configENABLE_TRUSTZONE + #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. + #endif /* configENABLE_TRUSTZONE */ + +/*-----------------------------------------------------------*/ + +/** + * @brief Type definitions. + */ + #define portCHAR char + #define portFLOAT float + #define portDOUBLE double + #define portLONG long + #define portSHORT short + #define portSTACK_TYPE uint32_t + #define portBASE_TYPE long + + typedef portSTACK_TYPE StackType_t; + typedef long BaseType_t; + typedef unsigned long UBaseType_t; + + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + * not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. + #endif +/*-----------------------------------------------------------*/ + +/** + * Architecture specifics. + */ + #define portSTACK_GROWTH ( -1 ) + #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + #define portBYTE_ALIGNMENT 8 + #define portNOP() + #define portINLINE __inline + #ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) + #endif + #define portHAS_STACK_OVERFLOW_CHECKING 1 +/*-----------------------------------------------------------*/ + +/** + * @brief Extern declarations. + */ + extern BaseType_t xPortIsInsideInterrupt( void ); + + extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; + + extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; + extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; + + extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + + #if ( configENABLE_TRUSTZONE == 1 ) + extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ + extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; + #endif /* configENABLE_TRUSTZONE */ + + #if ( configENABLE_MPU == 1 ) + extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; + extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; + #endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief MPU specific constants. + */ + #if ( configENABLE_MPU == 1 ) + #define portUSING_MPU_WRAPPERS 1 + #define portPRIVILEGE_BIT ( 0x80000000UL ) + #else + #define portPRIVILEGE_BIT ( 0x0UL ) + #endif /* configENABLE_MPU */ + +/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +#ifndef configTOTAL_MPU_REGIONS + /* Define to 8 for backward compatibility. */ + #define configTOTAL_MPU_REGIONS ( 8UL ) +#endif + +/* MPU regions. */ + #define portPRIVILEGED_FLASH_REGION ( 0UL ) + #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) + #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) + #define portPRIVILEGED_RAM_REGION ( 3UL ) + #define portSTACK_REGION ( 4UL ) + #define portFIRST_CONFIGURABLE_REGION ( 5UL ) + #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) + #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) + #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +/* Device memory attributes used in MPU_MAIR registers. + * + * 8-bit values encoded as follows: + * Bit[7:4] - 0000 - Device Memory + * Bit[3:2] - 00 --> Device-nGnRnE + * 01 --> Device-nGnRE + * 10 --> Device-nGRE + * 11 --> Device-GRE + * Bit[1:0] - 00, Reserved. + */ + #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ + #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ + #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ + #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ + +/* Normal memory attributes used in MPU_MAIR registers. */ + #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ + #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ + +/* Attributes used in MPU_RBAR registers. */ + #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) + #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) + #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) + + #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) + #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) + #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) + #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) + + #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) +/*-----------------------------------------------------------*/ + +/** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + +/** + * @brief MPU settings as stored in the TCB. + */ + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + } xMPU_SETTINGS; +/*-----------------------------------------------------------*/ + +/** + * @brief SVC numbers. + */ + #define portSVC_ALLOCATE_SECURE_CONTEXT 0 + #define portSVC_FREE_SECURE_CONTEXT 1 + #define portSVC_START_SCHEDULER 2 + #define portSVC_RAISE_PRIVILEGE 3 +/*-----------------------------------------------------------*/ + +/** + * @brief Scheduler utilities. + */ + #define portYIELD() vPortYield() + #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) + #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) + #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) + #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/** + * @brief Critical section management. + */ + #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) + #define portENTER_CRITICAL() vPortEnterCritical() + #define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/** + * @brief Tickless idle/low power functionality. + */ + #ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) + #endif +/*-----------------------------------------------------------*/ + +/** + * @brief Task function macros as described on the FreeRTOS.org WEB site. + */ + #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) + #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +/*-----------------------------------------------------------*/ + + #if ( configENABLE_TRUSTZONE == 1 ) + +/** + * @brief Allocate a secure context for the task. + * + * Tasks are not created with a secure context. Any task that is going to call + * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a + * secure context before it calls any secure function. + * + * @param[in] ulSecureStackSize The size of the secure stack to be allocated. + */ + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) + +/** + * @brief Called when a task is deleted to delete the task's secure context, + * if it has one. + * + * @param[in] pxTCB The TCB of the task being deleted. + */ + #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) + #endif /* configENABLE_TRUSTZONE */ +/*-----------------------------------------------------------*/ + + #if ( configENABLE_MPU == 1 ) + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + #define portIS_PRIVILEGED() xIsPrivileged() + +/** + * @brief Raise an SVC request to raise privilege. + * + * The SVC handler checks that the SVC was raised from a system call and only + * then it raises the privilege. If this is called from any other place, + * the privilege is not raised. + */ + #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + */ + #define portRESET_PRIVILEGE() vResetPrivilege() + #else + #define portIS_PRIVILEGED() + #define portRAISE_PRIVILEGE() + #define portRESET_PRIVILEGE() + #endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief Barriers. + */ + #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) +/*-----------------------------------------------------------*/ + + #ifdef __cplusplus + } + #endif + +#endif /* PORTMACROCOMMON_H */ From 0a70ecbb510ac91bdeaa1488b76ba8924efef283 Mon Sep 17 00:00:00 2001 From: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com> Date: Tue, 28 Feb 2023 13:22:25 +0530 Subject: [PATCH 053/109] Introduced Github Status Badge for Unit Tests (#634) * Introduced Github Status Badge for Unit Tests * Github status badge to point to latest run * Github status badge UT points to latest results * Fixed URL for Github Status badge --------- Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 025a135774f..90c3c698d15 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![CMock Unit Tests](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml/badge.svg?branch=main&event=push)](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml?query=branch%3Amain+event%3Apush+workflow%3A%22CMock+Unit+Tests%22++) + ## Getting started This repository contains FreeRTOS kernel source/header files and kernel ports only. This repository is referenced as a submodule in [FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS) repository, which contains pre-configured demo application projects under ```FreeRTOS/Demo``` directory. From e6514fb1edacbf2535aa8e5d16b7ae06a18f57e3 Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Thu, 2 Mar 2023 14:47:29 +0530 Subject: [PATCH 054/109] Remove C99 requirement from CMake file (#633) * Remove C99 requirement from CMake file The kernel source is C89 compliant and does not need C99. Signed-off-by: Gaurav Aggarwal * Explicitly set C89 requirement for kernel Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aead9a0d841..b51b7aaacdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,8 +230,7 @@ endif() ######################################################################## # Requirements -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) +set_property(TARGET freertos_kernel PROPERTY C_STANDARD 90) ######################################################################## # Overall Compile Options From c3e1df031e3f988780afb2a743fde93c12135005 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 2 Mar 2023 08:26:04 -0800 Subject: [PATCH 055/109] Add Thread Local Storage (TLS) support using Picolibc functions (#343) * Pass top of stack to configINIT_TLS_BLOCK Picolibc wants to allocate the per-task TLS block within the stack segment, so it will need to modify the top of stack value. Pass the pxTopOfStack variable to make this explicit. Signed-off-by: Keith Packard * Move newlib-specific definitions to separate file This reduces the clutter in FreeRTOS.h caused by having newlib-specific macros present there. Signed-off-by: Keith Packard * Make TLS code depend only on configUSE_C_RUNTIME_TLS_SUPPORT Remove reference to configUSE_NEWLIB_REENTRANT as that only works when using newlib. configUSE_C_RUNTIME_TLS_SUPPORT is always set when configUSE_NEWLIB_REENTRANT is set, so using both was redundant in that case. Signed-off-by: Keith Packard * portable-ARC: Adapt ARC support to use generalized TLS support With generalized thread local storage (TLS) support present in the core, the two ARC ports need to have the changes to the TCB mirrored to them. Signed-off-by: Keith Packard * Add Thread Local Storage (TLS) support using Picolibc functions This patch provides definitions of the general TLS support macros in terms of the Picolibc TLS support functions. Picolibc is normally configured to use TLS internally for all variables that are intended to be task-local, so these changes are necessary for picolibc to work correctly with FreeRTOS. The picolibc helper functions rely on elements within the linker script to arrange the TLS data in memory and define some symbols. Applications wanting to use this mechanism will need changes in their linker script when migrating to picolibc. Signed-off-by: Keith Packard --------- Signed-off-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- .github/lexicon.txt | 2 + include/FreeRTOS.h | 39 +++++--------- include/newlib-freertos.h | 62 +++++++++++++++++++++ include/picolibc-freertos.h | 69 ++++++++++++++++++++++++ portable/ThirdParty/GCC/ARC_EM_HS/port.c | 12 +---- portable/ThirdParty/GCC/ARC_v1/port.c | 12 +---- tasks.c | 12 ++--- 7 files changed, 155 insertions(+), 53 deletions(-) create mode 100644 include/newlib-freertos.h create mode 100644 include/picolibc-freertos.h diff --git a/.github/lexicon.txt b/.github/lexicon.txt index 47ce4ccde11..47d2349bfff 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -1054,6 +1054,7 @@ mclk mconfigintcoresw mcr mcu +md mddr mder mdh @@ -1335,6 +1336,7 @@ phy phya pic picnt +picolibc pien piir pimr diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index e720480dc64..f1ab32c6c1b 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -95,41 +95,26 @@ /* Required if struct _reent is used. */ #if ( configUSE_NEWLIB_REENTRANT == 1 ) -/* Note Newlib support has been included by popular demand, but is not - * used by the FreeRTOS maintainers themselves. FreeRTOS is not - * responsible for resulting newlib operation. User must be familiar with - * newlib and must provide system-wide implementations of the necessary - * stubs. Be warned that (at the time of writing) the current newlib design - * implements a system-wide malloc() that must be provided with locks. - * - * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html - * for additional information. */ - #include + #include "newlib-freertos.h" - #define configUSE_C_RUNTIME_TLS_SUPPORT 1 +#endif /* if ( configUSE_NEWLIB_REENTRANT == 1 ) */ - #ifndef configTLS_BLOCK_TYPE - #define configTLS_BLOCK_TYPE struct _reent - #endif +/* Must be defaulted before configUSE_PICOLIBC_TLS is used below. */ +#ifndef configUSE_PICOLIBC_TLS + #define configUSE_PICOLIBC_TLS 0 +#endif - #ifndef configINIT_TLS_BLOCK - #define configINIT_TLS_BLOCK( xTLSBlock ) _REENT_INIT_PTR( &( xTLSBlock ) ) - #endif +#if ( configUSE_PICOLIBC_TLS == 1 ) - #ifndef configSET_TLS_BLOCK - #define configSET_TLS_BLOCK( xTLSBlock ) ( _impure_ptr = &( xTLSBlock ) ) - #endif + #include "picolibc-freertos.h" - #ifndef configDEINIT_TLS_BLOCK - #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) - #endif -#endif /* if ( configUSE_NEWLIB_REENTRANT == 1 ) */ +#endif /* if ( configUSE_PICOLIBC_TLS == 1 ) */ #ifndef configUSE_C_RUNTIME_TLS_SUPPORT #define configUSE_C_RUNTIME_TLS_SUPPORT 0 #endif -#if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) +#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) #ifndef configTLS_BLOCK_TYPE #error Missing definition: configTLS_BLOCK_TYPE must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. @@ -146,7 +131,7 @@ #ifndef configDEINIT_TLS_BLOCK #error Missing definition: configDEINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. #endif -#endif /* if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) */ +#endif /* if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) */ /* * Check all the required application specific macros have been defined. @@ -1306,7 +1291,7 @@ typedef struct xSTATIC_TCB #if ( configGENERATE_RUN_TIME_STATS == 1 ) configRUN_TIME_COUNTER_TYPE ulDummy16; #endif - #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) configTLS_BLOCK_TYPE xDummy17; #endif #if ( configUSE_TASK_NOTIFICATIONS == 1 ) diff --git a/include/newlib-freertos.h b/include/newlib-freertos.h new file mode 100644 index 00000000000..497ca529990 --- /dev/null +++ b/include/newlib-freertos.h @@ -0,0 +1,62 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 INC_NEWLIB_FREERTOS_H +#define INC_NEWLIB_FREERTOS_H + +/* Note Newlib support has been included by popular demand, but is not + * used by the FreeRTOS maintainers themselves. FreeRTOS is not + * responsible for resulting newlib operation. User must be familiar with + * newlib and must provide system-wide implementations of the necessary + * stubs. Be warned that (at the time of writing) the current newlib design + * implements a system-wide malloc() that must be provided with locks. + * + * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html + * for additional information. */ + +#include + +#define configUSE_C_RUNTIME_TLS_SUPPORT 1 + +#ifndef configTLS_BLOCK_TYPE + #define configTLS_BLOCK_TYPE struct _reent +#endif + +#ifndef configINIT_TLS_BLOCK + #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) _REENT_INIT_PTR( &( xTLSBlock ) ) +#endif + +#ifndef configSET_TLS_BLOCK + #define configSET_TLS_BLOCK( xTLSBlock ) _impure_ptr = &( xTLSBlock ) +#endif + +#ifndef configDEINIT_TLS_BLOCK + #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) +#endif + +#endif /* INC_NEWLIB_FREERTOS_H */ diff --git a/include/picolibc-freertos.h b/include/picolibc-freertos.h new file mode 100644 index 00000000000..472d71e9932 --- /dev/null +++ b/include/picolibc-freertos.h @@ -0,0 +1,69 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 INC_PICOLIBC_FREERTOS_H +#define INC_PICOLIBC_FREERTOS_H + +/* Use picolibc TLS support to allocate space for __thread variables, + * initialize them at thread creation and set the TLS context at + * thread switch time. + * + * See the picolibc TLS docs: + * https://github.com/picolibc/picolibc/blob/main/doc/tls.md + * for additional information. */ + +#include + +#define configUSE_C_RUNTIME_TLS_SUPPORT 1 + +#define configTLS_BLOCK_TYPE void * + +/* Allocate thread local storage block off the end of the +* stack. The _tls_size() function returns the size (in +* bytes) of the total TLS area used by the application */ +#if ( portSTACK_GROWTH < 0 ) + #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ + do { \ + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) - _tls_size() ); \ + xTLSBlock = pxTopOfStack; \ + _init_tls( xTLSBlock ); \ + } while( 0 ) +#else /* portSTACK_GROWTH */ + #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ + do { \ + xTLSBlock = pxTopOfStack; \ + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) + _tls_size() ); \ + _init_tls( xTLSBlock ); \ + } while( 0 ) +#endif /* portSTACK_GROWTH */ + +#define configSET_TLS_BLOCK( xTLSBlock ) _set_tls( xTLSBlock ) + +#define configDEINIT_TLS_BLOCK( xTLSBlock ) + +#endif /* INC_PICOLIBC_FREERTOS_H */ diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/port.c b/portable/ThirdParty/GCC/ARC_EM_HS/port.c index 57be56a7f5f..0e023088efd 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/port.c +++ b/portable/ThirdParty/GCC/ARC_EM_HS/port.c @@ -251,16 +251,8 @@ void vPortEndTask( void ) uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ #endif - #if ( configUSE_NEWLIB_REENTRANT == 1 ) - - /* Allocate a Newlib reent structure that is specific to this task. - * Note Newlib support has been included by popular demand, but is not - * used by the FreeRTOS maintainers themselves. FreeRTOS is not - * responsible for resulting newlib operation. User must be familiar with - * newlib and must provide system-wide implementations of the necessary - * stubs. Be warned that (at the time of writing) the current newlib design - * implements a system-wide malloc() that must be provided with locks. */ - struct _reent xNewLib_reent; + #if ( 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 ) diff --git a/portable/ThirdParty/GCC/ARC_v1/port.c b/portable/ThirdParty/GCC/ARC_v1/port.c index d3de6fa3d60..4dbdc7e601c 100644 --- a/portable/ThirdParty/GCC/ARC_v1/port.c +++ b/portable/ThirdParty/GCC/ARC_v1/port.c @@ -251,16 +251,8 @@ void vPortEndTask( void ) uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ #endif - #if ( configUSE_NEWLIB_REENTRANT == 1 ) - - /* Allocate a Newlib reent structure that is specific to this task. - * Note Newlib support has been included by popular demand, but is not - * used by the FreeRTOS maintainers themselves. FreeRTOS is not - * responsible for resulting newlib operation. User must be familiar with - * newlib and must provide system-wide implementations of the necessary - * stubs. Be warned that (at the time of writing) the current newlib design - * implements a system-wide malloc() that must be provided with locks. */ - struct _reent xNewLib_reent; + #if ( 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 ) diff --git a/tasks.c b/tasks.c index 2b73b1b9703..0e7a56c6058 100644 --- a/tasks.c +++ b/tasks.c @@ -300,7 +300,7 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to 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 ) ) + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) configTLS_BLOCK_TYPE xTLSBlock; /**< Memory block used as Thread Local Storage (TLS) Block for the task. */ #endif @@ -955,10 +955,10 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, } #endif - #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) { /* Allocate and initialize memory for the task's TLS Block. */ - configINIT_TLS_BLOCK( pxNewTCB->xTLSBlock ); + configINIT_TLS_BLOCK( pxNewTCB->xTLSBlock, pxTopOfStack ); } #endif @@ -2030,7 +2030,7 @@ void vTaskStartScheduler( void ) * starts to run. */ portDISABLE_INTERRUPTS(); - #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) { /* Switch C-Runtime's TLS Block to point to the TLS * block specific to the task that will run first. */ @@ -3074,7 +3074,7 @@ void vTaskSwitchContext( void ) } #endif - #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) { /* Switch C-Runtime's TLS Block to point to the TLS * Block specific to this task. */ @@ -3950,7 +3950,7 @@ static void prvCheckTasksWaitingTermination( void ) * want to allocate and clean RAM statically. */ portCLEAN_UP_TCB( pxTCB ); - #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) { /* Free up the memory allocated for the task's TLS Block. */ configDEINIT_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); From a9e1f668497b9832edd4f1a85a1d37f4e8409cf9 Mon Sep 17 00:00:00 2001 From: Chris Copeland Date: Thu, 2 Mar 2023 09:49:56 -0800 Subject: [PATCH 056/109] Interrupt priority assert improvements for CM3/4/7 (#602) * Interrupt priority assert improvements for CM3/4/7 In the ARM_CM3, ARM_CM4, and ARM_CM7 ports, change the assertion that `configMAX_SYSCALL_INTERRUPT_PRIORITY` is nonzero to account for the number of priority bits implemented by the hardware. Change these ports to also use the lowest priority for PendSV and SysTick, ignoring `configKERNEL_INTERRUPT_PRIORITY`. * Remove not needed configKERNEL_INTERRUPT_PRIORITY define Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal --- portable/CCS/ARM_CM3/port.c | 13 +++++++++++-- portable/CCS/ARM_CM4F/port.c | 13 +++++++++++-- portable/GCC/ARM_CM3/port.c | 24 +++++++++++------------- portable/GCC/ARM_CM3_MPU/port.c | 17 +++++++++++------ portable/GCC/ARM_CM4F/port.c | 17 +++++++++++------ portable/GCC/ARM_CM4_MPU/port.c | 17 +++++++++++------ portable/GCC/ARM_CM7/r0p1/port.c | 17 +++++++++++------ portable/IAR/ARM_CM0/port.c | 7 ------- portable/IAR/ARM_CM3/port.c | 24 +++++++++++------------- portable/IAR/ARM_CM4F/port.c | 17 +++++++++++------ portable/IAR/ARM_CM4F_MPU/port.c | 17 +++++++++++------ portable/IAR/ARM_CM7/r0p1/port.c | 17 +++++++++++------ portable/MikroC/ARM_CM4F/port.c | 21 +++++++++++---------- portable/RVDS/ARM_CM3/port.c | 21 +++++++++++---------- portable/RVDS/ARM_CM4F/port.c | 17 +++++++++++------ portable/RVDS/ARM_CM4_MPU/port.c | 13 +++++++++++-- portable/RVDS/ARM_CM7/r0p1/port.c | 17 +++++++++++------ portable/Tasking/ARM_CM4F/port.c | 7 ++++--- 18 files changed, 180 insertions(+), 116 deletions(-) diff --git a/portable/CCS/ARM_CM3/port.c b/portable/CCS/ARM_CM3/port.c index 80e0b0a2410..dfdb240ed2b 100644 --- a/portable/CCS/ARM_CM3/port.c +++ b/portable/CCS/ARM_CM3/port.c @@ -52,8 +52,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -239,6 +240,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/CCS/ARM_CM4F/port.c b/portable/CCS/ARM_CM4F/port.c index 4006191705e..360e83d7000 100644 --- a/portable/CCS/ARM_CM4F/port.c +++ b/portable/CCS/ARM_CM4F/port.c @@ -56,8 +56,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -258,6 +259,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/GCC/ARM_CM3/port.c b/portable/GCC/ARM_CM3/port.c index 7f650fd360d..a5cea1e1e1b 100644 --- a/portable/GCC/ARM_CM3/port.c +++ b/portable/GCC/ARM_CM3/port.c @@ -34,13 +34,6 @@ #include "FreeRTOS.h" #include "task.h" -/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is - * defined. The value should also ensure backward compatibility. - * FreeRTOS.org versions prior to V4.4.0 did not include this definition. */ -#ifndef configKERNEL_INTERRUPT_PRIORITY - #define configKERNEL_INTERRUPT_PRIORITY 255 -#endif - /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) @@ -55,8 +48,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -265,10 +259,6 @@ static void prvPortStartFirstTask( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; @@ -293,6 +283,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index e0f1d170154..5f7d2c81113 100644 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -83,8 +83,9 @@ /* Constants required to access and manipulate the SysTick. */ #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to set up the initial stack. */ @@ -381,10 +382,6 @@ static void prvRestoreContextOfFirstTask( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See - * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); - #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; @@ -409,6 +406,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c index b946e6e9435..b978f0af54c 100644 --- a/portable/GCC/ARM_CM4F/port.c +++ b/portable/GCC/ARM_CM4F/port.c @@ -58,8 +58,9 @@ #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -295,10 +296,6 @@ static void prvPortStartFirstTask( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - /* This port can be used on all revisions of the Cortex-M7 core other than * the r0p1 parts. r0p1 parts should use the port from the * /source/portable/GCC/ARM_CM7/r0p1 directory. */ @@ -329,6 +326,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index 3125f7824d4..57d0ea5a2f6 100644 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -93,8 +93,9 @@ /* Constants required to access and manipulate the SysTick. */ #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to manipulate the VFP. */ @@ -412,10 +413,6 @@ static void prvRestoreContextOfFirstTask( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See - * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); - /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0 * and r0p1 cores. */ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) @@ -452,6 +449,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c index a9c69aae7fa..c602bd297cd 100644 --- a/portable/GCC/ARM_CM7/r0p1/port.c +++ b/portable/GCC/ARM_CM7/r0p1/port.c @@ -52,8 +52,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -289,10 +290,6 @@ static void prvPortStartFirstTask( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; @@ -317,6 +314,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/IAR/ARM_CM0/port.c b/portable/IAR/ARM_CM0/port.c index ad168e577ae..c55af1fd8ad 100644 --- a/portable/IAR/ARM_CM0/port.c +++ b/portable/IAR/ARM_CM0/port.c @@ -56,13 +56,6 @@ /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) -/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is - * defined. The value 255 should also ensure backward compatibility. - * FreeRTOS.org versions prior to V4.3.0 did not include this definition. */ -#ifndef configKERNEL_INTERRUPT_PRIORITY - #define configKERNEL_INTERRUPT_PRIORITY 0 -#endif - /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; diff --git a/portable/IAR/ARM_CM3/port.c b/portable/IAR/ARM_CM3/port.c index cef6c247216..f35ee98c798 100644 --- a/portable/IAR/ARM_CM3/port.c +++ b/portable/IAR/ARM_CM3/port.c @@ -55,8 +55,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -86,13 +87,6 @@ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) -/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is - * defined. The value 255 should also ensure backward compatibility. - * FreeRTOS.org versions prior to V4.3.0 did not include this definition. */ -#ifndef configKERNEL_INTERRUPT_PRIORITY - #define configKERNEL_INTERRUPT_PRIORITY 255 -#endif - /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ @@ -214,10 +208,6 @@ static void prvTaskExitError( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; @@ -242,6 +232,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/IAR/ARM_CM4F/port.c b/portable/IAR/ARM_CM4F/port.c index 243d0578585..90be11d0eda 100644 --- a/portable/IAR/ARM_CM4F/port.c +++ b/portable/IAR/ARM_CM4F/port.c @@ -65,8 +65,9 @@ #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -239,10 +240,6 @@ static void prvTaskExitError( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - /* This port can be used on all revisions of the Cortex-M7 core other than * the r0p1 parts. r0p1 parts should use the port from the * /source/portable/GCC/ARM_CM7/r0p1 directory. */ @@ -273,6 +270,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index 2f4d1b9e349..dd6bde281c2 100644 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -104,8 +104,9 @@ #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ @@ -346,10 +347,6 @@ void vPortSVCHandler_C( uint32_t * pulParam ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0 * and r0p1 cores. */ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) @@ -386,6 +383,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c index 207f0b3eb67..e9e3805f054 100644 --- a/portable/IAR/ARM_CM7/r0p1/port.c +++ b/portable/IAR/ARM_CM7/r0p1/port.c @@ -59,8 +59,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -233,10 +234,6 @@ static void prvTaskExitError( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; @@ -261,6 +258,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/MikroC/ARM_CM4F/port.c b/portable/MikroC/ARM_CM4F/port.c index a0b83ebd30b..886913fbc40 100644 --- a/portable/MikroC/ARM_CM4F/port.c +++ b/portable/MikroC/ARM_CM4F/port.c @@ -48,8 +48,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -295,10 +296,6 @@ static void prvPortStartFirstTask( void ) */ BaseType_t xPortStartScheduler( void ) { - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; @@ -320,13 +317,17 @@ BaseType_t xPortStartScheduler( void ) /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; - /* The kernel interrupt priority should be set to the lowest - * priority. */ - configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) ); - /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/RVDS/ARM_CM3/port.c b/portable/RVDS/ARM_CM3/port.c index 551fb3441b5..ac4bef29572 100644 --- a/portable/RVDS/ARM_CM3/port.c +++ b/portable/RVDS/ARM_CM3/port.c @@ -34,10 +34,6 @@ #include "FreeRTOS.h" #include "task.h" -#ifndef configKERNEL_INTERRUPT_PRIORITY - #define configKERNEL_INTERRUPT_PRIORITY 255 -#endif - #if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif @@ -65,8 +61,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -285,13 +282,17 @@ BaseType_t xPortStartScheduler( void ) /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; - /* The kernel interrupt priority should be set to the lowest - * priority. */ - configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) ); - /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/RVDS/ARM_CM4F/port.c b/portable/RVDS/ARM_CM4F/port.c index d6fb9d7a19c..cdc063dc9f8 100644 --- a/portable/RVDS/ARM_CM4F/port.c +++ b/portable/RVDS/ARM_CM4F/port.c @@ -71,8 +71,9 @@ #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -347,13 +348,17 @@ BaseType_t xPortStartScheduler( void ) /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; - /* The kernel interrupt priority should be set to the lowest - * priority. */ - configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) ); - /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index 22680d77623..b9c7f90b446 100644 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -83,8 +83,9 @@ #define portNVIC_SYSTICK_CLK ( 0x00000004UL ) #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to manipulate the VFP. */ @@ -442,6 +443,14 @@ BaseType_t xPortStartScheduler( void ) /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/RVDS/ARM_CM7/r0p1/port.c b/portable/RVDS/ARM_CM7/r0p1/port.c index ae0a4a6d943..7dadb9adb34 100644 --- a/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/portable/RVDS/ARM_CM7/r0p1/port.c @@ -65,8 +65,9 @@ #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) @@ -331,13 +332,17 @@ BaseType_t xPortStartScheduler( void ) /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; - /* The kernel interrupt priority should be set to the lowest - * priority. */ - configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) ); - /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; diff --git a/portable/Tasking/ARM_CM4F/port.c b/portable/Tasking/ARM_CM4F/port.c index d33a3982630..66b0d629466 100644 --- a/portable/Tasking/ARM_CM4F/port.c +++ b/portable/Tasking/ARM_CM4F/port.c @@ -41,8 +41,9 @@ #define portNVIC_SYSTICK_CLK 0x00000004 #define portNVIC_SYSTICK_INT 0x00000002 #define portNVIC_SYSTICK_ENABLE 0x00000001 -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16 ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24 ) +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) @@ -70,7 +71,7 @@ /* The priority used by the kernel is assigned to a variable to make access * from inline assembler easier. */ -const uint32_t ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY; +const uint32_t ulKernelPriority = portMIN_INTERRUPT_PRIORITY; /* Each task maintains its own interrupt status in the critical nesting * variable. */ From 97acc2e54a5aa7e1e47250f76b30627880255fb0 Mon Sep 17 00:00:00 2001 From: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com> Date: Thu, 2 Mar 2023 23:36:57 +0530 Subject: [PATCH 057/109] Introduced code coverage status badge (#635) * Introduced code coverage status badge * Trying to fix the URL checker issue * Fix URL check Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- .github/actions/url_verifier.sh | 11 +++++++---- README.md | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/actions/url_verifier.sh b/.github/actions/url_verifier.sh index 4c8aed53b12..e9804657b20 100755 --- a/.github/actions/url_verifier.sh +++ b/.github/actions/url_verifier.sh @@ -28,13 +28,14 @@ function test { for UNIQ_URL in ${!dict[@]} # loop urls do - CURL_RES=$(curl -si --user-agent "$(USER_AGENT)" ${UNIQ_URL} 2>/dev/null| head -n 1 | cut -f 2 -d ' ') + CURL_RES=$(curl -si --user-agent "${USER_AGENT}" ${UNIQ_URL} 2>/dev/null| head -n 1 | cut -f 2 -d ' ') RES=$? + echo "=================================" + echo "Checking URL: ${UNIQ_URL}" + if [ "${CURL_RES}" == '' -o "${CURL_RES}" != '200' ] then - echo "URL is: ${UNIQ_URL}" - echo "File names: ${dict[$UNIQ_URL]}" if [ "${CURL_RES}" == '' ] # curl returned an error then CURL_RES=$RES @@ -47,8 +48,10 @@ function test { else echo WARNING: Result is: "${CURL_RES}" fi - echo "=================================" + else + echo SUCCESS: Result is: "${CURL_RES}" fi + echo "=================================" done if [ "${SCRIPT_RET}" -eq 0 ] diff --git a/README.md b/README.md index 90c3c698d15..952914daf46 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![CMock Unit Tests](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml/badge.svg?branch=main&event=push)](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml?query=branch%3Amain+event%3Apush+workflow%3A%22CMock+Unit+Tests%22++) - +[![codecov](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel/badge.svg?branch=main)](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel) ## Getting started This repository contains FreeRTOS kernel source/header files and kernel ports only. This repository is referenced as a submodule in [FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS) repository, which contains pre-configured demo application projects under ```FreeRTOS/Demo``` directory. From ddd50d9a80fd80e2bca7e93d49baf5c71986cbbb Mon Sep 17 00:00:00 2001 From: Joseph Julicher Date: Fri, 3 Mar 2023 19:01:16 -0700 Subject: [PATCH 058/109] added portPOINTER_SIZE_TYPE and SIZE_MAX definition to PIC24/dsPIC port (#636) * added portPOINTER_SIZE_TYPE definition to PIC24/dsPIC port * Added SIZE_MAX definition to PIC24/dsPIC33 --- portable/MPLAB/PIC24_dsPIC/portmacro.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/portable/MPLAB/PIC24_dsPIC/portmacro.h b/portable/MPLAB/PIC24_dsPIC/portmacro.h index d05317e6f8c..83b695a43bb 100644 --- a/portable/MPLAB/PIC24_dsPIC/portmacro.h +++ b/portable/MPLAB/PIC24_dsPIC/portmacro.h @@ -51,6 +51,8 @@ extern "C" { #define portSHORT short #define portSTACK_TYPE uint16_t #define portBASE_TYPE short +#define portPOINTER_SIZE_TYPE size_t +#define SIZE_MAX ( ( size_t ) -1 ) typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; From 563c57e7dab713aa1e289795c44549239f732a43 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 5 Mar 2023 22:29:39 -0800 Subject: [PATCH 059/109] Fix TLS and stack alignment when using picolibc (#637) Both the TLS block and stack must be correctly aligned when using picolibc. The architecture stack alignment is represented by the portBYTE_ALIGNMENT_MASK and the TLS block alignment is provided by the Picolibc _tls_align() inline function for Picolibc version 1.8 and above. For older versions of Picolibc, we'll assume that the TLS block requires the same alignment as the stack. For downward growing stacks, this requires aligning the start of the TLS block to the maximum of the stack alignment and the TLS alignment. With this, both the TLS block and stack will now be correctly aligned. For upward growing stacks, the two areas must be aligned independently; the TLS block is aligned from the start of the stack, then the tls space is allocated, and then the stack is aligned above that. It's probably useful to know here that the linker ensures that variables within the TLS block are assigned offsets that match their alignment requirements. If the TLS block itself is correctly aligned, then everything within will also be. I have only tested the downward growing stack branch of this patch. Signed-off-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- include/picolibc-freertos.h | 41 ++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/include/picolibc-freertos.h b/include/picolibc-freertos.h index 472d71e9932..467f7a97091 100644 --- a/include/picolibc-freertos.h +++ b/include/picolibc-freertos.h @@ -43,22 +43,43 @@ #define configTLS_BLOCK_TYPE void * +#define picolibcTLS_SIZE ( ( portPOINTER_SIZE_TYPE ) _tls_size() ) +#define picolibcSTACK_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) + +#if __PICOLIBC_MAJOR__ > 1 || __PICOLIBC_MINOR__ >= 8 + +/* Picolibc 1.8 and newer have explicit alignment values provided + * by the _tls_align() inline */ + #define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) ( _tls_align() - 1 ) ) +#else + +/* For older Picolibc versions, use the general port alignment value */ + #define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) +#endif + /* Allocate thread local storage block off the end of the * stack. The _tls_size() function returns the size (in * bytes) of the total TLS area used by the application */ #if ( portSTACK_GROWTH < 0 ) - #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ - do { \ - pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) - _tls_size() ); \ - xTLSBlock = pxTopOfStack; \ - _init_tls( xTLSBlock ); \ + + #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ + do { \ + pxTopOfStack = ( StackType_t * ) ( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) \ + - picolibcTLS_SIZE ) & ~ \ + configMAX( picolibcSTACK_ALIGNMENT_MASK, \ + picolibcTLS_ALIGNMENT_MASK ) ); \ + xTLSBlock = pxTopOfStack; \ + _init_tls( xTLSBlock ); \ } while( 0 ) #else /* portSTACK_GROWTH */ - #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ - do { \ - xTLSBlock = pxTopOfStack; \ - pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) + _tls_size() ); \ - _init_tls( xTLSBlock ); \ + #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ + do { \ + xTLSBlock = ( void * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack + \ + picolibcTLS_ALIGNMENT_MASK ) & ~picolibcTLS_ALIGNMENT_MASK ); \ + pxTopOfStack = ( StackType_t * ) ( ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) + \ + picolibcTLS_SIZE ) + picolibcSTACK_ALIGNMENT_MASK ) & \ + ~picolibcSTACK_ALIGNMENT_MASK ); \ + _init_tls( xTLSBlock ); \ } while( 0 ) #endif /* portSTACK_GROWTH */ From 7b26ea6263d795bd1090eac60d63a29080934f2f Mon Sep 17 00:00:00 2001 From: Paul Bartell Date: Mon, 6 Mar 2023 08:19:28 -0800 Subject: [PATCH 060/109] Enable building the GCC Cortex-R5 port without an FPU (#586) * Ensure configUSE_TASK_FPU_SUPPORT option is set correctly If one does enable the FPU of the Cortex-R5 processor, then the GCC compiler will define the macro __ARM_FP. This can be used to ensure, that the configUSE_TASK_FPU_SUPPORT is set accordingly. * Enable the implementation of vPortTaskUsesFPU only if configUSE_TASK_FPU_SUPPORT is set to 1 * Remove error case in pxPortInitialiseStack The case of configUSE_TASK_FPU_SUPPORT is 0 is now handled * Enable access to FPU registers only if FPU is enabled * Make minor formating changes * Format ARM Cortex-R5 port * Address review comments from @ChristosZosi * Minor code review suggestions Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Christos Zosimidis Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal --- portable/GCC/ARM_CR5/port.c | 311 ++++++++++++++++++++----------- portable/GCC/ARM_CR5/portASM.S | 86 +++++---- portable/GCC/ARM_CR5/portmacro.h | 250 +++++++++++++------------ 3 files changed, 385 insertions(+), 262 deletions(-) diff --git a/portable/GCC/ARM_CR5/port.c b/portable/GCC/ARM_CR5/port.c index 8a9839cde56..03007821967 100644 --- a/portable/GCC/ARM_CR5/port.c +++ b/portable/GCC/ARM_CR5/port.c @@ -74,25 +74,52 @@ #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif -/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in - * portmacro.h. */ +/* + * __ARM_FP is defined by the c preprocessor when FPU support is enabled, + * usually with the -mfpu= argument and -mfloat-abi=. + * + * Note: Some implementations of the c standard library may use FPU registers + * for generic memory operations (memcpy, etc). + * When setting configUSE_TASK_FPU_SUPPORT == 1, care must be taken to + * ensure that the FPU registers are not used without an FPU context. + */ +#if ( configUSE_TASK_FPU_SUPPORT == 0 ) + #ifdef __ARM_FP + #error __ARM_FP is defined, so configUSE_TASK_FPU_SUPPORT must be set to either to 1 or 2. + #endif /* __ARM_FP */ +#elif ( configUSE_TASK_FPU_SUPPORT == 1 ) || ( configUSE_TASK_FPU_SUPPORT == 2 ) + #ifndef __ARM_FP + #error __ARM_FP is not defined, so configUSE_TASK_FPU_SUPPORT must be set to 0. + #endif /* __ARM_FP */ +#endif /* configUSE_TASK_FPU_SUPPORT */ + +/* + * Some vendor specific files default configCLEAR_TICK_INTERRUPT() in + * portmacro.h. + */ #ifndef configCLEAR_TICK_INTERRUPT #define configCLEAR_TICK_INTERRUPT() #endif -/* A critical section is exited when the critical section nesting count reaches - * this value. */ +/* + * A critical section is exited when the critical section nesting count reaches + * this value. + */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) -/* In all GICs 255 can be written to the priority mask register to unmask all - * (but the lowest) interrupt priority. */ +/* + * In all GICs 255 can be written to the priority mask register to unmask all + * (but the lowest) interrupt priority. + */ #define portUNMASK_VALUE ( 0xFFUL ) -/* Tasks are not created with a floating point context, but can be given a +/* + * Tasks are not created with a floating point context, but can be given a * floating point context after they have been created. A variable is stored as * part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task * does not have an FPU context, or any other value if the task does have an FPU - * context. */ + * context. + */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ @@ -101,8 +128,10 @@ #define portINTERRUPT_ENABLE_BIT ( 0x80UL ) #define portTHUMB_MODE_ADDRESS ( 0x01UL ) -/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary - * point is zero. */ +/* + * Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary + * point is zero. + */ #define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) /* Masks all bits in the APSR other than the mode bits. */ @@ -140,15 +169,19 @@ #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portBIT_0_SET ( ( uint8_t ) 0x01 ) -/* Let the user override the pre-loading of the initial LR with the address of +/* + * Let the user override the pre-loading of the initial LR with the address of * prvTaskExitError() in case is messes up unwinding of the stack in the - * debugger. */ + * debugger. + */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif +#if ( configUSE_TASK_FPU_SUPPORT != 0 ) + /* * The space on the stack required to hold the FPU registers. * @@ -160,7 +193,8 @@ * the size of the bank remains the same. The FPU has also a 32-bit * status register. */ -#define portFPU_REGISTER_WORDS ( ( 16 * 2 ) + 1 ) + #define portFPU_REGISTER_WORDS ( ( 16 * 2 ) + 1 ) +#endif /* configUSE_TASK_FPU_SUPPORT != 0 */ /*-----------------------------------------------------------*/ @@ -175,6 +209,8 @@ extern void vPortRestoreTaskContext( void ); */ static void prvTaskExitError( void ); +#if ( configUSE_TASK_FPU_SUPPORT != 0 ) + /* * If the application provides an implementation of vApplicationIRQHandler(), * then it will get called directly without saving the FPU registers on @@ -194,26 +230,36 @@ static void prvTaskExitError( void ); * FPU registers to be saved on interrupt entry their IRQ handler must be * called vApplicationIRQHandler(). */ -void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) ); + void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__( ( weak ) ); +#endif /* configUSE_TASK_FPU_SUPPORT != 0 */ /*-----------------------------------------------------------*/ -/* A variable is used to keep track of the critical section nesting. This +/* + * A variable is used to keep track of the critical section nesting. This * variable has to be stored as part of the task context and must be initialised to * a non zero value to ensure interrupts don't inadvertently become unmasked before * the scheduler starts. As it is stored as part of the task context it will - * automatically be set to 0 when the first task is started. */ + * automatically be set to 0 when the first task is started. + */ volatile uint32_t ulCriticalNesting = 9999UL; -/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then - * a floating point context must be saved and restored for the task. */ -uint32_t ulPortTaskHasFPUContext = pdFALSE; +#if ( configUSE_TASK_FPU_SUPPORT != 0 ) + +/* + * Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then + * a floating point context must be saved and restored for the task. + */ + uint32_t ulPortTaskHasFPUContext = pdFALSE; +#endif /* configUSE_TASK_FPU_SUPPORT != 0 */ /* Set to 1 to pend a context switch from an ISR. */ uint32_t ulPortYieldRequired = pdFALSE; -/* Counts the interrupt nesting depth. A context switch is only performed if - * if the nesting depth is 0. */ +/* + * Counts the interrupt nesting depth. A context switch is only performed if + * if the nesting depth is 0. + */ uint32_t ulPortInterruptNesting = 0UL; /* Used in asm code. */ @@ -231,12 +277,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { - /* Setup the initial stack of the task. The stack is set exactly as + /* + * Setup the initial stack of the task. The stack is set exactly as * expected by the portRESTORE_CONTEXT() macro. * * The fist real value on the stack is the status register, which is set for * system mode, with interrupts enabled. A few NULLs are added first to ensure - * GDB does not try decoding a non-existent return address. */ + * GDB does not try decoding a non-existent return address. + */ *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; @@ -285,24 +333,31 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack--; - /* The task will start with a critical nesting count of 0 as interrupts are - * enabled. */ + /* + * The task will start with a critical nesting count of 0 as interrupts are + * enabled. + */ + pxTopOfStack--; *pxTopOfStack = portNO_CRITICAL_NESTING; - #if( configUSE_TASK_FPU_SUPPORT == 1 ) + #if ( configUSE_TASK_FPU_SUPPORT == 1 ) { - /* The task will start without a floating point context. A task that - uses the floating point hardware must call vPortTaskUsesFPU() before - executing any floating point instructions. */ + /* + * The task will start without a floating point context. + * A task that uses the floating point hardware must call + * vPortTaskUsesFPU() before executing any floating point + * instructions. + */ pxTopOfStack--; *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; } - #elif( configUSE_TASK_FPU_SUPPORT == 2 ) + #elif ( configUSE_TASK_FPU_SUPPORT == 2 ) { - /* The task will start with a floating point context. Leave enough - space for the registers - and ensure they are initialized to 0. */ + /* + * The task will start with a floating point context. Leave enough + * space for the registers and ensure they are initialized to 0. + */ pxTopOfStack -= portFPU_REGISTER_WORDS; memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); @@ -310,9 +365,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, *pxTopOfStack = pdTRUE; ulPortTaskHasFPUContext = pdTRUE; } - #else + #elif ( configUSE_TASK_FPU_SUPPORT != 0 ) { - #error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined. + #error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 0, 1, or 2. } #endif /* configUSE_TASK_FPU_SUPPORT */ @@ -322,12 +377,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, static void prvTaskExitError( void ) { - /* A function that implements a task must not exit or attempt to return to + /* + * A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is - * defined, then stop here so application writers can catch the error. */ + * defined, then stop here so application writers can catch the error. + */ configASSERT( ulPortInterruptNesting == ~0UL ); portDISABLE_INTERRUPTS(); @@ -337,11 +394,15 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) -{ - ( void ) ulICCIAR; - configASSERT( ( volatile void * ) NULL ); -} +#if ( configUSE_TASK_FPU_SUPPORT != 0 ) + + void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) /* __attribute__( ( weak ) ) */ + { + ( void ) ulICCIAR; + configASSERT( ( volatile void * ) NULL ); + } + +#endif /* configUSE_TASK_FPU_SUPPORT != 0 */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) @@ -349,67 +410,82 @@ BaseType_t xPortStartScheduler( void ) uint32_t ulAPSR, ulCycles = 8; /* 8 bits per byte. */ #if ( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); + volatile uint8_t ucMaxPriorityValue; + + /* + * Determine how many priority bits are implemented in the GIC. + * Save the interrupt priority value that is about to be clobbered. + */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* + * Determine the number of priority bits available. First write to + * all possible bits. + */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Shift to the least significant bits. */ + while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET ) { - volatile uint32_t ulOriginalPriority; - volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); - volatile uint8_t ucMaxPriorityValue; - - /* Determine how many priority bits are implemented in the GIC. - * - * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; - - /* Determine the number of priority bits available. First write to - * all possible bits. */ - *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + ucMaxPriorityValue >>= ( uint8_t ) 0x01; - /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = *pucFirstUserPriorityRegister; + /* + * If ulCycles reaches 0 then ucMaxPriorityValue must have been + * read as 0, indicating a misconfiguration. + */ + ulCycles--; - /* Shift to the least significant bits. */ - while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET ) + if( ulCycles == 0 ) { - ucMaxPriorityValue >>= ( uint8_t ) 0x01; - - /* If ulCycles reaches 0 then ucMaxPriorityValue must have been - * read as 0, indicating a misconfiguration. */ - ulCycles--; - - if( ulCycles == 0 ) - { - break; - } + break; } - - /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read - * value. */ - configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY ); - - /* Restore the clobbered interrupt priority register to its original - * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; } + + /* + * Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read + * value. + */ + configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY ); + + /* + * Restore the clobbered interrupt priority register to its original + * value. + */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } #endif /* configASSERT_DEFINED */ - /* Only continue if the CPU is not in User mode. The CPU must be in a - * Privileged mode for the scheduler to start. */ + /* + * Only continue if the CPU is not in User mode. The CPU must be in a + * Privileged mode for the scheduler to start. + */ __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" ); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); if( ulAPSR != portAPSR_USER_MODE ) { - /* Only continue if the binary point value is set to its lowest possible + /* + * Only continue if the binary point value is set to its lowest possible * setting. See the comments in vPortValidateInterruptPriority() below for - * more information. */ + * more information. + */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ) { - /* Interrupts are turned off in the CPU itself to ensure tick does + /* + * Interrupts are turned off in the CPU itself to ensure tick does * not execute while the scheduler is being started. Interrupts are * automatically turned back on in the CPU when the first task starts - * executing. */ + * executing. + */ portCPU_IRQ_DISABLE(); /* Start the timer that generates the tick ISR. */ @@ -420,20 +496,25 @@ BaseType_t xPortStartScheduler( void ) } } - /* Will only get here if vTaskStartScheduler() was called with the CPU in + /* + * Will only get here if vTaskStartScheduler() was called with the CPU in * a non-privileged mode or the binary point register was not set to its lowest * possible value. prvTaskExitError() is referenced to prevent a compiler * warning about it being defined but not referenced in the case that the user - * defines their own exit address. */ + * defines their own exit address. + */ ( void ) prvTaskExitError; + return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { - /* Not implemented in ports where there is nothing to return to. - * Artificially force an assert. */ + /* + * Not implemented in ports where there is nothing to return to. + * Artificially force an assert. + */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ @@ -443,16 +524,20 @@ void vPortEnterCritical( void ) /* Mask interrupts up to the max syscall interrupt priority. */ ulPortSetInterruptMask(); - /* Now interrupts are disabled ulCriticalNesting can be accessed + /* + * Now interrupts are disabled ulCriticalNesting can be accessed * directly. Increment ulCriticalNesting to keep a count of how many times - * portENTER_CRITICAL() has been called. */ + * portENTER_CRITICAL() has been called. + */ ulCriticalNesting++; - /* This is not the interrupt safe version of the enter critical function so + /* + * This is not the interrupt safe version of the enter critical function so * assert() if it is being called from an interrupt context. Only API * functions that end in "FromISR" can be used in an interrupt. Only assert if * the critical nesting count is 1 to protect against recursive calls if the - * assert function also uses a critical section. */ + * assert function also uses a critical section. + */ if( ulCriticalNesting == 1 ) { configASSERT( ulPortInterruptNesting == 0 ); @@ -464,16 +549,19 @@ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { - /* Decrement the nesting count as the critical section is being - * exited. */ + /* Decrement the nesting count as the critical section is being exited. */ ulCriticalNesting--; - /* If the nesting level has reached zero then all interrupt - * priorities must be re-enabled. */ + /* + * If the nesting level has reached zero then all interrupt + * priorities must be re-enabled. + */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { - /* Critical nesting has reached zero so all interrupt priorities - * should be unmasked. */ + /* + * Critical nesting has reached zero so all interrupt priorities + * should be unmasked. + */ portCLEAR_INTERRUPT_MASK(); } } @@ -482,11 +570,13 @@ void vPortExitCritical( void ) void FreeRTOS_Tick_Handler( void ) { - /* Set interrupt mask before altering scheduler structures. The tick + /* + * Set interrupt mask before altering scheduler structures. The tick * handler runs at the lowest priority, so interrupts cannot already be masked, * so there is no need to save and restore the current mask value. It is * necessary to turn off interrupts in the CPU itself while the ICCPMR is being - * updated. */ + * updated. + */ portCPU_IRQ_DISABLE(); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm volatile ( "dsb \n" @@ -505,21 +595,23 @@ void FreeRTOS_Tick_Handler( void ) } /*-----------------------------------------------------------*/ -#if( configUSE_TASK_FPU_SUPPORT != 2 ) +#if ( configUSE_TASK_FPU_SUPPORT == 1 ) void vPortTaskUsesFPU( void ) { uint32_t ulInitialFPSCR = 0; - /* A task is registering the fact that it needs an FPU context. Set the - * FPU flag (which is saved as part of the task context). */ + /* + * A task is registering the fact that it needs an FPU context. Set the + * FPU flag (which is saved as part of the task context). + */ ulPortTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ __asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" ); } -#endif /* configUSE_TASK_FPU_SUPPORT */ +#endif /* configUSE_TASK_FPU_SUPPORT == 1 */ /*-----------------------------------------------------------*/ void vPortClearInterruptMask( uint32_t ulNewMaskValue ) @@ -535,8 +627,7 @@ uint32_t ulPortSetInterruptMask( void ) { uint32_t ulReturn; - /* Interrupt in the CPU must be turned off while the ICCPMR is being - * updated. */ + /* Interrupts must be masked while ICCPMR is updated. */ portCPU_IRQ_DISABLE(); if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) @@ -562,7 +653,8 @@ uint32_t ulPortSetInterruptMask( void ) void vPortValidateInterruptPriority( void ) { - /* The following assertion will fail if a service routine (ISR) for + /* + * The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called @@ -575,11 +667,13 @@ uint32_t ulPortSetInterruptMask( void ) * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * FreeRTOS maintains separate thread and ISR API functions to ensure - * interrupt entry is as fast and simple as possible. */ + * interrupt entry is as fast and simple as possible. + */ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); - /* Priority grouping: The interrupt controller (GIC) allows the bits + /* + * Priority grouping: The interrupt controller (GIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined @@ -588,7 +682,8 @@ uint32_t ulPortSetInterruptMask( void ) * * The priority grouping is configured by the GIC's binary point register * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest - * possible value (which may be above 0). */ + * possible value (which may be above 0). + */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/GCC/ARM_CR5/portASM.S b/portable/GCC/ARM_CR5/portASM.S index c44ea6b7913..c331057d610 100644 --- a/portable/GCC/ARM_CR5/portASM.S +++ b/portable/GCC/ARM_CR5/portASM.S @@ -45,7 +45,10 @@ .extern vTaskSwitchContext .extern vApplicationIRQHandler .extern ulPortInterruptNesting + +#if defined( __ARM_FP ) .extern ulPortTaskHasFPUContext +#endif /* __ARM_FP */ .global FreeRTOS_IRQ_Handler .global FreeRTOS_SWI_Handler @@ -64,20 +67,21 @@ LDR R1, [R2] PUSH {R1} - /* Does the task have a floating point context that needs saving? If - ulPortTaskHasFPUContext is 0 then no. */ - LDR R2, ulPortTaskHasFPUContextConst - LDR R3, [R2] - CMP R3, #0 + #if defined( __ARM_FP ) + /* Does the task have a floating point context that needs saving? If + ulPortTaskHasFPUContext is 0 then no. */ + LDR R2, ulPortTaskHasFPUContextConst + LDR R3, [R2] + CMP R3, #0 - /* Save the floating point context, if any. */ - FMRXNE R1, FPSCR - VPUSHNE {D0-D15} - /*VPUSHNE {D16-D31}*/ - PUSHNE {R1} + /* Save the floating point context, if any. */ + FMRXNE R1, FPSCR + VPUSHNE {D0-D15} + PUSHNE {R1} - /* Save ulPortTaskHasFPUContext itself. */ - PUSH {R3} + /* Save ulPortTaskHasFPUContext itself. */ + PUSH {R3} + #endif /* __ARM_FP */ /* Save the stack pointer in the TCB. */ LDR R0, pxCurrentTCBConst @@ -95,18 +99,21 @@ LDR R1, [R0] LDR SP, [R1] - /* Is there a floating point context to restore? If the restored - ulPortTaskHasFPUContext is zero then no. */ - LDR R0, ulPortTaskHasFPUContextConst - POP {R1} - STR R1, [R0] - CMP R1, #0 - - /* Restore the floating point context, if any. */ - POPNE {R0} - /*VPOPNE {D16-D31}*/ - VPOPNE {D0-D15} - VMSRNE FPSCR, R0 + #if defined( __ARM_FP ) + /* + * Is there a floating point context to restore? If the restored + * ulPortTaskHasFPUContext is zero then no. + */ + LDR R0, ulPortTaskHasFPUContextConst + POP {R1} + STR R1, [R0] + CMP R1, #0 + + /* Restore the floating point context, if any. */ + POPNE {R0} + VPOPNE {D0-D15} + VMSRNE FPSCR, R0 + #endif /* __ARM_FP */ /* Restore the critical section nesting depth. */ LDR R0, ulCriticalNestingConst @@ -132,8 +139,6 @@ .endm - - /****************************************************************************** * SVC handler is used to start the scheduler. *****************************************************************************/ @@ -279,22 +284,25 @@ switch_before_exit: * FPU registers to be saved on interrupt entry their IRQ handler must be * called vApplicationIRQHandler(). *****************************************************************************/ - .align 4 .weak vApplicationIRQHandler .type vApplicationIRQHandler, %function vApplicationIRQHandler: + PUSH {LR} - FMRX R1, FPSCR - VPUSH {D0-D15} - PUSH {R1} - LDR r1, vApplicationFPUSafeIRQHandlerConst - BLX r1 + #if defined( __ARM_FP ) + FMRX R1, FPSCR + VPUSH {D0-D15} + PUSH {R1} - POP {R0} - VPOP {D0-D15} - VMSR FPSCR, R0 + LDR r1, vApplicationFPUSafeIRQHandlerConst + BLX r1 + + POP {R0} + VPOP {D0-D15} + VMSR FPSCR, R0 + #endif /* __ARM_FP */ POP {PC} @@ -303,11 +311,15 @@ ulICCEOIRConst: .word ulICCEOIR ulICCPMRConst: .word ulICCPMR pxCurrentTCBConst: .word pxCurrentTCB ulCriticalNestingConst: .word ulCriticalNesting -ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext + +#if defined( __ARM_FP ) + ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext + vApplicationFPUSafeIRQHandlerConst: .word vApplicationFPUSafeIRQHandler +#endif /* __ARM_FP */ + ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask vTaskSwitchContextConst: .word vTaskSwitchContext vApplicationIRQHandlerConst: .word vApplicationIRQHandler ulPortInterruptNestingConst: .word ulPortInterruptNesting -vApplicationFPUSafeIRQHandlerConst: .word vApplicationFPUSafeIRQHandler .end diff --git a/portable/GCC/ARM_CR5/portmacro.h b/portable/GCC/ARM_CR5/portmacro.h index 4bd25bb048b..ff7337d1502 100644 --- a/portable/GCC/ARM_CR5/portmacro.h +++ b/portable/GCC/ARM_CR5/portmacro.h @@ -27,11 +27,13 @@ */ #ifndef PORTMACRO_H - #define PORTMACRO_H +#define PORTMACRO_H - #ifdef __cplusplus - extern "C" { - #endif +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. @@ -44,161 +46,175 @@ */ /* Type definitions. */ - #define portCHAR char - #define portFLOAT float - #define portDOUBLE double - #define portLONG long - #define portSHORT short - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE long +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +typedef uint32_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffffffffUL /*-----------------------------------------------------------*/ /* Hardware specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 8 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ - #define portEND_SWITCHING_ISR( xSwitchRequired ) \ - { \ - extern uint32_t ulPortYieldRequired; \ - \ - if( xSwitchRequired != pdFALSE ) \ - { \ - ulPortYieldRequired = pdTRUE; \ - } \ +#define portEND_SWITCHING_ISR( xSwitchRequired ) \ + { \ + extern uint32_t ulPortYieldRequired; \ + \ + if( xSwitchRequired != pdFALSE ) \ + { \ + ulPortYieldRequired = pdTRUE; \ + } \ } - #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) - #define portYIELD() __asm volatile ( "SWI 0" ::: "memory" ); +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" ); /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ - extern void vPortEnterCritical( void ); - extern void vPortExitCritical( void ); - extern uint32_t ulPortSetInterruptMask( void ); - extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); - extern void vPortInstallFreeRTOSVectorTable( void ); - -/* These macros do not globally disable/enable interrupts. They do mask off - * interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ - #define portENTER_CRITICAL() vPortEnterCritical(); - #define portEXIT_CRITICAL() vPortExitCritical(); - #define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() - #define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) - #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x ) +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); +extern void vPortInstallFreeRTOSVectorTable( void ); + +/* + * These macros do not globally disable/enable interrupts. They do mask off + * interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. + */ +#define portENTER_CRITICAL() vPortEnterCritical(); +#define portEXIT_CRITICAL() vPortExitCritical(); +#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() +#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x ) /*-----------------------------------------------------------*/ -/* Task function macros as described on the FreeRTOS.org WEB site. These are +/* + * Task function macros as described on the FreeRTOS.org WEB site. These are * not required for this port but included in case common demo code that uses these - * macros is used. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - -/* Prototype of the FreeRTOS tick handler. This must be installed as the - * handler for whichever peripheral is used to generate the RTOS tick. */ - void FreeRTOS_Tick_Handler( void ); - -/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are -created without an FPU context and must call vPortTaskUsesFPU() to give -themselves an FPU context before using any FPU instructions. If -configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context -by default. */ -#if( configUSE_TASK_FPU_SUPPORT != 2 ) + * macros is used. + */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) + +/* + * Prototype of the FreeRTOS tick handler. This must be installed as the + * handler for whichever peripheral is used to generate the RTOS tick. + */ +void FreeRTOS_Tick_Handler( void ); + +/* + * If configUSE_TASK_FPU_SUPPORT is set to 1, then tasks are created without an + * FPU context and must call vPortTaskUsesFPU() to allocate an FPU context + * prior to any FPU instructions. If configUSE_TASK_FPU_SUPPORT is set to 2, + * then all tasks have an FPU context allocated by default. + */ +#if ( configUSE_TASK_FPU_SUPPORT == 1 ) void vPortTaskUsesFPU( void ); -#else - /* Each task has an FPU context already, so define this function away to - nothing to prevent it being called accidentally. */ + #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() +#elif ( configUSE_TASK_FPU_SUPPORT == 2 ) + +/* + * Each task has an FPU context already, so define this function away to + * prevent it being called accidentally. + */ #define vPortTaskUsesFPU() + #define portTASK_USES_FLOATING_POINT() #endif /* configUSE_TASK_FPU_SUPPORT */ - #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() - #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) - #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) +#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) +#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ - #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION - #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 - #endif +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif - #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ - #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) - #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) /*-----------------------------------------------------------*/ - #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) ) - - #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ - - #ifdef configASSERT - void vPortValidateInterruptPriority( void ); - #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() - #endif /* configASSERT */ + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) ) - #define portNOP() __asm volatile ( "NOP" ) +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif /* configASSERT */ - #ifdef __cplusplus - } /* extern C */ - #endif +#define portNOP() __asm volatile ( "NOP" ) -/* The number of bits to shift for an interrupt priority is dependent on the - * number of bits implemented by the interrupt controller. */ - #if configUNIQUE_INTERRUPT_PRIORITIES == 16 - #define portPRIORITY_SHIFT 4 - #define portMAX_BINARY_POINT_VALUE 3 - #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 - #define portPRIORITY_SHIFT 3 - #define portMAX_BINARY_POINT_VALUE 2 - #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 - #define portPRIORITY_SHIFT 2 - #define portMAX_BINARY_POINT_VALUE 1 - #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 - #define portPRIORITY_SHIFT 1 - #define portMAX_BINARY_POINT_VALUE 0 - #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 - #define portPRIORITY_SHIFT 0 - #define portMAX_BINARY_POINT_VALUE 0 - #else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */ - #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware - #endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */ +/* + * The number of bits to shift for an interrupt priority is dependent on the + * number of bits implemented by the interrupt controller. + */ +#if configUNIQUE_INTERRUPT_PRIORITIES == 16 + #define portPRIORITY_SHIFT 4 + #define portMAX_BINARY_POINT_VALUE 3 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 32 + #define portPRIORITY_SHIFT 3 + #define portMAX_BINARY_POINT_VALUE 2 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 64 + #define portPRIORITY_SHIFT 2 + #define portMAX_BINARY_POINT_VALUE 1 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 128 + #define portPRIORITY_SHIFT 1 + #define portMAX_BINARY_POINT_VALUE 0 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 256 + #define portPRIORITY_SHIFT 0 + #define portMAX_BINARY_POINT_VALUE 0 +#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */ + #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware +#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */ /* Interrupt controller access addresses. */ - #define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) - #define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) - #define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) - #define portICCBPR_BINARY_POINT_OFFSET ( 0x08 ) - #define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 ) - - #define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) - #define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) ) - #define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ) - #define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET ) - #define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) - #define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) ) - #define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) ) - - #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) +#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) +#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) +#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) +#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 ) +#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 ) + +#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) +#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) ) +#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ) +#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET ) +#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) +#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) ) +#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) ) + +#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } /* extern C */ +#endif +/* *INDENT-ON* */ #endif /* PORTMACRO_H */ From 309a18a03adab1eaca5d86654dd4e1075ee49e7a Mon Sep 17 00:00:00 2001 From: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:04:15 -0800 Subject: [PATCH 061/109] Fix freertos_kernel cmake property, Posix Port (#640) * Fix freertos_kernel cmake property, Posix Port * Moves the `set_property()` call below the target definition in top level CMakeLists file * Corrects billion value from `ULL` suffix (not C90 compliant) to `UL` suffix with cast to uint64_t * Add blank line to CMakeLists.txt --- CMakeLists.txt | 8 ++++---- portable/ThirdParty/GCC/Posix/port.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b51b7aaacdd..6d83db88b9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -228,10 +228,6 @@ elseif((FREERTOS_PORT STREQUAL "A_CUSTOM_PORT") AND (NOT TARGET freertos_kernel_ " freertos_kernel)") endif() -######################################################################## -# Requirements -set_property(TARGET freertos_kernel PROPERTY C_STANDARD 90) - ######################################################################## # Overall Compile Options # Note the compile option strategy is to error on everything and then @@ -294,3 +290,7 @@ target_link_libraries(freertos_kernel $<$:freertos_config> freertos_kernel_port ) + +######################################################################## +# Requirements +set_property(TARGET freertos_kernel PROPERTY C_STANDARD 90) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 12076b9898d..d634c8b264e 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -343,7 +343,7 @@ static uint64_t prvGetTimeNs( void ) clock_gettime( CLOCK_MONOTONIC, &t ); - return ( uint64_t )t.tv_sec * 1000000000ULL + ( uint64_t )t.tv_nsec; + return ( uint64_t )t.tv_sec * ( uint64_t )1000000000UL + ( uint64_t )t.tv_nsec; } static uint64_t prvStartTimeNs; From 55658e15250132fd5671dedbbc43bd69eab3b3d9 Mon Sep 17 00:00:00 2001 From: Holden Date: Sat, 11 Mar 2023 12:34:15 -0500 Subject: [PATCH 062/109] Add missing FreeRTOS+ defines --- include/projdefs.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/projdefs.h b/include/projdefs.h index 67fc5351937..c81ad568436 100644 --- a/include/projdefs.h +++ b/include/projdefs.h @@ -44,6 +44,10 @@ typedef void (* TaskFunction_t)( void * ); #define pdFALSE ( ( BaseType_t ) 0 ) #define pdTRUE ( ( BaseType_t ) 1 ) +#define pdFALSE_SIGNED ( ( BaseType_t ) 0 ) +#define pdTRUE_SIGNED ( ( BaseType_t ) 1 ) +#define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0 ) +#define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1 ) #define pdPASS ( pdTRUE ) #define pdFAIL ( pdFALSE ) @@ -100,6 +104,7 @@ typedef void (* TaskFunction_t)( void * ); #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define pdFREERTOS_ERRNO_EAFNOSUPPORT 97 /* Address family not supported by protocol */ #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ From d4d5e43292a57df354dcf8f33d938283f2082855 Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Fri, 17 Mar 2023 08:22:34 +0530 Subject: [PATCH 063/109] Run kernel demos and unit tests for PR changes (#645) * Run kernel demos and unit tests for PR changes Kernel demos check builds multiple demos from FreeRTOS/FreeRTOS and unit tests check runs unit tests in FreeRTOS/FreeRTOS. Both of these checks currently use main branch of FreeRTOS-Kernel. This commits updates these checks to use the changes in the PR. Signed-off-by: Gaurav Aggarwal * Do not specify PR SHA explicitly as that is default Signed-off-by: Gaurav Aggarwal * Remove explicit PR SHA from kernel checks Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal --- .github/workflows/kernel-checks.yml | 1 - .github/workflows/kernel-demos.yml | 42 +++++++++++++++++------------ .github/workflows/unit-tests.yml | 4 ++- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/.github/workflows/kernel-checks.yml b/.github/workflows/kernel-checks.yml index b295033d28a..a4627f0e07c 100644 --- a/.github/workflows/kernel-checks.yml +++ b/.github/workflows/kernel-checks.yml @@ -28,7 +28,6 @@ jobs: - name: Checkout Pull Request uses: actions/checkout@v2 with: - ref: ${{ github.event.pull_request.head.sha }} path: inspect # Collect all affected files diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml index d6eace575ae..96a4c59759e 100644 --- a/.github/workflows/kernel-demos.yml +++ b/.github/workflows/kernel-demos.yml @@ -14,10 +14,11 @@ jobs: submodules: 'recursive' fetch-depth: 1 - - name: Fetch Kernel Submodule - shell: bash - run: | - git submodule update --checkout --init --depth 1 FreeRTOS/Source + # Checkout user pull request changes + - name: Checkout Pull Request + uses: actions/checkout@v2 + with: + path: ./FreeRTOS/Source - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 @@ -42,10 +43,11 @@ jobs: submodules: 'recursive' fetch-depth: 1 - - name: Fetch Kernel Submodule - shell: bash - run: | - git submodule update --checkout --init --depth 1 FreeRTOS/Source + # Checkout user pull request changes + - name: Checkout Pull Request + uses: actions/checkout@v2 + with: + path: ./FreeRTOS/Source - name: Build WIN32-MingW Demo working-directory: FreeRTOS/Demo/WIN32-MingW @@ -66,9 +68,11 @@ jobs: submodules: 'recursive' fetch-depth: 1 - - name: Fetch Kernel Submodule - shell: bash - run: git submodule update --checkout --init --depth 1 FreeRTOS/Source + # Checkout user pull request changes + - name: Checkout Pull Request + uses: actions/checkout@v2 + with: + path: ./FreeRTOS/Source - name: Install GCC shell: bash @@ -93,9 +97,11 @@ jobs: submodules: 'recursive' fetch-depth: 1 - - name: Fetch Kernel Submodule - shell: bash - run: git submodule update --checkout --init --depth 1 FreeRTOS/Source + # Checkout user pull request changes + - name: Checkout Pull Request + uses: actions/checkout@v2 + with: + path: ./FreeRTOS/Source - name: Install MSP430 Toolchain shell: bash @@ -120,9 +126,11 @@ jobs: submodules: 'recursive' fetch-depth: 1 - - name: Fetch Kernel Submodule - shell: bash - run: git submodule update --checkout --init --depth 1 FreeRTOS/Source + # Checkout user pull request changes + - name: Checkout Pull Request + uses: actions/checkout@v2 + with: + path: ./FreeRTOS/Source - name: Install GNU ARM Toolchain shell: bash diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index a714b757256..73e1808fa25 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -12,7 +12,9 @@ jobs: repository: FreeRTOS/FreeRTOS submodules: 'recursive' fetch-depth: 1 - - name: Clone This Repo + + # Checkout user pull request changes + - name: Checkout Pull Request uses: actions/checkout@v2 with: path: ./FreeRTOS/Source From 9488ba22d833f2c0746903dfc312b5add887ec8b Mon Sep 17 00:00:00 2001 From: Darian <32921628+Dazza0@users.noreply.github.com> Date: Thu, 23 Mar 2023 06:27:57 +0800 Subject: [PATCH 064/109] Add functions to get the buffers of statically created objects (#641) Added various ...GetStaticBuffer() functions to get the buffers of statically created objects. --------- Co-authored-by: Paul Bartell Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal --- .github/lexicon.txt | 19 ++++++++++++++++ event_groups.c | 36 +++++++++++++++++++++++++++++ include/event_groups.h | 22 ++++++++++++++++++ include/message_buffer.h | 31 +++++++++++++++++++++++++ include/queue.h | 41 +++++++++++++++++++++++++++++++++ include/semphr.h | 21 +++++++++++++++++ include/stream_buffer.h | 32 ++++++++++++++++++++++++++ include/task.h | 30 ++++++++++++++++++++++++ include/timers.h | 20 ++++++++++++++++ queue.c | 49 ++++++++++++++++++++++++++++++++++++++++ stream_buffer.c | 28 +++++++++++++++++++++++ tasks.c | 47 ++++++++++++++++++++++++++++++++++++++ timers.c | 24 ++++++++++++++++++++ 13 files changed, 400 insertions(+) diff --git a/.github/lexicon.txt b/.github/lexicon.txt index 47d2349bfff..e7ded970dbd 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -1464,13 +1464,24 @@ ppdc ppio ppitc ppmc +ppucmessagebufferstoragearea +ppucqueuestorage +ppucstreambufferstoragearea ppudr ppuer ppusr +ppuxstackbuffer ppvdestination ppwm +ppxeventgroupbuffer ppxidletaskstackbuffer ppxidletasktcbbuffer +ppxsemaphorebuffer +ppxstaticmessagebuffer +ppxstaticqueue +ppxstaticstreambuffer +ppxtaskbuffer +ppxtimerbuffer ppxtimertaskstackbuffer ppxtimertasktcbbuffer pr @@ -2723,6 +2734,7 @@ xeventgroupcreatestatic xeventgroupdelete xeventgroupgetbits xeventgroupgetbitsfromisr +xeventgroupgetstaticbuffer xeventgroupsetbits xeventgroupsetbitsfromisr xeventgroupsync @@ -2796,6 +2808,7 @@ xmessage xmessagebuffer xmessagebuffercreate xmessagebuffercreatestatic +xmessagebuffergetstaticbuffers xmessagebufferisempty xmessagebufferisfull xmessagebuffernextlengthbytes @@ -2865,6 +2878,7 @@ xqueuecreatestatic xqueuegenericsend xqueuegenericsendfromisr xqueuegetmutexholder +xqueuegetstaticbuffers xqueuegivefromisr xqueuegivemutexrecursive xqueueorsemaphore @@ -2919,6 +2933,7 @@ xsemaphorecreaterecursivemutex xsemaphorecreaterecursivemutexstatic xsemaphoregetmutexholder xsemaphoregetmutexholderfromisr +xsemaphoregetstaticbuffer xsemaphoregive xsemaphoregivefromisr xsemaphoregivemutexrecursive @@ -2943,6 +2958,7 @@ xstreambuffer xstreambufferbytesavailable xstreambuffercreate xstreambuffercreatestatic +xstreambuffergetstaticbuffers xstreambufferisempty xstreambufferisfull xstreambuffernextmessagelengthbytes @@ -2981,6 +2997,7 @@ xtaskgetcurrenttaskhandle xtaskgethandle xtaskgetidletaskhandle xtaskgetschedulerstate +xtaskgetstaticbuffers xtaskgettickcount xtaskgettickcountfromisr xtaskhandle @@ -3048,6 +3065,7 @@ xtimerdelete xtimergetexpirytime xtimergetperiod xtimergetreloadmode +xtimergetstaticbuffer xtimergettimerdaemontaskhandle xtimeristimeractive xtimerlistitem @@ -3081,3 +3099,4 @@ xwritevalue xxr xyieldpending xzr + diff --git a/event_groups.c b/event_groups.c index 7c86e605a88..5c4b4297baf 100644 --- a/event_groups.c +++ b/event_groups.c @@ -677,6 +677,42 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) } /*-----------------------------------------------------------*/ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) + { + BaseType_t xReturn; + EventGroup_t * pxEventBits = xEventGroup; + + configASSERT( pxEventBits ); + configASSERT( ppxEventGroupBuffer ); + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Check if the event group was statically allocated. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE ) + { + *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + #else /* configSUPPORT_DYNAMIC_ALLOCATION */ + { + /* Event group must have been statically allocated. */ + *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; + xReturn = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + /* For internal use only - execute a 'set bits' command that was pended from * an interrupt. */ void vEventGroupSetBitsCallback( void * pvEventGroup, diff --git a/include/event_groups.h b/include/event_groups.h index 3f37d90be5d..47572ce94e4 100644 --- a/include/event_groups.h +++ b/include/event_groups.h @@ -763,6 +763,28 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG */ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; +/** + * event_groups.h + * @code{c} + * BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + * StaticEventGroup_t ** ppxEventGroupBuffer ); + * @endcode + * + * Retrieve a pointer to a statically created event groups's data structure + * buffer. It is the same buffer that is supplied at the time of creation. + * + * @param xEventGroup The event group for which to retrieve the buffer. + * + * @param ppxEventGroupBuffer Used to return a pointer to the event groups's + * data structure buffer. + * + * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /* For internal use only. */ void vEventGroupSetBitsCallback( void * pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; diff --git a/include/message_buffer.h b/include/message_buffer.h index b56dd35964e..74fab118f51 100644 --- a/include/message_buffer.h +++ b/include/message_buffer.h @@ -245,6 +245,37 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif +/** + * message_buffer.h + * + * @code{c} + * BaseType_t xMessageBufferGetStaticBuffers( MessageBufferHandle_t xMessageBuffer, + * uint8_t ** ppucMessageBufferStorageArea, + * StaticMessageBuffer_t ** ppxStaticMessageBuffer ); + * @endcode + * + * Retrieve pointers to a statically created message buffer's data structure + * buffer and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xMessageBuffer The message buffer for which to retrieve the buffers. + * + * @param ppucMessageBufferStorageArea Used to return a pointer to the + * message buffer's storage area buffer. + * + * @param ppxStaticMessageBuffer Used to return a pointer to the message + * buffer's data structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise.. + * + * \defgroup xMessageBufferGetStaticBuffers xMessageBufferGetStaticBuffers + * \ingroup MessageBufferManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xMessageBufferGetStaticBuffers( xMessageBuffer, ppucMessageBufferStorageArea, ppxStaticMessageBuffer ) \ + xStreamBufferGetStaticBuffers( ( xMessageBuffer ), ( ppucMessageBufferStorageArea ), ( ppxStaticMessageBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /** * message_buffer.h * diff --git a/include/queue.h b/include/queue.h index f488a2e7641..66c8286aef0 100644 --- a/include/queue.h +++ b/include/queue.h @@ -235,6 +235,35 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) #endif /* configSUPPORT_STATIC_ALLOCATION */ +/** + * queue. h + * @code{c} + * BaseType_t xQueueGetStaticBuffers( QueueHandle_t xQueue, + * uint8_t ** ppucQueueStorage, + * StaticQueue_t ** ppxStaticQueue ); + * @endcode + * + * Retrieve pointers to a statically created queue's data structure buffer + * and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xQueue The queue for which to retrieve the buffers. + * + * @param ppucQueueStorage Used to return a pointer to the queue's storage + * area buffer. + * + * @param ppxStaticQueue Used to return a pointer to the queue's data + * structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \defgroup xQueueGetStaticBuffers xQueueGetStaticBuffers + * \ingroup QueueManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueGetStaticBuffers( xQueue, ppucQueueStorage, ppxStaticQueue ) xQueueGenericGetStaticBuffers( ( xQueue ), ( ppucQueueStorage ), ( ppxStaticQueue ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /** * queue. h * @code{c} @@ -1542,6 +1571,18 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; #endif +/* + * Generic version of the function used to retrieve the buffers of statically + * created queues. This is called by other functions and macros that retrieve + * the buffers of other statically created RTOS objects that use the queue + * structure as their base. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, + uint8_t ** ppucQueueStorage, + StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION; +#endif + /* * Queue sets provide a mechanism to allow a task to block (pend) on a read * operation from multiple queues or semaphores simultaneously. diff --git a/include/semphr.h b/include/semphr.h index c2206fa98ff..7977a01b84e 100644 --- a/include/semphr.h +++ b/include/semphr.h @@ -1190,4 +1190,25 @@ typedef QueueHandle_t SemaphoreHandle_t; */ #define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) ) +/** + * semphr.h + * @code{c} + * BaseType_t xSemaphoreGetStaticBuffer( SemaphoreHandle_t xSemaphore ); + * @endcode + * + * Retrieve pointer to a statically created binary semaphore, counting semaphore, + * or mutex semaphore's data structure buffer. This is the same buffer that is + * supplied at the time of creation. + * + * @param xSemaphore The semaphore for which to retrieve the buffer. + * + * @param ppxSemaphoreBuffer Used to return a pointer to the semaphore's + * data structure buffer. + * + * @return pdTRUE if buffer was retrieved, pdFALSE otherwise. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreGetStaticBuffer( xSemaphore, ppxSemaphoreBuffer ) xQueueGenericGetStaticBuffers( ( QueueHandle_t ) ( xSemaphore ), NULL, ( ppxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + #endif /* SEMAPHORE_H */ diff --git a/include/stream_buffer.h b/include/stream_buffer.h index d65ed9e9cec..521c178ef5a 100644 --- a/include/stream_buffer.h +++ b/include/stream_buffer.h @@ -260,6 +260,38 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer, + * uint8_t ** ppucStreamBufferStorageArea, + * StaticStreamBuffer_t ** ppxStaticStreamBuffer ); + * @endcode + * + * Retrieve pointers to a statically created stream buffer's data structure + * buffer and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xStreamBuffer The stream buffer for which to retrieve the buffers. + * + * @param ppucStreamBufferStorageArea Used to return a pointer to the stream + * buffer's storage area buffer. + * + * @param ppxStaticStreamBuffer Used to return a pointer to the stream + * buffer's data structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \defgroup xStreamBufferGetStaticBuffers xStreamBufferGetStaticBuffers + * \ingroup StreamBufferManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer, + uint8_t ** ppucStreamBufferStorageArea, + StaticStreamBuffer_t ** ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /** * stream_buffer.h * diff --git a/include/task.h b/include/task.h index 08c14dd6ff1..054f43644a1 100644 --- a/include/task.h +++ b/include/task.h @@ -1509,6 +1509,36 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e */ TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +/** + * task. h + * @code{c} + * BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask, + * StackType_t ** ppuxStackBuffer, + * StaticTask_t ** ppxTaskBuffer ); + * @endcode + * + * Retrieve pointers to a statically created task's data structure + * buffer and stack buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xTask The task for which to retrieve the buffers. + * + * @param ppuxStackBuffer Used to return a pointer to the task's stack buffer. + * + * @param ppxTaskBuffer Used to return a pointer to the task's data structure + * buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \defgroup xTaskGetStaticBuffers xTaskGetStaticBuffers + * \ingroup TaskUtils + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask, + StackType_t ** ppuxStackBuffer, + StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /** * task.h * @code{c} diff --git a/include/timers.h b/include/timers.h index 6a064d62a41..2967a4674c7 100644 --- a/include/timers.h +++ b/include/timers.h @@ -1323,6 +1323,26 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; */ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; +/** + * BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer, + * StaticTimer_t ** ppxTimerBuffer ); + * + * Retrieve pointer to a statically created timer's data structure + * buffer. This is the same buffer that is supplied at the time of + * creation. + * + * @param xTimer The timer for which to retrieve the buffer. + * + * @param ppxTaskBuffer Used to return a pointer to the timers's data + * structure buffer. + * + * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer, + StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /* * Functions beyond this part are not part of the public API and are intended * for use by the kernel only. diff --git a/queue.c b/queue.c index ca6bfbc60dc..662052f5ef6 100644 --- a/queue.c +++ b/queue.c @@ -419,6 +419,55 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue, #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, + uint8_t ** ppucQueueStorage, + StaticQueue_t ** ppxStaticQueue ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( ppxStaticQueue ); + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Check if the queue was statically allocated. */ + if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdTRUE ) + { + if( ppucQueueStorage != NULL ) + { + *ppucQueueStorage = ( uint8_t * ) pxQueue->pcHead; + } + + *ppxStaticQueue = ( StaticQueue_t * ) pxQueue; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + #else /* configSUPPORT_DYNAMIC_ALLOCATION */ + { + /* Queue must have been statically allocated. */ + if( ppucQueueStorage != NULL ) + { + *ppucQueueStorage = ( uint8_t * ) pxQueue->pcHead; + } + + *ppxStaticQueue = ( StaticQueue_t * ) pxQueue; + xReturn = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + return xReturn; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, diff --git a/stream_buffer.c b/stream_buffer.c index 0d0b3350acd..938c4051cec 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -472,6 +472,34 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, #endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer, + uint8_t ** ppucStreamBufferStorageArea, + StaticStreamBuffer_t ** ppxStaticStreamBuffer ) + { + BaseType_t xReturn; + const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + configASSERT( ppucStreamBufferStorageArea ); + configASSERT( ppxStaticStreamBuffer ); + + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) != ( uint8_t ) 0 ) + { + *ppucStreamBufferStorageArea = pxStreamBuffer->pucBuffer; + *ppxStaticStreamBuffer = ( StaticStreamBuffer_t * ) pxStreamBuffer; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) { StreamBuffer_t * pxStreamBuffer = xStreamBuffer; diff --git a/tasks.c b/tasks.c index 0e7a56c6058..befd63e2279 100644 --- a/tasks.c +++ b/tasks.c @@ -2489,6 +2489,53 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char #endif /* INCLUDE_xTaskGetHandle */ /*-----------------------------------------------------------*/ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask, + StackType_t ** ppuxStackBuffer, + StaticTask_t ** ppxTaskBuffer ) + { + BaseType_t xReturn; + TCB_t * pxTCB; + + configASSERT( ppuxStackBuffer != NULL ); + configASSERT( ppxTaskBuffer != NULL ); + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 ) + { + if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ) + { + *ppuxStackBuffer = pxTCB->pxStack; + *ppxTaskBuffer = ( StaticTask_t * ) pxTCB; + xReturn = pdTRUE; + } + else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) + { + *ppuxStackBuffer = pxTCB->pxStack; + *ppxTaskBuffer = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + #else /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 */ + { + *ppuxStackBuffer = pxTCB->pxStack; + *ppxTaskBuffer = ( StaticTask_t * ) pxTCB; + xReturn = pdTRUE; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 */ + + return xReturn; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, diff --git a/timers.c b/timers.c index 06a29279597..76a59a8b999 100644 --- a/timers.c +++ b/timers.c @@ -510,6 +510,30 @@ } /*-----------------------------------------------------------*/ + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer, + StaticTimer_t ** ppxTimerBuffer ) + { + BaseType_t xReturn; + Timer_t * pxTimer = xTimer; + + configASSERT( ppxTimerBuffer != NULL ); + + if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) != 0 ) + { + *ppxTimerBuffer = ( StaticTimer_t * ) pxTimer; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { Timer_t * pxTimer = xTimer; From 99797e14e3c041ce520682694e27533bfafb0cb0 Mon Sep 17 00:00:00 2001 From: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> Date: Thu, 23 Mar 2023 15:06:33 +0530 Subject: [PATCH 065/109] Cortex-M Assert when NVIC implements 8 PRIO bits (#639) * Cortex-M Assert when NVIC implements 8 PRIO bits * Fix CM3 ports * Fix ARM_CM3_MPU * Fix ARM CM3 * Fix ARM_CM4_MPU * Fix ARM_CM4 * Fix GCC ARM_CM7 * Fix IAR ARM ports * Uncrustify changes * Fix MikroC_ARM_CM4F port * Fix MikroC_ARM_CM4F port-(2) * Fix RVDS ARM ports * Revert changes for Tasking/ARM_CM4F port * Revert changes for Tasking/ARM_CM4F port-(2) * Update port.c Fix GCC/ARM_CM4F port * Update port.c * update GCC\ARM_CM4F port * update port.c * Assert to check configMAX_SYSCALL_INTERRUPT_PRIORITY is set to higher priority * Fix merge error: remove duplicate code * Fix typos --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Ubuntu --- portable/CCS/ARM_CM3/port.c | 63 +++++-- portable/CCS/ARM_CM4F/port.c | 63 +++++-- portable/GCC/ARM_CM3/port.c | 37 +++- portable/GCC/ARM_CM3_MPU/port.c | 37 +++- portable/GCC/ARM_CM4F/port.c | 73 +++++--- portable/GCC/ARM_CM4_MPU/port.c | 37 +++- portable/GCC/ARM_CM7/r0p1/port.c | 77 +++++--- portable/IAR/ARM_CM3/port.c | 35 +++- portable/IAR/ARM_CM4F/port.c | 35 +++- portable/IAR/ARM_CM4F_MPU/port.c | 293 +++++++++++++++++------------- portable/IAR/ARM_CM7/r0p1/port.c | 35 +++- portable/MikroC/ARM_CM4F/port.c | 35 +++- portable/RVDS/ARM_CM3/port.c | 35 +++- portable/RVDS/ARM_CM4F/port.c | 35 +++- portable/RVDS/ARM_CM4_MPU/port.c | 243 ++++++++++++++----------- portable/RVDS/ARM_CM7/r0p1/port.c | 35 +++- portable/Tasking/ARM_CM4F/port.c | 3 +- 17 files changed, 805 insertions(+), 366 deletions(-) mode change 100644 => 100755 portable/CCS/ARM_CM3/port.c mode change 100644 => 100755 portable/CCS/ARM_CM4F/port.c mode change 100644 => 100755 portable/GCC/ARM_CM3/port.c mode change 100644 => 100755 portable/GCC/ARM_CM3_MPU/port.c mode change 100644 => 100755 portable/GCC/ARM_CM4F/port.c mode change 100644 => 100755 portable/GCC/ARM_CM4_MPU/port.c mode change 100644 => 100755 portable/GCC/ARM_CM7/r0p1/port.c mode change 100644 => 100755 portable/IAR/ARM_CM3/port.c mode change 100644 => 100755 portable/IAR/ARM_CM4F/port.c mode change 100644 => 100755 portable/IAR/ARM_CM4F_MPU/port.c mode change 100644 => 100755 portable/IAR/ARM_CM7/r0p1/port.c mode change 100644 => 100755 portable/MikroC/ARM_CM4F/port.c mode change 100644 => 100755 portable/RVDS/ARM_CM3/port.c mode change 100644 => 100755 portable/RVDS/ARM_CM4F/port.c mode change 100644 => 100755 portable/RVDS/ARM_CM4_MPU/port.c mode change 100644 => 100755 portable/RVDS/ARM_CM7/r0p1/port.c mode change 100644 => 100755 portable/Tasking/ARM_CM4F/port.c diff --git a/portable/CCS/ARM_CM3/port.c b/portable/CCS/ARM_CM3/port.c old mode 100644 new mode 100755 index dfdb240ed2b..63dc600a756 --- a/portable/CCS/ARM_CM3/port.c +++ b/portable/CCS/ARM_CM3/port.c @@ -219,6 +219,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -250,20 +251,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -272,7 +299,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif @@ -379,9 +406,9 @@ void xPortSysTickHandler( void ) /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ - __asm( " cpsid i"); - __asm( " dsb"); - __asm( " isb"); + __asm( " cpsid i" ); + __asm( " dsb" ); + __asm( " isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ @@ -389,7 +416,7 @@ void xPortSysTickHandler( void ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ - __asm( " cpsie i"); + __asm( " cpsie i" ); } else { @@ -450,9 +477,9 @@ void xPortSysTickHandler( void ) if( xModifiableIdleTime > 0 ) { - __asm( " dsb"); - __asm( " wfi"); - __asm( " isb"); + __asm( " dsb" ); + __asm( " wfi" ); + __asm( " isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); @@ -460,17 +487,17 @@ void xPortSysTickHandler( void ) /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ - __asm( " cpsie i"); - __asm( " dsb"); - __asm( " isb"); + __asm( " cpsie i" ); + __asm( " dsb" ); + __asm( " isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ - __asm( " cpsid i"); - __asm( " dsb"); - __asm( " isb"); + __asm( " cpsid i" ); + __asm( " dsb" ); + __asm( " isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the @@ -578,7 +605,7 @@ void xPortSysTickHandler( void ) vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ - __asm( " cpsie i"); + __asm( " cpsie i" ); } } diff --git a/portable/CCS/ARM_CM4F/port.c b/portable/CCS/ARM_CM4F/port.c old mode 100644 new mode 100755 index 360e83d7000..a741b091561 --- a/portable/CCS/ARM_CM4F/port.c +++ b/portable/CCS/ARM_CM4F/port.c @@ -238,6 +238,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -269,20 +270,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -291,7 +318,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif @@ -404,9 +431,9 @@ void xPortSysTickHandler( void ) /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ - __asm( " cpsid i"); - __asm( " dsb"); - __asm( " isb"); + __asm( " cpsid i" ); + __asm( " dsb" ); + __asm( " isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ @@ -414,7 +441,7 @@ void xPortSysTickHandler( void ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ - __asm( " cpsie i"); + __asm( " cpsie i" ); } else { @@ -475,9 +502,9 @@ void xPortSysTickHandler( void ) if( xModifiableIdleTime > 0 ) { - __asm( " dsb"); - __asm( " wfi"); - __asm( " isb"); + __asm( " dsb" ); + __asm( " wfi" ); + __asm( " isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); @@ -485,17 +512,17 @@ void xPortSysTickHandler( void ) /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ - __asm( " cpsie i"); - __asm( " dsb"); - __asm( " isb"); + __asm( " cpsie i" ); + __asm( " dsb" ); + __asm( " isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ - __asm( " cpsid i"); - __asm( " dsb"); - __asm( " isb"); + __asm( " cpsid i" ); + __asm( " dsb" ); + __asm( " isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the @@ -603,7 +630,7 @@ void xPortSysTickHandler( void ) vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ - __asm( " cpsie i"); + __asm( " cpsie i" ); } } diff --git a/portable/GCC/ARM_CM3/port.c b/portable/GCC/ARM_CM3/port.c old mode 100644 new mode 100755 index a5cea1e1e1b..57337e60502 --- a/portable/GCC/ARM_CM3/port.c +++ b/portable/GCC/ARM_CM3/port.c @@ -262,6 +262,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -293,20 +294,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -315,7 +342,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif @@ -756,4 +783,4 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } -#endif /* configASSERT_DEFINED */ +#endif /* configASSERT_DEFINED */ \ No newline at end of file diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c old mode 100644 new mode 100755 index 5f7d2c81113..4b21236e785 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -385,6 +385,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -416,20 +417,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -438,7 +465,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif @@ -923,4 +950,4 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } #endif /* configASSERT_DEFINED */ -/*-----------------------------------------------------------*/ +/*-----------------------------------------------------------*/ \ No newline at end of file diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c old mode 100644 new mode 100755 index b978f0af54c..84e79130487 --- a/portable/GCC/ARM_CM4F/port.c +++ b/portable/GCC/ARM_CM4F/port.c @@ -251,11 +251,11 @@ static void prvTaskExitError( void ) void vPortSVCHandler( void ) { __asm volatile ( - " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ - " ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ - " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */ - " ldmia r0!, {r4-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ - " msr psp, r0 \n"/* Restore the task stack pointer. */ + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" @@ -274,17 +274,17 @@ static void prvPortStartFirstTask( void ) * would otherwise result in the unnecessary leaving of space in the SVC stack * for lazy saving of FPU registers. */ __asm volatile ( - " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" - " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ - " mov r0, #0 \n"/* Clear the bit that indicates the FPU is in use, see comment above. */ + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ " msr control, r0 \n" - " cpsie i \n"/* Globally enable interrupts. */ + " cpsie i \n" /* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" - " svc 0 \n"/* System call to start first task. */ + " svc 0 \n" /* System call to start first task. */ " nop \n" " .ltorg \n" ); @@ -305,6 +305,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -336,20 +337,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -358,7 +385,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif @@ -453,15 +480,15 @@ void xPortPendSVHandler( void ) " mrs r0, psp \n" " isb \n" " \n" - " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" - " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n" " \n" - " stmdb r0!, {r4-r11, r14} \n"/* Save the core registers. */ - " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ + " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ " \n" " stmdb sp!, {r0, r3} \n" " mov r0, %0 \n" @@ -473,12 +500,12 @@ void xPortPendSVHandler( void ) " msr basepri, r0 \n" " ldmia sp!, {r0, r3} \n" " \n" - " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" " \n" - " ldmia r0!, {r4-r11, r14} \n"/* Pop the core registers. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */ " \n" - " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n" " \n" @@ -772,10 +799,10 @@ static void vPortEnableVFP( void ) { __asm volatile ( - " ldr.w r0, =0xE000ED88 \n"/* The FPU enable bits are in the CPACR. */ + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ " ldr r1, [r0] \n" " \n" - " orr r1, r1, #( 0xf << 20 ) \n"/* Enable CP10 and CP11 coprocessors, then save back. */ + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ " str r1, [r0] \n" " bx r14 \n" " .ltorg \n" diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c old mode 100644 new mode 100755 index 57d0ea5a2f6..682b64ea8c1 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -428,6 +428,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -459,20 +460,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -481,7 +508,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif @@ -1046,4 +1073,4 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } #endif /* configASSERT_DEFINED */ -/*-----------------------------------------------------------*/ +/*-----------------------------------------------------------*/ \ No newline at end of file diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c old mode 100644 new mode 100755 index c602bd297cd..25a06bf46e2 --- a/portable/GCC/ARM_CM7/r0p1/port.c +++ b/portable/GCC/ARM_CM7/r0p1/port.c @@ -245,11 +245,11 @@ static void prvTaskExitError( void ) void vPortSVCHandler( void ) { __asm volatile ( - " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ - " ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ - " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */ - " ldmia r0!, {r4-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ - " msr psp, r0 \n"/* Restore the task stack pointer. */ + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" @@ -268,17 +268,17 @@ static void prvPortStartFirstTask( void ) * would otherwise result in the unnecessary leaving of space in the SVC stack * for lazy saving of FPU registers. */ __asm volatile ( - " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" - " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ - " mov r0, #0 \n"/* Clear the bit that indicates the FPU is in use, see comment above. */ + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ " msr control, r0 \n" - " cpsie i \n"/* Globally enable interrupts. */ + " cpsie i \n" /* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" - " svc 0 \n"/* System call to start first task. */ + " svc 0 \n" /* System call to start first task. */ " nop \n" " .ltorg \n" ); @@ -293,6 +293,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -324,20 +325,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -346,7 +373,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif @@ -441,34 +468,34 @@ void xPortPendSVHandler( void ) " mrs r0, psp \n" " isb \n" " \n" - " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" - " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n" " \n" - " stmdb r0!, {r4-r11, r14} \n"/* Save the core registers. */ - " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ + " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ " \n" " stmdb sp!, {r0, r3} \n" " mov r0, %0 \n" - " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ + " cpsid i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ " msr basepri, r0 \n" " dsb \n" " isb \n" - " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ + " cpsie i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ " bl vTaskSwitchContext \n" " mov r0, #0 \n" " msr basepri, r0 \n" " ldmia sp!, {r0, r3} \n" " \n" - " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" " \n" - " ldmia r0!, {r4-r11, r14} \n"/* Pop the core registers. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */ " \n" - " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n" " \n" @@ -762,10 +789,10 @@ static void vPortEnableVFP( void ) { __asm volatile ( - " ldr.w r0, =0xE000ED88 \n"/* The FPU enable bits are in the CPACR. */ + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ " ldr r1, [r0] \n" " \n" - " orr r1, r1, #( 0xf << 20 ) \n"/* Enable CP10 and CP11 coprocessors, then save back. */ + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ " str r1, [r0] \n" " bx r14 \n" " .ltorg \n" diff --git a/portable/IAR/ARM_CM3/port.c b/portable/IAR/ARM_CM3/port.c old mode 100644 new mode 100755 index f35ee98c798..a7a5ad86bd2 --- a/portable/IAR/ARM_CM3/port.c +++ b/portable/IAR/ARM_CM3/port.c @@ -211,6 +211,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -242,20 +243,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -264,7 +291,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM4F/port.c b/portable/IAR/ARM_CM4F/port.c old mode 100644 new mode 100755 index 90be11d0eda..9b4ed52fae5 --- a/portable/IAR/ARM_CM4F/port.c +++ b/portable/IAR/ARM_CM4F/port.c @@ -249,6 +249,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -280,20 +281,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -302,7 +329,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c old mode 100644 new mode 100755 index dd6bde281c2..6aec5b34262 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -194,7 +194,7 @@ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ -#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) +#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; @@ -203,7 +203,7 @@ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ -#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) +#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; @@ -316,9 +316,9 @@ void vPortSVCHandler_C( uint32_t * pulParam ) { __asm volatile ( - " mrs r1, control \n"/* Obtain current control value. */ - " bic r1, r1, #1 \n"/* Set privilege bit. */ - " msr control, r1 \n"/* Write back new control value. */ + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, r1, #1 \n" /* Set privilege bit. */ + " msr control, r1 \n" /* Write back new control value. */ ::: "r1", "memory" ); } @@ -328,9 +328,9 @@ void vPortSVCHandler_C( uint32_t * pulParam ) case portSVC_RAISE_PRIVILEGE: __asm volatile ( - " mrs r1, control \n"/* Obtain current control value. */ - " bic r1, r1, #1 \n"/* Set privilege bit. */ - " msr control, r1 \n"/* Write back new control value. */ + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, r1, #1 \n" /* Set privilege bit. */ + " msr control, r1 \n" /* Write back new control value. */ ::: "r1", "memory" ); break; @@ -352,6 +352,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) ); #else + /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define * configENABLE_ERRATA_837070_WORKAROUND to 1 in your * FreeRTOSConfig.h. */ @@ -360,74 +361,101 @@ BaseType_t xPortStartScheduler( void ) #endif #if ( configASSERT_DEFINED == 1 ) - { - volatile uint32_t ulOriginalPriority; - volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); - volatile uint8_t ucMaxPriorityValue; - - /* Determine the maximum priority from which ISR safe FreeRTOS API - * functions can be called. ISR safe functions are those that end in - * "FromISR". FreeRTOS maintains separate thread and ISR API functions to - * ensure interrupt entry is as fast and simple as possible. - * - * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + { + volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + * functions can be called. ISR safe functions are those that end in + * "FromISR". FreeRTOS maintains separate thread and ISR API functions to + * ensure interrupt entry is as fast and simple as possible. + * + * Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; - /* Determine the number of priority bits available. First write to all - * possible bits. */ - *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + /* Determine the number of priority bits available. First write to all + * possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; - /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = *pucFirstUserPriorityRegister; + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; - /* Use the same mask on the maximum system call priority. */ - ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; - /* Check that the maximum system call priority is nonzero after - * accounting for the number of priority bits supported by the - * hardware. A priority of 0 is invalid because setting the BASEPRI - * register to 0 unmasks all interrupts, and interrupts with priority 0 - * cannot be masked using BASEPRI. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( ucMaxSysCallPriority ); + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); - /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + /* Calculate the maximum acceptable priority group value for the number + * of bits read back. */ - while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) - { - ulMaxPRIGROUPValue--; - ucMaxPriorityValue <<= ( uint8_t ) 0x01; - } + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulImplementedPrioBits++; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } - #ifdef __NVIC_PRIO_BITS - { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); - } - #endif - - /* Shift the priority group value back to its position within the AIRCR - * register. */ - ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; - ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; - - /* Restore the clobbered interrupt priority register to its original - * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + * priority bits matches the number of priority bits actually queried + * from the hardware. */ + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + * priority bits matches the number of priority bits actually queried + * from the hardware. */ + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } + #endif + + /* Shift the priority group value back to its position within the AIRCR + * register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + * value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ @@ -468,32 +496,49 @@ void vPortEndScheduler( void ) void vPortEnterCritical( void ) { -#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) - if( portIS_PRIVILEGED() == pdFALSE ) - { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + * assert() if it is being called from an interrupt context. Only API + * functions that end in "FromISR" can be used in an interrupt. Only assert if + * the critical nesting count is 1 to protect against recursive calls if the + * assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } - portDISABLE_INTERRUPTS(); - uxCriticalNesting++; - /* This is not the interrupt safe version of the enter critical function so - * assert() if it is being called from an interrupt context. Only API - * functions that end in "FromISR" can be used in an interrupt. Only assert if - * the critical nesting count is 1 to protect against recursive calls if the - * assert function also uses a critical section. */ - if( uxCriticalNesting == 1 ) + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else { - configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + * assert() if it is being called from an interrupt context. Only API + * functions that end in "FromISR" can be used in an interrupt. Only assert if + * the critical nesting count is 1 to protect against recursive calls if the + * assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } } - portMEMORY_BARRIER(); - - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); - } - else - { + #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */ portDISABLE_INTERRUPTS(); uxCriticalNesting++; + /* This is not the interrupt safe version of the enter critical function so * assert() if it is being called from an interrupt context. Only API * functions that end in "FromISR" can be used in an interrupt. Only assert if @@ -503,45 +548,42 @@ void vPortEnterCritical( void ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } - } -#else - portDISABLE_INTERRUPTS(); - uxCriticalNesting++; - /* This is not the interrupt safe version of the enter critical function so - * assert() if it is being called from an interrupt context. Only API - * functions that end in "FromISR" can be used in an interrupt. Only assert if - * the critical nesting count is 1 to protect against recursive calls if the - * assert function also uses a critical section. */ - if( uxCriticalNesting == 1 ) - { - configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); - } -#endif + #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */ } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { -#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) - if( portIS_PRIVILEGED() == pdFALSE ) - { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - configASSERT( uxCriticalNesting ); - uxCriticalNesting--; + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; - if( uxCriticalNesting == 0 ) - { - portENABLE_INTERRUPTS(); + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); } - portMEMORY_BARRIER(); + else + { + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); - } - else - { + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + } + #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */ configASSERT( uxCriticalNesting ); uxCriticalNesting--; @@ -549,16 +591,7 @@ void vPortExitCritical( void ) { portENABLE_INTERRUPTS(); } - } -#else - configASSERT( uxCriticalNesting ); - uxCriticalNesting--; - - if( uxCriticalNesting == 0 ) - { - portENABLE_INTERRUPTS(); - } -#endif + #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */ } /*-----------------------------------------------------------*/ @@ -710,7 +743,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | - ( portSTACK_REGION ); /* Region number. */ + ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c old mode 100644 new mode 100755 index e9e3805f054..1c53fa94e28 --- a/portable/IAR/ARM_CM7/r0p1/port.c +++ b/portable/IAR/ARM_CM7/r0p1/port.c @@ -237,6 +237,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -268,20 +269,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -290,7 +317,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif diff --git a/portable/MikroC/ARM_CM4F/port.c b/portable/MikroC/ARM_CM4F/port.c old mode 100644 new mode 100755 index 886913fbc40..8e314b67092 --- a/portable/MikroC/ARM_CM4F/port.c +++ b/portable/MikroC/ARM_CM4F/port.c @@ -299,6 +299,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -330,20 +331,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -352,7 +379,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM3/port.c b/portable/RVDS/ARM_CM3/port.c old mode 100644 new mode 100755 index ac4bef29572..e1bfc6afcc7 --- a/portable/RVDS/ARM_CM3/port.c +++ b/portable/RVDS/ARM_CM3/port.c @@ -264,6 +264,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -295,20 +296,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -317,7 +344,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM4F/port.c b/portable/RVDS/ARM_CM4F/port.c old mode 100644 new mode 100755 index cdc063dc9f8..5233533c0c7 --- a/portable/RVDS/ARM_CM4F/port.c +++ b/portable/RVDS/ARM_CM4F/port.c @@ -330,6 +330,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -361,20 +362,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -383,7 +410,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c old mode 100644 new mode 100755 index b9c7f90b446..d9978a913f7 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -201,7 +201,7 @@ void vResetPrivilege( void ); /** * @brief Enter critical section. */ -#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) +#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; @@ -210,7 +210,7 @@ void vResetPrivilege( void ); /** * @brief Exit from critical section. */ -#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) +#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; @@ -412,6 +412,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) ); #else + /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define * configENABLE_ERRATA_837070_WORKAROUND to 1 in your * FreeRTOSConfig.h. */ @@ -420,74 +421,101 @@ BaseType_t xPortStartScheduler( void ) #endif #if ( configASSERT_DEFINED == 1 ) - { - volatile uint32_t ulOriginalPriority; - volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); - volatile uint8_t ucMaxPriorityValue; - - /* Determine the maximum priority from which ISR safe FreeRTOS API - * functions can be called. ISR safe functions are those that end in - * "FromISR". FreeRTOS maintains separate thread and ISR API functions to - * ensure interrupt entry is as fast and simple as possible. - * - * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + { + volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; + volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + * functions can be called. ISR safe functions are those that end in + * "FromISR". FreeRTOS maintains separate thread and ISR API functions to + * ensure interrupt entry is as fast and simple as possible. + * + * Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; - /* Determine the number of priority bits available. First write to all - * possible bits. */ - *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + /* Determine the number of priority bits available. First write to all + * possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; - /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = *pucFirstUserPriorityRegister; + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; - /* Use the same mask on the maximum system call priority. */ - ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; - /* Check that the maximum system call priority is nonzero after - * accounting for the number of priority bits supported by the - * hardware. A priority of 0 is invalid because setting the BASEPRI - * register to 0 unmasks all interrupts, and interrupts with priority 0 - * cannot be masked using BASEPRI. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( ucMaxSysCallPriority ); + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); - /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + /* Calculate the maximum acceptable priority group value for the number + * of bits read back. */ - while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) - { - ulMaxPRIGROUPValue--; - ucMaxPriorityValue <<= ( uint8_t ) 0x01; - } + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulImplementedPrioBits++; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } - #ifdef __NVIC_PRIO_BITS - { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); - } - #endif - - /* Shift the priority group value back to its position within the AIRCR - * register. */ - ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; - ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; - - /* Restore the clobbered interrupt priority register to its original - * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + * priority bits matches the number of priority bits actually queried + * from the hardware. */ + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + * priority bits matches the number of priority bits actually queried + * from the hardware. */ + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + } + #endif + + /* Shift the priority group value back to its position within the AIRCR + * register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + * value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the same priority as the kernel, and the SVC @@ -559,53 +587,63 @@ void vPortEndScheduler( void ) void vPortEnterCritical( void ) { -#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) - if( portIS_PRIVILEGED() == pdFALSE ) - { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portDISABLE_INTERRUPTS(); - uxCriticalNesting++; - portMEMORY_BARRIER(); + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); - } - else - { + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + } + #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */ portDISABLE_INTERRUPTS(); uxCriticalNesting++; - } -#else - portDISABLE_INTERRUPTS(); - uxCriticalNesting++; -#endif + #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */ } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { -#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) - if( portIS_PRIVILEGED() == pdFALSE ) - { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - configASSERT( uxCriticalNesting ); - uxCriticalNesting--; + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; - if( uxCriticalNesting == 0 ) - { - portENABLE_INTERRUPTS(); + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); } - portMEMORY_BARRIER(); + else + { + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); - } - else - { + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + } + #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */ configASSERT( uxCriticalNesting ); uxCriticalNesting--; @@ -613,16 +651,7 @@ void vPortExitCritical( void ) { portENABLE_INTERRUPTS(); } - } -#else - configASSERT( uxCriticalNesting ); - uxCriticalNesting--; - - if( uxCriticalNesting == 0 ) - { - portENABLE_INTERRUPTS(); - } -#endif + #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */ } /*-----------------------------------------------------------*/ @@ -910,7 +939,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | - ( portSTACK_REGION ); /* Region number. */ + ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | diff --git a/portable/RVDS/ARM_CM7/r0p1/port.c b/portable/RVDS/ARM_CM7/r0p1/port.c old mode 100644 new mode 100755 index 7dadb9adb34..ee456d87a9b --- a/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/portable/RVDS/ARM_CM7/r0p1/port.c @@ -314,6 +314,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -345,20 +346,46 @@ BaseType_t xPortStartScheduler( void ) /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulMaxPRIGROUPValue--; + ulImplementedPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); } #endif @@ -367,7 +394,7 @@ BaseType_t xPortStartScheduler( void ) /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + configASSERT( ulImplementedPrioBits == configPRIO_BITS ); } #endif diff --git a/portable/Tasking/ARM_CM4F/port.c b/portable/Tasking/ARM_CM4F/port.c old mode 100644 new mode 100755 index 66b0d629466..4ba5da739d0 --- a/portable/Tasking/ARM_CM4F/port.c +++ b/portable/Tasking/ARM_CM4F/port.c @@ -266,5 +266,4 @@ void prvSetupTimerInterrupt( void ) /* Configure SysTick to interrupt at the requested rate. */ *( portNVIC_SYSTICK_LOAD ) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; *( portNVIC_SYSTICK_CTRL ) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; -} -/*-----------------------------------------------------------*/ +} \ No newline at end of file From 97e58da31362f180642a381f9ea55aee04546c83 Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Tue, 28 Mar 2023 14:28:47 +0530 Subject: [PATCH 066/109] Remove C90 requirement from CMakeLists (#649) This is needed as it is breaking projects - https://forums.freertos.org/t/freertos-gcc-cmake/16984 We will re-evaluate and accordingly add this later. Signed-off-by: Gaurav Aggarwal --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d83db88b9c..d45de64b1b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,5 +292,3 @@ target_link_libraries(freertos_kernel ) ######################################################################## -# Requirements -set_property(TARGET freertos_kernel PROPERTY C_STANDARD 90) From 68f105375f65ffd347e3e322d46200cb389d8886 Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:01:37 +0530 Subject: [PATCH 067/109] Only add alignment padding when needed (#650) Heap 4 and Heap 5 add some padding to ensure that the allocated blocks are always aligned to portBYTE_ALIGNMENT bytes. The code until now was adding padding always even if the resulting block was already aligned. This commits updates the code to only add padding if the resulting block is not aligned. Signed-off-by: Gaurav Aggarwal --- portable/MemMang/heap_4.c | 30 ++++++++++++++++++++++++------ portable/MemMang/heap_5.c | 30 ++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/portable/MemMang/heap_4.c b/portable/MemMang/heap_4.c index 8ca7c81e4f3..c7a8209ed2b 100644 --- a/portable/MemMang/heap_4.c +++ b/portable/MemMang/heap_4.c @@ -159,13 +159,31 @@ void * pvPortMalloc( size_t xWantedSize ) if( xWantedSize > 0 ) { /* The wanted size must be increased so it can contain a BlockLink_t - * structure in addition to the requested amount of bytes. Some - * additional increment may also be needed for alignment. */ - xAdditionalRequiredSize = xHeapStructSize + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); - - if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) + * structure in addition to the requested amount of bytes. */ + if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 ) { - xWantedSize += xAdditionalRequiredSize; + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + * of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); + + if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) + { + xWantedSize += xAdditionalRequiredSize; + } + else + { + xWantedSize = 0; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } else { diff --git a/portable/MemMang/heap_5.c b/portable/MemMang/heap_5.c index 3a1df9b64c9..db9e1eb37ad 100644 --- a/portable/MemMang/heap_5.c +++ b/portable/MemMang/heap_5.c @@ -170,13 +170,31 @@ void * pvPortMalloc( size_t xWantedSize ) if( xWantedSize > 0 ) { /* The wanted size must be increased so it can contain a BlockLink_t - * structure in addition to the requested amount of bytes. Some - * additional increment may also be needed for alignment. */ - xAdditionalRequiredSize = xHeapStructSize + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); - - if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) + * structure in addition to the requested amount of bytes. */ + if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 ) { - xWantedSize += xAdditionalRequiredSize; + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + * of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); + + if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) + { + xWantedSize += xAdditionalRequiredSize; + } + else + { + xWantedSize = 0; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } else { From 1b8a4244bdd911f156ce5bc6f9f13dcde68228cb Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 29 Mar 2023 15:23:45 +0200 Subject: [PATCH 068/109] add a missing comma (#651) --- include/task.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/task.h b/include/task.h index 054f43644a1..702f74dce9b 100644 --- a/include/task.h +++ b/include/task.h @@ -1664,7 +1664,7 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL /** * task.h * @code{c} - * void vApplicationStackOverflowHook( TaskHandle_t xTask char *pcTaskName); + * void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName); * @endcode * * The application stack overflow hook is called when a stack overflow is detected for a task. From aa987a3443b60894bc64714135bca44831406886 Mon Sep 17 00:00:00 2001 From: Vo Trung Chi Date: Tue, 4 Apr 2023 22:10:54 +0700 Subject: [PATCH 069/109] fix conversion warning (#658) FreeRTOS-Kernel/portable/GCC/ARM_CM4F/port.c:399:41: error: conversion from 'uint32_t' {aka 'long unsigned int'} to 'uint8_t' {aka 'unsigned char'} may change value [-Werror=conversion] Signed-off-by: Vo Trung Chi --- portable/CCS/ARM_CM3/port.c | 6 +++--- portable/CCS/ARM_CM4F/port.c | 6 +++--- portable/GCC/ARM_CA53_64_BIT/port.c | 6 +++--- portable/GCC/ARM_CA9/port.c | 6 +++--- portable/GCC/ARM_CM3/port.c | 6 +++--- portable/GCC/ARM_CM3_MPU/port.c | 6 +++--- portable/GCC/ARM_CM4F/port.c | 6 +++--- portable/GCC/ARM_CM4_MPU/port.c | 6 +++--- portable/GCC/ARM_CM7/r0p1/port.c | 6 +++--- portable/GCC/ARM_CR5/port.c | 6 +++--- portable/IAR/ARM_CM3/port.c | 6 +++--- portable/IAR/ARM_CM4F/port.c | 6 +++--- portable/IAR/ARM_CM4F_MPU/port.c | 6 +++--- portable/IAR/ARM_CM7/r0p1/port.c | 6 +++--- portable/MikroC/ARM_CM4F/port.c | 6 +++--- portable/RVDS/ARM_CM3/port.c | 6 +++--- portable/RVDS/ARM_CM4F/port.c | 6 +++--- portable/RVDS/ARM_CM4_MPU/port.c | 6 +++--- portable/RVDS/ARM_CM7/r0p1/port.c | 6 +++--- 19 files changed, 57 insertions(+), 57 deletions(-) diff --git a/portable/CCS/ARM_CM3/port.c b/portable/CCS/ARM_CM3/port.c index 63dc600a756..ef5fa5b9340 100755 --- a/portable/CCS/ARM_CM3/port.c +++ b/portable/CCS/ARM_CM3/port.c @@ -218,7 +218,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -229,7 +229,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -310,7 +310,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/CCS/ARM_CM4F/port.c b/portable/CCS/ARM_CM4F/port.c index a741b091561..c43cf0ef314 100755 --- a/portable/CCS/ARM_CM4F/port.c +++ b/portable/CCS/ARM_CM4F/port.c @@ -237,7 +237,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -248,7 +248,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -329,7 +329,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CA53_64_BIT/port.c b/portable/GCC/ARM_CA53_64_BIT/port.c index 3e686e33811..545bac15d86 100644 --- a/portable/GCC/ARM_CA53_64_BIT/port.c +++ b/portable/GCC/ARM_CA53_64_BIT/port.c @@ -270,14 +270,14 @@ uint32_t ulAPSR; #if( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); volatile uint8_t ucMaxPriorityValue; /* Determine how many priority bits are implemented in the GIC. Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all possible bits. */ @@ -300,7 +300,7 @@ uint32_t ulAPSR; /* Restore the clobbered interrupt priority register to its original value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CA9/port.c b/portable/GCC/ARM_CA9/port.c index 75e69f876a2..8c74214117c 100644 --- a/portable/GCC/ARM_CA9/port.c +++ b/portable/GCC/ARM_CA9/port.c @@ -329,14 +329,14 @@ uint32_t ulAPSR; #if( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); volatile uint8_t ucMaxPriorityValue; /* Determine how many priority bits are implemented in the GIC. Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all possible bits. */ @@ -357,7 +357,7 @@ uint32_t ulAPSR; /* Restore the clobbered interrupt priority register to its original value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CM3/port.c b/portable/GCC/ARM_CM3/port.c index 57337e60502..4aa1f2425d7 100755 --- a/portable/GCC/ARM_CM3/port.c +++ b/portable/GCC/ARM_CM3/port.c @@ -261,7 +261,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -272,7 +272,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -353,7 +353,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index 4b21236e785..e33df014c0e 100755 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -384,7 +384,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -395,7 +395,7 @@ BaseType_t xPortStartScheduler( void ) * to ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -476,7 +476,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c index 84e79130487..fd9e6dbb8f2 100755 --- a/portable/GCC/ARM_CM4F/port.c +++ b/portable/GCC/ARM_CM4F/port.c @@ -304,7 +304,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -315,7 +315,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -396,7 +396,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index 682b64ea8c1..1733fd82072 100755 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -427,7 +427,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -438,7 +438,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -519,7 +519,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c index 25a06bf46e2..316dba13b8e 100755 --- a/portable/GCC/ARM_CM7/r0p1/port.c +++ b/portable/GCC/ARM_CM7/r0p1/port.c @@ -292,7 +292,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -303,7 +303,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -384,7 +384,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CR5/port.c b/portable/GCC/ARM_CR5/port.c index 03007821967..2cbc24dbf9d 100644 --- a/portable/GCC/ARM_CR5/port.c +++ b/portable/GCC/ARM_CR5/port.c @@ -411,7 +411,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); volatile uint8_t ucMaxPriorityValue; @@ -419,7 +419,7 @@ BaseType_t xPortStartScheduler( void ) * Determine how many priority bits are implemented in the GIC. * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* * Determine the number of priority bits available. First write to @@ -457,7 +457,7 @@ BaseType_t xPortStartScheduler( void ) * Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/IAR/ARM_CM3/port.c b/portable/IAR/ARM_CM3/port.c index a7a5ad86bd2..f1c78e46240 100755 --- a/portable/IAR/ARM_CM3/port.c +++ b/portable/IAR/ARM_CM3/port.c @@ -210,7 +210,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -221,7 +221,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -302,7 +302,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/IAR/ARM_CM4F/port.c b/portable/IAR/ARM_CM4F/port.c index 9b4ed52fae5..05d5be0aa65 100755 --- a/portable/IAR/ARM_CM4F/port.c +++ b/portable/IAR/ARM_CM4F/port.c @@ -248,7 +248,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -259,7 +259,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -340,7 +340,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index 6aec5b34262..69b7bc5d9bc 100755 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -362,7 +362,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -373,7 +373,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -454,7 +454,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c index 1c53fa94e28..9217653a7d4 100755 --- a/portable/IAR/ARM_CM7/r0p1/port.c +++ b/portable/IAR/ARM_CM7/r0p1/port.c @@ -236,7 +236,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -247,7 +247,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -328,7 +328,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/MikroC/ARM_CM4F/port.c b/portable/MikroC/ARM_CM4F/port.c index 8e314b67092..1936de19447 100755 --- a/portable/MikroC/ARM_CM4F/port.c +++ b/portable/MikroC/ARM_CM4F/port.c @@ -298,7 +298,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -309,7 +309,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -390,7 +390,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/RVDS/ARM_CM3/port.c b/portable/RVDS/ARM_CM3/port.c index e1bfc6afcc7..2ffdd9cc8bd 100755 --- a/portable/RVDS/ARM_CM3/port.c +++ b/portable/RVDS/ARM_CM3/port.c @@ -263,7 +263,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -274,7 +274,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -355,7 +355,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/RVDS/ARM_CM4F/port.c b/portable/RVDS/ARM_CM4F/port.c index 5233533c0c7..bf2fb86f76a 100755 --- a/portable/RVDS/ARM_CM4F/port.c +++ b/portable/RVDS/ARM_CM4F/port.c @@ -329,7 +329,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -340,7 +340,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -421,7 +421,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index d9978a913f7..e0bd8c86d0f 100755 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -422,7 +422,7 @@ BaseType_t xPortStartScheduler( void ) #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -433,7 +433,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -514,7 +514,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ diff --git a/portable/RVDS/ARM_CM7/r0p1/port.c b/portable/RVDS/ARM_CM7/r0p1/port.c index ee456d87a9b..2e81e324df9 100755 --- a/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/portable/RVDS/ARM_CM7/r0p1/port.c @@ -313,7 +313,7 @@ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { - volatile uint32_t ulOriginalPriority; + volatile uint8_t ucOriginalPriority; volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; @@ -324,7 +324,7 @@ BaseType_t xPortStartScheduler( void ) * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; + ucOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ @@ -405,7 +405,7 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ucOriginalPriority; } #endif /* configASSERT_DEFINED */ From 686b6e62eb48f0bab57cab47fbbd90d0d23504e8 Mon Sep 17 00:00:00 2001 From: Paul Bartell Date: Wed, 19 Apr 2023 22:24:54 -0700 Subject: [PATCH 070/109] ARMv7M: Adjust implemented priority bit assertions (#665) Adjust assertions related to the CMSIS __NVIC_PRIO_BITS and FreeRTOS configPRIO_BITS configuration macros such that these macros specify the minimum number of implemented priority bits supported by a config build rather than the exact number of implemented priority bits. Related to Qemu issue #1122 --- portable/CCS/ARM_CM3/port.c | 20 ++++++++++++-------- portable/CCS/ARM_CM4F/port.c | 20 ++++++++++++-------- portable/GCC/ARM_CM3/port.c | 20 ++++++++++++-------- portable/GCC/ARM_CM3_MPU/port.c | 28 ++++++++++++++++------------ portable/GCC/ARM_CM4F/port.c | 20 ++++++++++++-------- portable/GCC/ARM_CM4_MPU/port.c | 28 ++++++++++++++++------------ portable/GCC/ARM_CM7/r0p1/port.c | 20 ++++++++++++-------- portable/IAR/ARM_CM3/port.c | 20 ++++++++++++-------- portable/IAR/ARM_CM4F/port.c | 20 ++++++++++++-------- portable/IAR/ARM_CM4F_MPU/port.c | 20 ++++++++++++-------- portable/IAR/ARM_CM7/r0p1/port.c | 20 ++++++++++++-------- portable/MikroC/ARM_CM4F/port.c | 20 ++++++++++++-------- portable/RVDS/ARM_CM3/port.c | 20 ++++++++++++-------- portable/RVDS/ARM_CM4F/port.c | 20 ++++++++++++-------- portable/RVDS/ARM_CM4_MPU/port.c | 20 ++++++++++++-------- portable/RVDS/ARM_CM7/r0p1/port.c | 20 ++++++++++++-------- 16 files changed, 200 insertions(+), 136 deletions(-) diff --git a/portable/CCS/ARM_CM3/port.c b/portable/CCS/ARM_CM3/port.c index ef5fa5b9340..f3c4e5add03 100755 --- a/portable/CCS/ARM_CM3/port.c +++ b/portable/CCS/ARM_CM3/port.c @@ -287,19 +287,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/CCS/ARM_CM4F/port.c b/portable/CCS/ARM_CM4F/port.c index c43cf0ef314..c675afe67b4 100755 --- a/portable/CCS/ARM_CM4F/port.c +++ b/portable/CCS/ARM_CM4F/port.c @@ -306,19 +306,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/GCC/ARM_CM3/port.c b/portable/GCC/ARM_CM3/port.c index 4aa1f2425d7..9b42eac5a4e 100755 --- a/portable/GCC/ARM_CM3/port.c +++ b/portable/GCC/ARM_CM3/port.c @@ -330,19 +330,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index e33df014c0e..619f2b0c8be 100755 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -452,21 +452,25 @@ BaseType_t xPortStartScheduler( void ) } #ifdef __NVIC_PRIO_BITS - { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } + { + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); + } #endif #ifdef configPRIO_BITS - { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } + { + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); + } #endif /* Shift the priority group value back to its position within the AIRCR diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c index fd9e6dbb8f2..88fc76db894 100755 --- a/portable/GCC/ARM_CM4F/port.c +++ b/portable/GCC/ARM_CM4F/port.c @@ -373,19 +373,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index 1733fd82072..ab76ee84204 100755 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -495,21 +495,25 @@ BaseType_t xPortStartScheduler( void ) } #ifdef __NVIC_PRIO_BITS - { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } + { + /* + * Check that the number of implemented priority bits queried + * from hardware is at least as many as specified in the + * CMSIS __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); + } #endif #ifdef configPRIO_BITS - { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } + { + /* + * Check that the number of implemented priority bits queried + * from hardware is at least as many as specified in the + * FreeRTOS configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); + } #endif /* Shift the priority group value back to its position within the AIRCR diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c index 316dba13b8e..2be4f27704d 100755 --- a/portable/GCC/ARM_CM7/r0p1/port.c +++ b/portable/GCC/ARM_CM7/r0p1/port.c @@ -361,19 +361,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM3/port.c b/portable/IAR/ARM_CM3/port.c index f1c78e46240..d54c3aceb4a 100755 --- a/portable/IAR/ARM_CM3/port.c +++ b/portable/IAR/ARM_CM3/port.c @@ -279,19 +279,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM4F/port.c b/portable/IAR/ARM_CM4F/port.c index 05d5be0aa65..e0deaf12840 100755 --- a/portable/IAR/ARM_CM4F/port.c +++ b/portable/IAR/ARM_CM4F/port.c @@ -317,19 +317,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index 69b7bc5d9bc..1b7cca65c86 100755 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -431,19 +431,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c index 9217653a7d4..63f83993db9 100755 --- a/portable/IAR/ARM_CM7/r0p1/port.c +++ b/portable/IAR/ARM_CM7/r0p1/port.c @@ -305,19 +305,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/MikroC/ARM_CM4F/port.c b/portable/MikroC/ARM_CM4F/port.c index 1936de19447..8ef593f5523 100755 --- a/portable/MikroC/ARM_CM4F/port.c +++ b/portable/MikroC/ARM_CM4F/port.c @@ -367,19 +367,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM3/port.c b/portable/RVDS/ARM_CM3/port.c index 2ffdd9cc8bd..ae7ce37f37b 100755 --- a/portable/RVDS/ARM_CM3/port.c +++ b/portable/RVDS/ARM_CM3/port.c @@ -332,19 +332,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM4F/port.c b/portable/RVDS/ARM_CM4F/port.c index bf2fb86f76a..cb003aa38f9 100755 --- a/portable/RVDS/ARM_CM4F/port.c +++ b/portable/RVDS/ARM_CM4F/port.c @@ -398,19 +398,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index e0bd8c86d0f..13e2f8a8ed1 100755 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -491,19 +491,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM7/r0p1/port.c b/portable/RVDS/ARM_CM7/r0p1/port.c index 2e81e324df9..1df54ab2802 100755 --- a/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/portable/RVDS/ARM_CM7/r0p1/port.c @@ -382,19 +382,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif From d8d2454421a110f36b331cf1b8986d5f909289cc Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 20 Apr 2023 22:01:42 +0800 Subject: [PATCH 071/109] Update get idle tasks stats --- tasks.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/tasks.c b/tasks.c index d082b60b21b..15e1960ad06 100644 --- a/tasks.c +++ b/tasks.c @@ -460,8 +460,8 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t /* Do not move these variables to function scope as doing so prevents the * code working with debuggers that need to remove the static qualifier. */ - PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime[ configNUM_CORES ] = { 0UL }; /**< Holds the value of a timer/counter the last time a task was switched in. */ - PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ configNUM_CORES ] = { 0UL }; /**< Holds the total amount of execution time as defined by the run time counter clock. */ + PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the value of a timer/counter the last time a task was switched in. */ + PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the total amount of execution time as defined by the run time counter clock. */ #endif @@ -7438,7 +7438,15 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) { - return ulTaskGetRunTimeCounter( xIdleTaskHandle ); + configRUN_TIME_COUNTER_TYPE ulIdleRunTimeCounter = 0; + BaseType_t i; + + for( i = 0; i < configNUMBER_OF_CORES; i++ ) + { + ulIdleRunTimeCounter += ulTaskGetRunTimeCounter( xIdleTaskHandles[ i ] ); + } + + return ulIdleRunTimeCounter; } #endif @@ -7448,7 +7456,16 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) { - return ulTaskGetRunTimePercent( xIdleTaskHandle ); + + configRUN_TIME_COUNTER_TYPE ulIdleRunTimePercent = 0; + BaseType_t i; + + for( i = 0; i < configNUMBER_OF_CORES; i++ ) + { + ulIdleRunTimePercent += ulTaskGetRunTimePercent( xIdleTaskHandles[ i ] ); + } + + return ulIdleRunTimePercent; } #endif From 3101a1af0bf60b0ac841c3c2d2d328e1d22bf6b4 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 20 Apr 2023 21:57:37 +0800 Subject: [PATCH 072/109] Define portBASE_TYPE in XMOS AICORE porting --- portable/ThirdParty/xClang/XCOREAI/portmacro.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/portable/ThirdParty/xClang/XCOREAI/portmacro.h b/portable/ThirdParty/xClang/XCOREAI/portmacro.h index aef12cf3749..69a734f783e 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portmacro.h +++ b/portable/ThirdParty/xClang/XCOREAI/portmacro.h @@ -26,6 +26,8 @@ typedef double portDOUBLE; typedef int32_t BaseType_t; typedef uint32_t UBaseType_t; +#define portBASE_TYPE BaseType_t + #if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff @@ -164,7 +166,7 @@ void vTaskExitCritical(void); #define portEXIT_CRITICAL() vTaskExitCritical() extern UBaseType_t vTaskEnterCriticalFromISR( void ); -extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ); +extern void vTaskExitCriticalFromISR( BaseType_t xSavedInterruptStatus ); #define portENTER_CRITICAL_FROM_ISR vTaskEnterCriticalFromISR #define portEXIT_CRITICAL_FROM_ISR vTaskExitCriticalFromISR From 5c094b574485ebd94786d1b4b39b0af036bb38a5 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 20 Apr 2023 22:09:02 +0800 Subject: [PATCH 073/109] Update enter critical from ISR API --- portable/ThirdParty/xClang/XCOREAI/portmacro.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/portable/ThirdParty/xClang/XCOREAI/portmacro.h b/portable/ThirdParty/xClang/XCOREAI/portmacro.h index 69a734f783e..019d29a3c7a 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portmacro.h +++ b/portable/ThirdParty/xClang/XCOREAI/portmacro.h @@ -165,8 +165,8 @@ void vTaskExitCritical(void); #define portENTER_CRITICAL() vTaskEnterCritical() #define portEXIT_CRITICAL() vTaskExitCritical() -extern UBaseType_t vTaskEnterCriticalFromISR( void ); -extern void vTaskExitCriticalFromISR( BaseType_t xSavedInterruptStatus ); +extern portBASE_TYPE vTaskEnterCriticalFromISR( void ); +extern void vTaskExitCriticalFromISR( portBASE_TYPE xSavedInterruptStatus ); #define portENTER_CRITICAL_FROM_ISR vTaskEnterCriticalFromISR #define portEXIT_CRITICAL_FROM_ISR vTaskExitCriticalFromISR From 714e5432472c7009f03c26c12ae37d62a0c5c2ca Mon Sep 17 00:00:00 2001 From: Paul Bartell Date: Tue, 18 Apr 2023 12:01:49 -0700 Subject: [PATCH 074/109] Format portmacro.h in arm CM0 ports --- portable/GCC/ARM_CM0/portmacro.h | 120 +++++++++++++++--------------- portable/IAR/ARM_CM0/portmacro.h | 114 ++++++++++++++-------------- portable/RVDS/ARM_CM0/portmacro.h | 100 +++++++++++++------------ 3 files changed, 169 insertions(+), 165 deletions(-) diff --git a/portable/GCC/ARM_CM0/portmacro.h b/portable/GCC/ARM_CM0/portmacro.h index 408162d6402..db69cfddf5b 100644 --- a/portable/GCC/ARM_CM0/portmacro.h +++ b/portable/GCC/ARM_CM0/portmacro.h @@ -28,11 +28,11 @@ #ifndef PORTMACRO_H - #define PORTMACRO_H +#define PORTMACRO_H - #ifdef __cplusplus - extern "C" { - #endif +#ifdef __cplusplus +extern "C" { +#endif /*----------------------------------------------------------- * Port specific definitions. @@ -45,84 +45,86 @@ */ /* Type definitions. */ - #define portCHAR char - #define portFLOAT float - #define portDOUBLE double - #define portLONG long - #define portSHORT short - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE long - - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; - - #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ - #define portTICK_TYPE_IS_ATOMIC 1 - #else - #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. - #endif + #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. +#endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 8 - #define portDONT_DISCARD __attribute__( ( used ) ) - #define portNORETURN __attribute__( ( noreturn ) ) +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +#define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ - extern void vPortYield( void ); - #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) - #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) - #define portYIELD() vPortYield() - #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) - #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) \ + do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ + while( 0 ) +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ - extern void vPortEnterCritical( void ); - extern void vPortExitCritical( void ); - extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__( ( naked ) ); - extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( naked ) ); - - #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) - #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) - #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) - #define portENTER_CRITICAL() vPortEnterCritical() - #define portEXIT_CRITICAL() vPortExitCritical() +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__( ( naked ) ); +extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( naked ) ); + +#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) +#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) +#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ - #ifndef portSUPPRESS_TICKS_AND_SLEEP - extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); - #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) - #endif +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portNOP() +#define portNOP() - #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) +#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) - #ifdef __cplusplus - } - #endif +#ifdef __cplusplus +} +#endif #endif /* PORTMACRO_H */ diff --git a/portable/IAR/ARM_CM0/portmacro.h b/portable/IAR/ARM_CM0/portmacro.h index ce1aa08fc9d..622b584c006 100644 --- a/portable/IAR/ARM_CM0/portmacro.h +++ b/portable/IAR/ARM_CM0/portmacro.h @@ -27,11 +27,11 @@ */ #ifndef PORTMACRO_H - #define PORTMACRO_H +#define PORTMACRO_H - #ifdef __cplusplus - extern "C" { - #endif +#ifdef __cplusplus +extern "C" { +#endif /*----------------------------------------------------------- * Port specific definitions. @@ -44,87 +44,87 @@ */ /* Type definitions. */ - #define portCHAR char - #define portFLOAT float - #define portDOUBLE double - #define portLONG long - #define portSHORT short - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE long - - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; - - - #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + + +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ - #define portTICK_TYPE_IS_ATOMIC 1 - #else - #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. - #endif + #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. +#endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 8 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Scheduler utilities. */ - extern void vPortYield( void ); - #define portNVIC_INT_CTRL ( ( volatile uint32_t * ) 0xe000ed04 ) - #define portNVIC_PENDSVSET 0x10000000 - #define portYIELD() vPortYield() - #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET - #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +extern void vPortYield( void ); +#define portNVIC_INT_CTRL ( ( volatile uint32_t * ) 0xe000ed04 ) +#define portNVIC_PENDSVSET 0x10000000 +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ - extern void vPortEnterCritical( void ); - extern void vPortExitCritical( void ); - extern uint32_t ulSetInterruptMaskFromISR( void ); - extern void vClearInterruptMaskFromISR( uint32_t ulMask ); +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulSetInterruptMaskFromISR( void ); +extern void vClearInterruptMaskFromISR( uint32_t ulMask ); - #define portDISABLE_INTERRUPTS() __asm volatile ( "cpsid i" ) - #define portENABLE_INTERRUPTS() __asm volatile ( "cpsie i" ) - #define portENTER_CRITICAL() vPortEnterCritical() - #define portEXIT_CRITICAL() vPortExitCritical() - #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) +#define portDISABLE_INTERRUPTS() __asm volatile ( "cpsid i" ) +#define portENABLE_INTERRUPTS() __asm volatile ( "cpsie i" ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ - #ifndef portSUPPRESS_TICKS_AND_SLEEP - extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); - #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) - #endif +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portNOP() +#define portNOP() /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ - #pragma diag_suppress=Pa082 +#pragma diag_suppress=Pa082 - #ifdef __cplusplus - } - #endif +#ifdef __cplusplus +} +#endif #endif /* PORTMACRO_H */ diff --git a/portable/RVDS/ARM_CM0/portmacro.h b/portable/RVDS/ARM_CM0/portmacro.h index 54165e74cc4..fb1eea7cad0 100644 --- a/portable/RVDS/ARM_CM0/portmacro.h +++ b/portable/RVDS/ARM_CM0/portmacro.h @@ -47,76 +47,78 @@ */ /* Type definitions. */ - #define portCHAR char - #define portFLOAT float - #define portDOUBLE double - #define portLONG long - #define portSHORT short - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE long - - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; - - #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ - #define portTICK_TYPE_IS_ATOMIC 1 - #else - #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. - #endif + #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. +#endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 8 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Scheduler utilities. */ - extern void vPortYield( void ); - #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) - #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) - #define portYIELD() vPortYield() - #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) - #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) \ + do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ + while( 0 ) +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ - extern void vPortEnterCritical( void ); - extern void vPortExitCritical( void ); - extern uint32_t ulSetInterruptMaskFromISR( void ); - extern void vClearInterruptMaskFromISR( uint32_t ulMask ); - - #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) - #define portDISABLE_INTERRUPTS() __disable_irq() - #define portENABLE_INTERRUPTS() __enable_irq() - #define portENTER_CRITICAL() vPortEnterCritical() - #define portEXIT_CRITICAL() vPortExitCritical() +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulSetInterruptMaskFromISR( void ); +extern void vClearInterruptMaskFromISR( uint32_t ulMask ); + +#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) +#define portDISABLE_INTERRUPTS() __disable_irq() +#define portENABLE_INTERRUPTS() __enable_irq() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ - #ifndef portSUPPRESS_TICKS_AND_SLEEP - extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); - #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) - #endif +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portNOP() +#define portNOP() /* *INDENT-OFF* */ #ifdef __cplusplus From 5f19e34f878af97810a7662a75eac59bd74d628b Mon Sep 17 00:00:00 2001 From: Paul Bartell Date: Tue, 18 Apr 2023 14:43:29 -0700 Subject: [PATCH 075/109] portable/ARM_CM0: Add xPortIsInsideInterrupt Add missing xPortIsInsideInterrupt function to Cortex-M0 port. --- portable/GCC/ARM_CM0/portmacro.h | 40 +++++++++++++++++++++++++++++-- portable/IAR/ARM_CM0/portmacro.h | 39 ++++++++++++++++++++++++++++-- portable/RVDS/ARM_CM0/portmacro.h | 35 +++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 4 deletions(-) diff --git a/portable/GCC/ARM_CM0/portmacro.h b/portable/GCC/ARM_CM0/portmacro.h index db69cfddf5b..b9e9ef6623f 100644 --- a/portable/GCC/ARM_CM0/portmacro.h +++ b/portable/GCC/ARM_CM0/portmacro.h @@ -30,9 +30,11 @@ #ifndef PORTMACRO_H #define PORTMACRO_H +/* *INDENT-OFF* */ #ifdef __cplusplus -extern "C" { + extern "C" { #endif +/* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. @@ -123,8 +125,42 @@ extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( nake #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) -#ifdef __cplusplus + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) +#endif + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; } + +/*-----------------------------------------------------------*/ + + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } #endif +/* *INDENT-ON* */ #endif /* PORTMACRO_H */ diff --git a/portable/IAR/ARM_CM0/portmacro.h b/portable/IAR/ARM_CM0/portmacro.h index 622b584c006..5dcc949b228 100644 --- a/portable/IAR/ARM_CM0/portmacro.h +++ b/portable/IAR/ARM_CM0/portmacro.h @@ -26,12 +26,15 @@ * */ + #ifndef PORTMACRO_H #define PORTMACRO_H +/* *INDENT-OFF* */ #ifdef __cplusplus -extern "C" { + extern "C" { #endif +/* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. @@ -118,13 +121,45 @@ extern void vClearInterruptMaskFromISR( uint32_t ulMask ); #define portNOP() +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) +#endif + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Pa082 +/* *INDENT-OFF* */ #ifdef __cplusplus -} + } #endif +/* *INDENT-ON* */ #endif /* PORTMACRO_H */ diff --git a/portable/RVDS/ARM_CM0/portmacro.h b/portable/RVDS/ARM_CM0/portmacro.h index fb1eea7cad0..4a1ea8a7b3a 100644 --- a/portable/RVDS/ARM_CM0/portmacro.h +++ b/portable/RVDS/ARM_CM0/portmacro.h @@ -120,6 +120,41 @@ extern void vClearInterruptMaskFromISR( uint32_t ulMask ); #define portNOP() +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE __forceinline +#endif + +/*-----------------------------------------------------------*/ + +static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm + { +/* *INDENT-OFF* */ + mrs ulCurrentInterrupt, ipsr +/* *INDENT-ON* */ + } + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + /* *INDENT-OFF* */ #ifdef __cplusplus } From a5f109450887e29cdca1f74ab66f1a63cc548782 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Fri, 21 Apr 2023 13:10:50 +0800 Subject: [PATCH 076/109] Fix get task stats --- tasks.c | 62 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/tasks.c b/tasks.c index 15e1960ad06..0c1538543c1 100644 --- a/tasks.c +++ b/tasks.c @@ -7388,17 +7388,10 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) { - configRUN_TIME_COUNTER_TYPE ulReturn = 0; - - for( BaseType_t i = 0; i < configNUMBER_OF_CORES; i++ ) - { - ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; - } - - return ulReturn; + return xTask->ulRunTimeCounter; } -#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +#endif /*-----------------------------------------------------------*/ #if ( configGENERATE_RUN_TIME_STATS == 1 ) @@ -7406,9 +7399,8 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; - configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; - ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) ( portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES ); + ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); /* For percentage calculations. */ ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; @@ -7416,12 +7408,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - for( BaseType_t i = 0; i < configNUMBER_OF_CORES; i++ ) - { - ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; - } - - ulReturn = ulRunTimeCounter / ulTotalTime; + ulReturn = xTask->ulRunTimeCounter / ulTotalTime; } else { @@ -7434,41 +7421,54 @@ TickType_t uxTaskResetEventItemValue( void ) #endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ /*-----------------------------------------------------------*/ -#if ( configGENERATE_RUN_TIME_STATS == 1 ) +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) { - configRUN_TIME_COUNTER_TYPE ulIdleRunTimeCounter = 0; - BaseType_t i; + configRUN_TIME_COUNTER_TYPE ulReturn = 0; - for( i = 0; i < configNUMBER_OF_CORES; i++ ) + for( BaseType_t i = 0; i < configNUM_CORES; i++ ) { - ulIdleRunTimeCounter += ulTaskGetRunTimeCounter( xIdleTaskHandles[ i ] ); + ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; } - return ulIdleRunTimeCounter; + return ulReturn; } -#endif +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ /*-----------------------------------------------------------*/ -#if ( configGENERATE_RUN_TIME_STATS == 1 ) +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) { + configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; + configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; - configRUN_TIME_COUNTER_TYPE ulIdleRunTimePercent = 0; - BaseType_t i; + ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES; + + /* For percentage calculations. */ + ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; - for( i = 0; i < configNUMBER_OF_CORES; i++ ) + /* Avoid divide by zero errors. */ + if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - ulIdleRunTimePercent += ulTaskGetRunTimePercent( xIdleTaskHandles[ i ] ); + for( BaseType_t i = 0; i < configNUMBER_OF_CORES; i++ ) + { + ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; + } + + ulReturn = ulRunTimeCounter / ulTotalTime; + } + else + { + ulReturn = 0; } - return ulIdleRunTimePercent; + return ulReturn; } -#endif +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ /*-----------------------------------------------------------*/ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, From 39b3beafda16bb8b352cbae01ba9bcd58c474d0e Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Fri, 21 Apr 2023 13:23:30 +0800 Subject: [PATCH 077/109] Fix missing configNUM_CORES --- tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks.c b/tasks.c index 0c1538543c1..d54975086d7 100644 --- a/tasks.c +++ b/tasks.c @@ -7427,7 +7427,7 @@ TickType_t uxTaskResetEventItemValue( void ) { configRUN_TIME_COUNTER_TYPE ulReturn = 0; - for( BaseType_t i = 0; i < configNUM_CORES; i++ ) + for( BaseType_t i = 0; i < configNUMBER_OF_CORES; i++ ) { ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; } From f6ec3c73d3081aca62a0367d99d9c095c056e929 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 24 Apr 2023 16:39:31 +0800 Subject: [PATCH 078/109] Fix uncrustify --- tasks.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tasks.c b/tasks.c index 400da8f73c1..9ed0ddfd331 100644 --- a/tasks.c +++ b/tasks.c @@ -294,7 +294,7 @@ typedef BaseType_t TaskRunning_t; /* Code below here allows infinite loop controlling, especially for the infinite loop * in idle task function (for example when performing unit tests). */ #ifndef INFINITE_LOOP - #define INFINITE_LOOP() 1 + #define INFINITE_LOOP() 1 #endif /* @@ -460,8 +460,8 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t /* Do not move these variables to function scope as doing so prevents the * code working with debuggers that need to remove the static qualifier. */ - PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the value of a timer/counter the last time a task was switched in. */ - PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the total amount of execution time as defined by the run time counter clock. */ +PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the value of a timer/counter the last time a task was switched in. */ +PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the total amount of execution time as defined by the run time counter clock. */ #endif @@ -796,7 +796,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * than priority level of currently ready tasks. */ if( pxTCB->uxPriority >= uxTopReadyPriority ) #else - /* Yield is not required for a task which is already running. */ if( taskTASK_IS_RUNNING( pxTCB ) == pdFALSE ) #endif @@ -3738,7 +3737,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char return pxReturn; } - #else + #else /* if ( configNUMBER_OF_CORES == 1 ) */ static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, const char pcNameToQuery[] ) { From 8037d3b019cd0e5b06d905f255697bab7d02dc76 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 24 Apr 2023 16:48:14 +0800 Subject: [PATCH 079/109] Update lexicon --- .github/lexicon.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/lexicon.txt b/.github/lexicon.txt index 305498fdc59..5e7d6dbbf75 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -1521,6 +1521,7 @@ prstc prttc prv prvaddcurrenttasktodelayedlist +prvcheckforrunstatechange prvcheckinterfaces prvchecktaskswaitingtermination prvcopydatatoqueue From 4e2c58d0abed598c623b533c8038e4b303b41ff7 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 24 Apr 2023 16:49:29 +0800 Subject: [PATCH 080/109] Remove tailing space --- portable/ThirdParty/xClang/XCOREAI/portasm.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portable/ThirdParty/xClang/XCOREAI/portasm.S b/portable/ThirdParty/xClang/XCOREAI/portasm.S index 702e9a2f021..7445672a08e 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portasm.S +++ b/portable/ThirdParty/xClang/XCOREAI/portasm.S @@ -87,7 +87,7 @@ rtos_interrupt_callback_common: bla r1} /* and call the callback function. */ {set sp, r4 /* Restore the task's SP now. */ - + get r11, id} /* Get the logical core ID into r11. */ ldaw r0, dp[rtos_core_map] ldw r0, r0[r11] /* Translate to the RTOS core ID into r0. */ From c659463ed01fc6f15983feec3d4dc651ffa9027e Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 24 Apr 2023 17:05:35 +0800 Subject: [PATCH 081/109] Fix ulTotalRunTime and ulTaskSwitchedInTime * SMP has multiple ulTotalRunTime and ulTaskSwitchedInTime --- tasks.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasks.c b/tasks.c index 400da8f73c1..439115fadce 100644 --- a/tasks.c +++ b/tasks.c @@ -4540,9 +4540,9 @@ BaseType_t xTaskIncrementTick( void ) #if ( configGENERATE_RUN_TIME_STATS == 1 ) { #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE - portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime[ 0 ] ); #else - ulTotalRunTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + ulTotalRunTime[ 0 ] = portGET_RUN_TIME_COUNTER_VALUE(); #endif /* Add the amount of time the task has been running to the @@ -4552,16 +4552,16 @@ BaseType_t xTaskIncrementTick( void ) * overflows. The guard against negative values is to protect * against suspect run time stat counter implementations - which * are provided by the application, not the kernel. */ - if( ulTotalRunTime > ulTaskSwitchedInTime ) + if( ulTotalRunTime[ 0 ] > ulTaskSwitchedInTime[ 0 ] ) { - pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime[ 0 ] - ulTaskSwitchedInTime[ 0 ] ); } else { mtCOVERAGE_TEST_MARKER(); } - ulTaskSwitchedInTime = ulTotalRunTime; + ulTaskSwitchedInTime[ 0 ] = ulTotalRunTime[ 0 ]; } #endif /* configGENERATE_RUN_TIME_STATS */ From 8748c6ecf419b98ffea51ff3e89a22d11ec98394 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 24 Apr 2023 22:39:12 +0800 Subject: [PATCH 082/109] Ignore XMOS AICORE header check --- .github/scripts/kernel_checker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/scripts/kernel_checker.py b/.github/scripts/kernel_checker.py index f24bbf25722..a0706932fe0 100755 --- a/.github/scripts/kernel_checker.py +++ b/.github/scripts/kernel_checker.py @@ -87,7 +87,8 @@ r'.*\.git.*', r'.*portable/IAR/AtmelSAM7S64/.*AT91SAM7.*', r'.*portable/GCC/ARM7_AT91SAM7S/.*', - r'.*portable/MPLAB/PIC18F/stdio.h' + r'.*portable/MPLAB/PIC18F/stdio.h', + r'.*portable/ThirdParty/xClang/XCOREAI/*' ] KERNEL_THIRD_PARTY_PATTERNS = [ From 6d2b4423645fa1725f4f5d4b8594918bb76268f3 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Tue, 25 Apr 2023 11:04:22 +0800 Subject: [PATCH 083/109] Fix MSVC build init array --- tasks.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tasks.c b/tasks.c index ddfb3a1df4e..ff1eb0f8ace 100644 --- a/tasks.c +++ b/tasks.c @@ -441,10 +441,7 @@ PRIVILEGED_DATA static volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ -PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = -{ - [ 0 ... ( configNUMBER_OF_CORES - 1 ) ] = NULL, -}; /**< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = { NULL }; /**< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ /* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. * For tracking the state of remote threads, OpenOCD uses uxTopUsedPriority From c3fefa6910f99189380354ca28f39aeb20f734f9 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Tue, 25 Apr 2023 06:49:16 +0000 Subject: [PATCH 084/109] Fix MSVC building. --- tasks.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tasks.c b/tasks.c index 4fbabe2a142..2f221cb021b 100644 --- a/tasks.c +++ b/tasks.c @@ -441,10 +441,7 @@ PRIVILEGED_DATA static volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ -PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ] = -{ - [ 0 ... ( configNUMBER_OF_CORES - 1 ) ] = NULL, -}; /**< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ]; /**< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ /* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. * For tracking the state of remote threads, OpenOCD uses uxTopUsedPriority From 791e0c965f2a1e97acd30a75542cf9c59a2d1c9e Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Tue, 25 Apr 2023 17:50:05 +0800 Subject: [PATCH 085/109] Fix for c90 compiler --- tasks.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tasks.c b/tasks.c index 0cbd15660e7..c5f72711608 100644 --- a/tasks.c +++ b/tasks.c @@ -7464,8 +7464,9 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) { configRUN_TIME_COUNTER_TYPE ulReturn = 0; + BaseType_t i; - for( BaseType_t i = 0; i < configNUMBER_OF_CORES; i++ ) + for( i = 0; i < configNUMBER_OF_CORES; i++ ) { ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; } @@ -7482,6 +7483,7 @@ TickType_t uxTaskResetEventItemValue( void ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; + BaseType_t i; ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES; @@ -7491,7 +7493,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - for( BaseType_t i = 0; i < configNUMBER_OF_CORES; i++ ) + for( i = 0; i < configNUMBER_OF_CORES; i++ ) { ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; } From a108e909dbf1259e82ddd36cdf87f2a8aac064a3 Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Tue, 25 Apr 2023 17:53:21 +0800 Subject: [PATCH 086/109] Merge main to misra smp rebase20221130 (#3) * Update XMOS AICORE conflict (#77) * Define portBASE_TYPE in XMOS AICORE porting * Update enter critical from ISR API * Fix run time stats for SMP (#76) * Update get idle tasks stats * Fix get task stats * Fix missing configNUM_CORES * Update the uxSchedulerSuspended after prvCheckForRunStateChange (#62) * Update the uxSchedulerSuspended after the prvCheckForRunStateChange to prevent race condition in fromISR APIs * Fix SMP dev branch CI errors (#79) * Fix uncrustify * Update lexicon * Remove tailing space * Ignore XMOS AICORE header check * Fix ulTotalRunTime and ulTaskSwitchedInTime (#80) * SMP has multiple ulTotalRunTime and ulTaskSwitchedInTime * Smp dev compelete merge main 20230424 (#78) * Fix array-bounds compiler warning on gcc11+ in list.h (#580) listGET_OWNER_OF_NEXT_ENTRY computes `( pxConstList )->pxIndex->pxNext` after verifying that `( pxConstList )->pxIndex` points to `xListEnd`, which due to being a MiniListItem_t, can be shorter than a ListItem_t. Thus, `( pxConstList )->pxIndex` is a `ListItem_t *` that extends past the end of the `List_t` whose `xListEnd` it points to. This is fixed by accessing `pxNext` through a `MiniListItem_t` instead. * move the prototype for vApplicationIdleHook to task.h. (#600) Co-authored-by: pluess Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Update equal priority task preemption (#603) * vTaskResume and vTaskPrioritySet don't preempt equal priority task * Update vTaskResumeAll not to preempt task with equal priority * Fix in xTaskResumeFromISR * Update FreeRTOS/FreeRTOS build checks (#613) This is needed to be compatible with the refactoring done in this PR - https://github.com/FreeRTOS/FreeRTOS/pull/889 Signed-off-by: Gaurav Aggarwal Signed-off-by: Gaurav Aggarwal * Add ulTaskGetRunTimeCounter and ulTaskGetRunTimePercent (#611) Allow ulTaskGetIdleRunTimeCounter and ulTaskGetIdleRunTimePercent to be used whenever configGENERATE_RUN_TIME_STATS is enabled, as this is the only requirement for these functions to work. * Fix some CMake documentation typos (#616) The quick start instructions for CMake mention the "master" git branch which has been replaced by "main" in the current repo. The main CMakeLists.txt documents how to integrate a custom port. Fix a typo in the suggested CMake code. * Added support of 64bit events. (#597) * Added support of 64bit even Signed-off-by: Cervenka Dusan * Added missing brackets Signed-off-by: Cervenka Dusan * Made proper name for tick macro. Signed-off-by: Cervenka Dusan * Improved macro evaluation Signed-off-by: Cervenka Dusan * Fixed missed port files + documentation Signed-off-by: Cervenka Dusan * Changes made on PR Signed-off-by: Cervenka Dusan * Fix macro definition. Signed-off-by: Cervenka Dusan * Formatted code with uncrustify Signed-off-by: Cervenka Dusan --------- Signed-off-by: Cervenka Dusan * Introduce portMEMORY_BARRIER for Microblaze port. (#621) The introduction of `portMEMORY_BARRIER` will ensure the places in the kernel use a barrier will work. For example, `xTaskResumeAll` has a memory barrier to ensure its correctness when compiled with optimization enabled. Without the barrier `xTaskResumeAll` can fail (e.g. start reading and writing to address 0 and/or infinite looping) when `xPendingReadyList` contains more than one task to restore. In `xTaskResumeAll` the compiler chooses to cache the `pxTCB` the first time through the loop for use in every subsequent loop. This is incorrect as the removal of `pxTCB->xEventListItem` will actually change the value of `pxTCB` if it was read again at the top of the loop. The barrier forces the compiler to read `pxTCB` again at the top of the loop. The compiler is operating correctly. The removal `pxTCB->xEventListItem` executes on a `List_t *` and `ListItem_t *`. This means that the compiler can assume that any `MiniListItem_t` values are unchanged by the loop (i.e. "strict-aliasing"). This allows the compiler to cache `pxTCB` as it is obtained via a `MiniListItem_t`. This is incorrect in this case because it is possible for a `ListItem_t *` to actually alias a `MiniListItem_t`. This is technically a "violation of aliasing rules" so we use the the barrier to disable the strict-aliasing optimization in this loop. * Do not call exit() on MSVC Port when calling vPortEndScheduler (#624) * make port exitable * correctly set xPortRunning to False * add suggestions from Review Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * add suggestions from Review Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Update PR template to include checkbox for Unit Test related changes (#627) * Fix build failure introduced in PR #597 (#629) The PR #597 introduced a new config option configTICK_TYPE_WIDTH_IN_BITS which can be defined to one of the following: * TICK_TYPE_WIDTH_16_BITS - Tick type is 16 bit wide. * TICK_TYPE_WIDTH_32_BITS - Tick type is 32 bit wide. * TICK_TYPE_WIDTH_64_BITS - Tick type is 64 bit wide. Earlier we supported 16 and 32 bit width for tick type which was controlled using the config option configUSE_16_BIT_TICKS. The PR tried to maintain backward compatibility by honoring configUSE_16_BIT_TICKS. The backward compatibility did not work as expected though, as the macro configTICK_TYPE_WIDTH_IN_BITS was used before it was defined. This PR addresses it by ensuring that the macro configTICK_TYPE_WIDTH_IN_BITS is defined before it is used. Testing 1. configUSE_16_BIT_TICKS is defined to 0. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 109e: 4b50 ldr r3, [pc, #320] ; (11e0 ) 10a0: f8d3 4134 ldr.w r4, [r3, #308] ; 0x134 10a4: 3401 adds r4, #1 10a6: f8c3 4134 str.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 32 bit. 2. configUSE_16_BIT_TICKS is defined to 1. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 10e2: 4b53 ldr r3, [pc, #332] ; (1230 ) 10e4: f8b3 4134 ldrh.w r4, [r3, #308] ; 0x134 10e8: b2a4 uxth r4, r4 10ea: 3401 adds r4, #1 10ec: b2a4 uxth r4, r4 10ee: f8a3 4134 strh.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 16 bit. 3. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_16_BITS. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 10e2: 4b53 ldr r3, [pc, #332] ; (1230 ) 10e4: f8b3 4134 ldrh.w r4, [r3, #308] ; 0x134 10e8: b2a4 uxth r4, r4 10ea: 3401 adds r4, #1 10ec: b2a4 uxth r4, r4 10ee: f8a3 4134 strh.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 16 bit. 4. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_32_BITS. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 109e: 4b50 ldr r3, [pc, #320] ; (11e0 ) 10a0: f8d3 4134 ldr.w r4, [r3, #308] ; 0x134 10a4: 3401 adds r4, #1 10a6: f8c3 4134 str.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 32 bit. 5. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_64_BITS. ``` #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. ``` The testing was done for GCC/ARM_CM3 port which does not support 64 bit tick type. 6. Neither configUSE_16_BIT_TICKS nor configTICK_TYPE_WIDTH_IN_BITS defined. ``` #error Missing definition: One of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. ``` 7. Both configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS defined. ``` #error Only one of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. ``` Related issue - https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/628 Signed-off-by: Gaurav Aggarwal * Feature/fixing clang gnu compiler warnings (#620) * Adding in ability to support a library for freertos_config and a custom freertos_kernel_port (#558) * Using single name definition for libraries everywhere. (#558) * Supporting backwards compatibility with FREERTOS_CONFIG_FILE_DIRECTORY (#571) * Removing compiler warnings for GNU and Clang. (#571) * Added in documentation on how to consume from a main project. Added default PORT selection for native POSIX and MINGW platforms. * Only adding freertos_config if it exists. Removing auto generation of it from a FREERTOS_CONFIG_FILE_DIRECTORY. * Fixing clang and gnu compiler warnings. * Adding in project information and how to compile for GNU/clang * Fixing compiler issue with unused variable - no need to declare variable. * Adding in compile warnings for linux builds that kernel is okay with using. * Fixing more extra-semi-stmt clang warnings. * Moving definition of hooks into header files if features are enabled. * Fixing formatting with uncrustify. * Fixing merge conflicts with main merge. * Fixing compiler errors due to merge issues and formatting. * Fixing Line feeds. * Adding 'portNORETURN' into portmacros.h. Other Updates based on PR request * Further clean-up of clang and clang-tidy issues. * Removing compiler specific pragmas from common c files. * Fixing missing lexicon entry and uncrustify formatting changes. * Resolving merge issue multiple defnitions of proto for prvIdleTask * Fixing formatting issues that are not covered by uncrustify. Use clang-tidy instead if you want this level of control. * More uncrustify formatting issues. * Fixing extra bracket in #if statement. --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * POSIX port fixes (#626) * Fix types in POSIX port Use TaskFunction_t and StackType_t as other ports do. * Fix portTICK_RATE_MICROSECONDS in POSIX port --------- Co-authored-by: Jacques GUILLOU Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Cortex-M35P: Add Cortex-M35P port (#631) * Cortex-M35P: Add Cortex-M35P port The Cortex-M35P support added to kernel. The port hasn't been validated yet with TF-M. Hence TF-M support is not included in this port. Signed-off-by: Devaraj Ranganna * Add portNORETURN to the newly added portmacro.h Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Devaraj Ranganna Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> * Introduced Github Status Badge for Unit Tests (#634) * Introduced Github Status Badge for Unit Tests * Github status badge to point to latest run * Github status badge UT points to latest results * Fixed URL for Github Status badge --------- Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> * Remove C99 requirement from CMake file (#633) * Remove C99 requirement from CMake file The kernel source is C89 compliant and does not need C99. Signed-off-by: Gaurav Aggarwal * Explicitly set C89 requirement for kernel Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal * Add Thread Local Storage (TLS) support using Picolibc functions (#343) * Pass top of stack to configINIT_TLS_BLOCK Picolibc wants to allocate the per-task TLS block within the stack segment, so it will need to modify the top of stack value. Pass the pxTopOfStack variable to make this explicit. Signed-off-by: Keith Packard * Move newlib-specific definitions to separate file This reduces the clutter in FreeRTOS.h caused by having newlib-specific macros present there. Signed-off-by: Keith Packard * Make TLS code depend only on configUSE_C_RUNTIME_TLS_SUPPORT Remove reference to configUSE_NEWLIB_REENTRANT as that only works when using newlib. configUSE_C_RUNTIME_TLS_SUPPORT is always set when configUSE_NEWLIB_REENTRANT is set, so using both was redundant in that case. Signed-off-by: Keith Packard * portable-ARC: Adapt ARC support to use generalized TLS support With generalized thread local storage (TLS) support present in the core, the two ARC ports need to have the changes to the TCB mirrored to them. Signed-off-by: Keith Packard * Add Thread Local Storage (TLS) support using Picolibc functions This patch provides definitions of the general TLS support macros in terms of the Picolibc TLS support functions. Picolibc is normally configured to use TLS internally for all variables that are intended to be task-local, so these changes are necessary for picolibc to work correctly with FreeRTOS. The picolibc helper functions rely on elements within the linker script to arrange the TLS data in memory and define some symbols. Applications wanting to use this mechanism will need changes in their linker script when migrating to picolibc. Signed-off-by: Keith Packard --------- Signed-off-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Interrupt priority assert improvements for CM3/4/7 (#602) * Interrupt priority assert improvements for CM3/4/7 In the ARM_CM3, ARM_CM4, and ARM_CM7 ports, change the assertion that `configMAX_SYSCALL_INTERRUPT_PRIORITY` is nonzero to account for the number of priority bits implemented by the hardware. Change these ports to also use the lowest priority for PendSV and SysTick, ignoring `configKERNEL_INTERRUPT_PRIORITY`. * Remove not needed configKERNEL_INTERRUPT_PRIORITY define Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal * Introduced code coverage status badge (#635) * Introduced code coverage status badge * Trying to fix the URL checker issue * Fix URL check Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * added portPOINTER_SIZE_TYPE and SIZE_MAX definition to PIC24/dsPIC port (#636) * added portPOINTER_SIZE_TYPE definition to PIC24/dsPIC port * Added SIZE_MAX definition to PIC24/dsPIC33 * Fix TLS and stack alignment when using picolibc (#637) Both the TLS block and stack must be correctly aligned when using picolibc. The architecture stack alignment is represented by the portBYTE_ALIGNMENT_MASK and the TLS block alignment is provided by the Picolibc _tls_align() inline function for Picolibc version 1.8 and above. For older versions of Picolibc, we'll assume that the TLS block requires the same alignment as the stack. For downward growing stacks, this requires aligning the start of the TLS block to the maximum of the stack alignment and the TLS alignment. With this, both the TLS block and stack will now be correctly aligned. For upward growing stacks, the two areas must be aligned independently; the TLS block is aligned from the start of the stack, then the tls space is allocated, and then the stack is aligned above that. It's probably useful to know here that the linker ensures that variables within the TLS block are assigned offsets that match their alignment requirements. If the TLS block itself is correctly aligned, then everything within will also be. I have only tested the downward growing stack branch of this patch. Signed-off-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Enable building the GCC Cortex-R5 port without an FPU (#586) * Ensure configUSE_TASK_FPU_SUPPORT option is set correctly If one does enable the FPU of the Cortex-R5 processor, then the GCC compiler will define the macro __ARM_FP. This can be used to ensure, that the configUSE_TASK_FPU_SUPPORT is set accordingly. * Enable the implementation of vPortTaskUsesFPU only if configUSE_TASK_FPU_SUPPORT is set to 1 * Remove error case in pxPortInitialiseStack The case of configUSE_TASK_FPU_SUPPORT is 0 is now handled * Enable access to FPU registers only if FPU is enabled * Make minor formating changes * Format ARM Cortex-R5 port * Address review comments from @ChristosZosi * Minor code review suggestions Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Christos Zosimidis Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal * Fix freertos_kernel cmake property, Posix Port (#640) * Fix freertos_kernel cmake property, Posix Port * Moves the `set_property()` call below the target definition in top level CMakeLists file * Corrects billion value from `ULL` suffix (not C90 compliant) to `UL` suffix with cast to uint64_t * Add blank line to CMakeLists.txt * Add missing FreeRTOS+ defines * Run kernel demos and unit tests for PR changes (#645) * Run kernel demos and unit tests for PR changes Kernel demos check builds multiple demos from FreeRTOS/FreeRTOS and unit tests check runs unit tests in FreeRTOS/FreeRTOS. Both of these checks currently use main branch of FreeRTOS-Kernel. This commits updates these checks to use the changes in the PR. Signed-off-by: Gaurav Aggarwal * Do not specify PR SHA explicitly as that is default Signed-off-by: Gaurav Aggarwal * Remove explicit PR SHA from kernel checks Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal * Add functions to get the buffers of statically created objects (#641) Added various ...GetStaticBuffer() functions to get the buffers of statically created objects. --------- Co-authored-by: Paul Bartell Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal * Cortex-M Assert when NVIC implements 8 PRIO bits (#639) * Cortex-M Assert when NVIC implements 8 PRIO bits * Fix CM3 ports * Fix ARM_CM3_MPU * Fix ARM CM3 * Fix ARM_CM4_MPU * Fix ARM_CM4 * Fix GCC ARM_CM7 * Fix IAR ARM ports * Uncrustify changes * Fix MikroC_ARM_CM4F port * Fix MikroC_ARM_CM4F port-(2) * Fix RVDS ARM ports * Revert changes for Tasking/ARM_CM4F port * Revert changes for Tasking/ARM_CM4F port-(2) * Update port.c Fix GCC/ARM_CM4F port * Update port.c * update GCC\ARM_CM4F port * update port.c * Assert to check configMAX_SYSCALL_INTERRUPT_PRIORITY is set to higher priority * Fix merge error: remove duplicate code * Fix typos --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Ubuntu * Remove C90 requirement from CMakeLists (#649) This is needed as it is breaking projects - https://forums.freertos.org/t/freertos-gcc-cmake/16984 We will re-evaluate and accordingly add this later. Signed-off-by: Gaurav Aggarwal * Only add alignment padding when needed (#650) Heap 4 and Heap 5 add some padding to ensure that the allocated blocks are always aligned to portBYTE_ALIGNMENT bytes. The code until now was adding padding always even if the resulting block was already aligned. This commits updates the code to only add padding if the resulting block is not aligned. Signed-off-by: Gaurav Aggarwal * add a missing comma (#651) * fix conversion warning (#658) FreeRTOS-Kernel/portable/GCC/ARM_CM4F/port.c:399:41: error: conversion from 'uint32_t' {aka 'long unsigned int'} to 'uint8_t' {aka 'unsigned char'} may change value [-Werror=conversion] Signed-off-by: Vo Trung Chi * ARMv7M: Adjust implemented priority bit assertions (#665) Adjust assertions related to the CMSIS __NVIC_PRIO_BITS and FreeRTOS configPRIO_BITS configuration macros such that these macros specify the minimum number of implemented priority bits supported by a config build rather than the exact number of implemented priority bits. Related to Qemu issue #1122 * Format portmacro.h in arm CM0 ports * portable/ARM_CM0: Add xPortIsInsideInterrupt Add missing xPortIsInsideInterrupt function to Cortex-M0 port. --------- Signed-off-by: Gaurav Aggarwal Signed-off-by: Cervenka Dusan Signed-off-by: Devaraj Ranganna Signed-off-by: Keith Packard Signed-off-by: Vo Trung Chi Co-authored-by: Archit Gupta <71798289+archigup@users.noreply.github.com> Co-authored-by: tcpluess Co-authored-by: pluess Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Chris Copeland Co-authored-by: David J. Fiddes <35607151+davefiddes@users.noreply.github.com> Co-authored-by: Dusan Cervenka Co-authored-by: bbain <16752579+bbain@users.noreply.github.com> Co-authored-by: Ju1He1 <93189163+Ju1He1@users.noreply.github.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Co-authored-by: phelter Co-authored-by: jacky309 Co-authored-by: Jacques GUILLOU Co-authored-by: Devaraj Ranganna Co-authored-by: Gaurav Aggarwal Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com> Co-authored-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Joseph Julicher Co-authored-by: Paul Bartell Co-authored-by: Christos Zosimidis Co-authored-by: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Co-authored-by: Holden Co-authored-by: Darian <32921628+Dazza0@users.noreply.github.com> Co-authored-by: Ubuntu Co-authored-by: Nicolas Co-authored-by: Vo Trung Chi * Fix for c90 compiler --------- Signed-off-by: Gaurav Aggarwal Signed-off-by: Cervenka Dusan Signed-off-by: Devaraj Ranganna Signed-off-by: Keith Packard Signed-off-by: Vo Trung Chi Co-authored-by: Archit Gupta <71798289+archigup@users.noreply.github.com> Co-authored-by: tcpluess Co-authored-by: pluess Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Chris Copeland Co-authored-by: David J. Fiddes <35607151+davefiddes@users.noreply.github.com> Co-authored-by: Dusan Cervenka Co-authored-by: bbain <16752579+bbain@users.noreply.github.com> Co-authored-by: Ju1He1 <93189163+Ju1He1@users.noreply.github.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Co-authored-by: phelter Co-authored-by: jacky309 Co-authored-by: Jacques GUILLOU Co-authored-by: Devaraj Ranganna Co-authored-by: Gaurav Aggarwal Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com> Co-authored-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Joseph Julicher Co-authored-by: Paul Bartell Co-authored-by: Christos Zosimidis Co-authored-by: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Co-authored-by: Darian <32921628+Dazza0@users.noreply.github.com> Co-authored-by: Ubuntu Co-authored-by: Nicolas Co-authored-by: Vo Trung Chi --- .github/lexicon.txt | 1 + .github/scripts/kernel_checker.py | 3 +- portable/CCS/ARM_CM3/port.c | 20 ++- portable/CCS/ARM_CM4F/port.c | 20 ++- portable/GCC/ARM_CM0/portmacro.h | 156 +++++++++++------- portable/GCC/ARM_CM3/port.c | 20 ++- portable/GCC/ARM_CM3_MPU/port.c | 28 ++-- portable/GCC/ARM_CM4F/port.c | 20 ++- portable/GCC/ARM_CM4_MPU/port.c | 28 ++-- portable/GCC/ARM_CM7/r0p1/port.c | 20 ++- portable/IAR/ARM_CM0/portmacro.h | 149 ++++++++++------- portable/IAR/ARM_CM3/port.c | 20 ++- portable/IAR/ARM_CM4F/port.c | 20 ++- portable/IAR/ARM_CM4F_MPU/port.c | 20 ++- portable/IAR/ARM_CM7/r0p1/port.c | 20 ++- portable/MikroC/ARM_CM4F/port.c | 20 ++- portable/RVDS/ARM_CM0/portmacro.h | 135 +++++++++------ portable/RVDS/ARM_CM3/port.c | 20 ++- portable/RVDS/ARM_CM4F/port.c | 20 ++- portable/RVDS/ARM_CM4_MPU/port.c | 20 ++- portable/RVDS/ARM_CM7/r0p1/port.c | 20 ++- portable/ThirdParty/xClang/XCOREAI/portasm.S | 2 +- .../ThirdParty/xClang/XCOREAI/portmacro.h | 6 +- tasks.c | 120 ++++++++------ 24 files changed, 549 insertions(+), 359 deletions(-) diff --git a/.github/lexicon.txt b/.github/lexicon.txt index 305498fdc59..5e7d6dbbf75 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -1521,6 +1521,7 @@ prstc prttc prv prvaddcurrenttasktodelayedlist +prvcheckforrunstatechange prvcheckinterfaces prvchecktaskswaitingtermination prvcopydatatoqueue diff --git a/.github/scripts/kernel_checker.py b/.github/scripts/kernel_checker.py index f24bbf25722..a0706932fe0 100755 --- a/.github/scripts/kernel_checker.py +++ b/.github/scripts/kernel_checker.py @@ -87,7 +87,8 @@ r'.*\.git.*', r'.*portable/IAR/AtmelSAM7S64/.*AT91SAM7.*', r'.*portable/GCC/ARM7_AT91SAM7S/.*', - r'.*portable/MPLAB/PIC18F/stdio.h' + r'.*portable/MPLAB/PIC18F/stdio.h', + r'.*portable/ThirdParty/xClang/XCOREAI/*' ] KERNEL_THIRD_PARTY_PATTERNS = [ diff --git a/portable/CCS/ARM_CM3/port.c b/portable/CCS/ARM_CM3/port.c index ef5fa5b9340..f3c4e5add03 100755 --- a/portable/CCS/ARM_CM3/port.c +++ b/portable/CCS/ARM_CM3/port.c @@ -287,19 +287,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/CCS/ARM_CM4F/port.c b/portable/CCS/ARM_CM4F/port.c index c43cf0ef314..c675afe67b4 100755 --- a/portable/CCS/ARM_CM4F/port.c +++ b/portable/CCS/ARM_CM4F/port.c @@ -306,19 +306,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/GCC/ARM_CM0/portmacro.h b/portable/GCC/ARM_CM0/portmacro.h index 408162d6402..b9e9ef6623f 100644 --- a/portable/GCC/ARM_CM0/portmacro.h +++ b/portable/GCC/ARM_CM0/portmacro.h @@ -28,11 +28,13 @@ #ifndef PORTMACRO_H - #define PORTMACRO_H +#define PORTMACRO_H - #ifdef __cplusplus - extern "C" { - #endif +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. @@ -45,84 +47,120 @@ */ /* Type definitions. */ - #define portCHAR char - #define portFLOAT float - #define portDOUBLE double - #define portLONG long - #define portSHORT short - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE long - - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; - - #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ - #define portTICK_TYPE_IS_ATOMIC 1 - #else - #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. - #endif + #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. +#endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 8 - #define portDONT_DISCARD __attribute__( ( used ) ) - #define portNORETURN __attribute__( ( noreturn ) ) +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +#define portDONT_DISCARD __attribute__( ( used ) ) +#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ - extern void vPortYield( void ); - #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) - #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) - #define portYIELD() vPortYield() - #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) - #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) \ + do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ + while( 0 ) +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ - extern void vPortEnterCritical( void ); - extern void vPortExitCritical( void ); - extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__( ( naked ) ); - extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( naked ) ); - - #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) - #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) - #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) - #define portENTER_CRITICAL() vPortEnterCritical() - #define portEXIT_CRITICAL() vPortExitCritical() +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__( ( naked ) ); +extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( naked ) ); + +#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) +#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) +#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ - #ifndef portSUPPRESS_TICKS_AND_SLEEP - extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); - #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) - #endif +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portNOP() +#define portNOP() - #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) +#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) - #ifdef __cplusplus - } - #endif + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) +#endif + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ #endif /* PORTMACRO_H */ diff --git a/portable/GCC/ARM_CM3/port.c b/portable/GCC/ARM_CM3/port.c index 4aa1f2425d7..9b42eac5a4e 100755 --- a/portable/GCC/ARM_CM3/port.c +++ b/portable/GCC/ARM_CM3/port.c @@ -330,19 +330,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index e33df014c0e..619f2b0c8be 100755 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -452,21 +452,25 @@ BaseType_t xPortStartScheduler( void ) } #ifdef __NVIC_PRIO_BITS - { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } + { + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); + } #endif #ifdef configPRIO_BITS - { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } + { + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); + } #endif /* Shift the priority group value back to its position within the AIRCR diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c index fd9e6dbb8f2..88fc76db894 100755 --- a/portable/GCC/ARM_CM4F/port.c +++ b/portable/GCC/ARM_CM4F/port.c @@ -373,19 +373,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index 1733fd82072..ab76ee84204 100755 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -495,21 +495,25 @@ BaseType_t xPortStartScheduler( void ) } #ifdef __NVIC_PRIO_BITS - { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } + { + /* + * Check that the number of implemented priority bits queried + * from hardware is at least as many as specified in the + * CMSIS __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); + } #endif #ifdef configPRIO_BITS - { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } + { + /* + * Check that the number of implemented priority bits queried + * from hardware is at least as many as specified in the + * FreeRTOS configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); + } #endif /* Shift the priority group value back to its position within the AIRCR diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c index 316dba13b8e..2be4f27704d 100755 --- a/portable/GCC/ARM_CM7/r0p1/port.c +++ b/portable/GCC/ARM_CM7/r0p1/port.c @@ -361,19 +361,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM0/portmacro.h b/portable/IAR/ARM_CM0/portmacro.h index ce1aa08fc9d..5dcc949b228 100644 --- a/portable/IAR/ARM_CM0/portmacro.h +++ b/portable/IAR/ARM_CM0/portmacro.h @@ -26,12 +26,15 @@ * */ + #ifndef PORTMACRO_H - #define PORTMACRO_H +#define PORTMACRO_H - #ifdef __cplusplus - extern "C" { - #endif +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. @@ -44,87 +47,119 @@ */ /* Type definitions. */ - #define portCHAR char - #define portFLOAT float - #define portDOUBLE double - #define portLONG long - #define portSHORT short - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE long - - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; - - - #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + + +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ - #define portTICK_TYPE_IS_ATOMIC 1 - #else - #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. - #endif + #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. +#endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 8 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Scheduler utilities. */ - extern void vPortYield( void ); - #define portNVIC_INT_CTRL ( ( volatile uint32_t * ) 0xe000ed04 ) - #define portNVIC_PENDSVSET 0x10000000 - #define portYIELD() vPortYield() - #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET - #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +extern void vPortYield( void ); +#define portNVIC_INT_CTRL ( ( volatile uint32_t * ) 0xe000ed04 ) +#define portNVIC_PENDSVSET 0x10000000 +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ - extern void vPortEnterCritical( void ); - extern void vPortExitCritical( void ); - extern uint32_t ulSetInterruptMaskFromISR( void ); - extern void vClearInterruptMaskFromISR( uint32_t ulMask ); +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulSetInterruptMaskFromISR( void ); +extern void vClearInterruptMaskFromISR( uint32_t ulMask ); - #define portDISABLE_INTERRUPTS() __asm volatile ( "cpsid i" ) - #define portENABLE_INTERRUPTS() __asm volatile ( "cpsie i" ) - #define portENTER_CRITICAL() vPortEnterCritical() - #define portEXIT_CRITICAL() vPortExitCritical() - #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) +#define portDISABLE_INTERRUPTS() __asm volatile ( "cpsid i" ) +#define portENABLE_INTERRUPTS() __asm volatile ( "cpsie i" ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ - #ifndef portSUPPRESS_TICKS_AND_SLEEP - extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); - #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) - #endif +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) + +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) +#endif + +/*-----------------------------------------------------------*/ - #define portNOP() +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ - #pragma diag_suppress=Pa082 +#pragma diag_suppress=Pa082 - #ifdef __cplusplus - } - #endif +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ #endif /* PORTMACRO_H */ diff --git a/portable/IAR/ARM_CM3/port.c b/portable/IAR/ARM_CM3/port.c index f1c78e46240..d54c3aceb4a 100755 --- a/portable/IAR/ARM_CM3/port.c +++ b/portable/IAR/ARM_CM3/port.c @@ -279,19 +279,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM4F/port.c b/portable/IAR/ARM_CM4F/port.c index 05d5be0aa65..e0deaf12840 100755 --- a/portable/IAR/ARM_CM4F/port.c +++ b/portable/IAR/ARM_CM4F/port.c @@ -317,19 +317,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index 69b7bc5d9bc..1b7cca65c86 100755 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -431,19 +431,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c index 9217653a7d4..63f83993db9 100755 --- a/portable/IAR/ARM_CM7/r0p1/port.c +++ b/portable/IAR/ARM_CM7/r0p1/port.c @@ -305,19 +305,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/MikroC/ARM_CM4F/port.c b/portable/MikroC/ARM_CM4F/port.c index 1936de19447..8ef593f5523 100755 --- a/portable/MikroC/ARM_CM4F/port.c +++ b/portable/MikroC/ARM_CM4F/port.c @@ -367,19 +367,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM0/portmacro.h b/portable/RVDS/ARM_CM0/portmacro.h index 54165e74cc4..4a1ea8a7b3a 100644 --- a/portable/RVDS/ARM_CM0/portmacro.h +++ b/portable/RVDS/ARM_CM0/portmacro.h @@ -47,76 +47,113 @@ */ /* Type definitions. */ - #define portCHAR char - #define portFLOAT float - #define portDOUBLE double - #define portLONG long - #define portSHORT short - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE long - - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; - - #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ - #define portTICK_TYPE_IS_ATOMIC 1 - #else - #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. - #endif + #define portTICK_TYPE_IS_ATOMIC 1 +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. +#endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 8 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Scheduler utilities. */ - extern void vPortYield( void ); - #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) - #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) - #define portYIELD() vPortYield() - #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) - #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) \ + do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ + while( 0 ) +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ - extern void vPortEnterCritical( void ); - extern void vPortExitCritical( void ); - extern uint32_t ulSetInterruptMaskFromISR( void ); - extern void vClearInterruptMaskFromISR( uint32_t ulMask ); - - #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) - #define portDISABLE_INTERRUPTS() __disable_irq() - #define portENABLE_INTERRUPTS() __enable_irq() - #define portENTER_CRITICAL() vPortEnterCritical() - #define portEXIT_CRITICAL() vPortExitCritical() +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulSetInterruptMaskFromISR( void ); +extern void vClearInterruptMaskFromISR( uint32_t ulMask ); + +#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) +#define portDISABLE_INTERRUPTS() __disable_irq() +#define portENABLE_INTERRUPTS() __enable_irq() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ - #ifndef portSUPPRESS_TICKS_AND_SLEEP - extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); - #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) - #endif +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) + +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE __forceinline +#endif + +/*-----------------------------------------------------------*/ + +static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; - #define portNOP() + /* Obtain the number of the currently executing interrupt. */ + __asm + { +/* *INDENT-OFF* */ + mrs ulCurrentInterrupt, ipsr +/* *INDENT-ON* */ + } + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #ifdef __cplusplus diff --git a/portable/RVDS/ARM_CM3/port.c b/portable/RVDS/ARM_CM3/port.c index 2ffdd9cc8bd..ae7ce37f37b 100755 --- a/portable/RVDS/ARM_CM3/port.c +++ b/portable/RVDS/ARM_CM3/port.c @@ -332,19 +332,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM4F/port.c b/portable/RVDS/ARM_CM4F/port.c index bf2fb86f76a..cb003aa38f9 100755 --- a/portable/RVDS/ARM_CM4F/port.c +++ b/portable/RVDS/ARM_CM4F/port.c @@ -398,19 +398,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index e0bd8c86d0f..13e2f8a8ed1 100755 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -491,19 +491,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/RVDS/ARM_CM7/r0p1/port.c b/portable/RVDS/ARM_CM7/r0p1/port.c index 2e81e324df9..1df54ab2802 100755 --- a/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/portable/RVDS/ARM_CM7/r0p1/port.c @@ -382,19 +382,23 @@ BaseType_t xPortStartScheduler( void ) #ifdef __NVIC_PRIO_BITS { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the CMSIS + * __NVIC_PRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); + /* + * Check that the number of implemented priority bits queried from + * hardware is at least as many as specified in the FreeRTOS + * configPRIO_BITS configuration macro. + */ + configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); } #endif diff --git a/portable/ThirdParty/xClang/XCOREAI/portasm.S b/portable/ThirdParty/xClang/XCOREAI/portasm.S index 702e9a2f021..7445672a08e 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portasm.S +++ b/portable/ThirdParty/xClang/XCOREAI/portasm.S @@ -87,7 +87,7 @@ rtos_interrupt_callback_common: bla r1} /* and call the callback function. */ {set sp, r4 /* Restore the task's SP now. */ - + get r11, id} /* Get the logical core ID into r11. */ ldaw r0, dp[rtos_core_map] ldw r0, r0[r11] /* Translate to the RTOS core ID into r0. */ diff --git a/portable/ThirdParty/xClang/XCOREAI/portmacro.h b/portable/ThirdParty/xClang/XCOREAI/portmacro.h index aef12cf3749..019d29a3c7a 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portmacro.h +++ b/portable/ThirdParty/xClang/XCOREAI/portmacro.h @@ -26,6 +26,8 @@ typedef double portDOUBLE; typedef int32_t BaseType_t; typedef uint32_t UBaseType_t; +#define portBASE_TYPE BaseType_t + #if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff @@ -163,8 +165,8 @@ void vTaskExitCritical(void); #define portENTER_CRITICAL() vTaskEnterCritical() #define portEXIT_CRITICAL() vTaskExitCritical() -extern UBaseType_t vTaskEnterCriticalFromISR( void ); -extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ); +extern portBASE_TYPE vTaskEnterCriticalFromISR( void ); +extern void vTaskExitCriticalFromISR( portBASE_TYPE xSavedInterruptStatus ); #define portENTER_CRITICAL_FROM_ISR vTaskEnterCriticalFromISR #define portEXIT_CRITICAL_FROM_ISR vTaskExitCriticalFromISR diff --git a/tasks.c b/tasks.c index 2f221cb021b..c5f72711608 100644 --- a/tasks.c +++ b/tasks.c @@ -294,7 +294,7 @@ typedef BaseType_t TaskRunning_t; /* Code below here allows infinite loop controlling, especially for the infinite loop * in idle task function (for example when performing unit tests). */ #ifndef INFINITE_LOOP - #define INFINITE_LOOP() 1 + #define INFINITE_LOOP() 1 #endif /* @@ -466,8 +466,8 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t /* Do not move these variables to function scope as doing so prevents the * code working with debuggers that need to remove the static qualifier. */ - PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime[ configNUM_CORES ] = { 0UL }; /**< Holds the value of a timer/counter the last time a task was switched in. */ - PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ configNUM_CORES ] = { 0UL }; /**< Holds the total amount of execution time as defined by the run time counter clock. */ +PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the value of a timer/counter the last time a task was switched in. */ +PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the total amount of execution time as defined by the run time counter clock. */ #endif @@ -696,7 +696,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; static void prvCheckForRunStateChange( void ) { UBaseType_t uxPrevCriticalNesting; - UBaseType_t uxPrevSchedulerSuspended; TCB_t * pxThisTCB; /* This should be skipped if called from an ISR. If the task on the current @@ -720,24 +719,19 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * and reacquire the correct locks. And then, do it all over again * if our state changed again during the reacquisition. */ uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT(); - uxPrevSchedulerSuspended = uxSchedulerSuspended; - - /* This must only be called the first time we enter into a critical - * section, otherwise it could context switch in the middle of a - * critical section. */ - configASSERT( ( uxPrevCriticalNesting + uxPrevSchedulerSuspended ) == 1U ); if( uxPrevCriticalNesting > 0U ) { portSET_CRITICAL_NESTING_COUNT( 0U ); + portRELEASE_ISR_LOCK(); } else { - portGET_ISR_LOCK(); - uxSchedulerSuspended = 0U; + /* The scheduler is suspended. uxSchedulerSuspended is updated + * only when the task is not requested to yield. */ + mtCOVERAGE_TEST_MARKER(); } - portRELEASE_ISR_LOCK(); portRELEASE_TASK_LOCK(); portMEMORY_BARRIER(); @@ -755,11 +749,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; portGET_ISR_LOCK(); portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting ); - uxSchedulerSuspended = uxPrevSchedulerSuspended; if( uxPrevCriticalNesting == 0U ) { - /* uxPrevSchedulerSuspended must be 1. */ portRELEASE_ISR_LOCK(); } } @@ -816,7 +808,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * than priority level of currently ready tasks. */ if( pxTCB->uxPriority >= uxTopReadyPriority ) #else - /* Yield is not required for a task which is already running. */ if( taskTASK_IS_RUNNING( pxTCB ) == pdFALSE ) #endif @@ -3402,14 +3393,11 @@ void vTaskSuspendAll( void ) portSOFTWARE_BARRIER(); portGET_TASK_LOCK(); - portGET_ISR_LOCK(); - - /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment - * is used to allow calls to vTaskSuspendAll() to nest. */ - ++uxSchedulerSuspended; - portRELEASE_ISR_LOCK(); - if( uxSchedulerSuspended == 1U ) + /* uxSchedulerSuspended is increased after prvCheckForRunStateChange. The + * purpose is to prevent altering the variable when fromISR APIs are readying + * it. */ + if( uxSchedulerSuspended == 0U ) { if( portGET_CRITICAL_NESTING_COUNT() == 0U ) { @@ -3425,6 +3413,13 @@ void vTaskSuspendAll( void ) mtCOVERAGE_TEST_MARKER(); } + portGET_ISR_LOCK(); + + /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment + * is used to allow calls to vTaskSuspendAll() to nest. */ + ++uxSchedulerSuspended; + portRELEASE_ISR_LOCK(); + portCLEAR_INTERRUPT_MASK( ulState ); } else @@ -3777,7 +3772,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char return pxReturn; } - #else + #else /* if ( configNUMBER_OF_CORES == 1 ) */ static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, const char pcNameToQuery[] ) { @@ -4579,9 +4574,9 @@ BaseType_t xTaskIncrementTick( void ) #if ( configGENERATE_RUN_TIME_STATS == 1 ) { #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE - portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime[ 0 ] ); #else - ulTotalRunTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + ulTotalRunTime[ 0 ] = portGET_RUN_TIME_COUNTER_VALUE(); #endif /* Add the amount of time the task has been running to the @@ -4591,16 +4586,16 @@ BaseType_t xTaskIncrementTick( void ) * overflows. The guard against negative values is to protect * against suspect run time stat counter implementations - which * are provided by the application, not the kernel. */ - if( ulTotalRunTime > ulTaskSwitchedInTime ) + if( ulTotalRunTime[ 0 ] > ulTaskSwitchedInTime[ 0 ] ) { - pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime[ 0 ] - ulTaskSwitchedInTime[ 0 ] ); } else { mtCOVERAGE_TEST_MARKER(); } - ulTaskSwitchedInTime = ulTotalRunTime; + ulTaskSwitchedInTime[ 0 ] = ulTotalRunTime[ 0 ]; } #endif /* configGENERATE_RUN_TIME_STATS */ @@ -7431,18 +7426,10 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) { - configRUN_TIME_COUNTER_TYPE ulReturn = 0; - BaseType_t i = 0; - - for( i = ( BaseType_t ) 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) - { - ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; - } - - return ulReturn; + return xTask->ulRunTimeCounter; } -#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +#endif /*-----------------------------------------------------------*/ #if ( configGENERATE_RUN_TIME_STATS == 1 ) @@ -7450,10 +7437,8 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; - configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; - BaseType_t i = 0; - ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) ( portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES ); + ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); /* For percentage calculations. */ ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; @@ -7461,12 +7446,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - for( i = ( BaseType_t ) 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) - { - ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; - } - - ulReturn = ulRunTimeCounter / ulTotalTime; + ulReturn = xTask->ulRunTimeCounter / ulTotalTime; } else { @@ -7479,24 +7459,56 @@ TickType_t uxTaskResetEventItemValue( void ) #endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ /*-----------------------------------------------------------*/ -#if ( configGENERATE_RUN_TIME_STATS == 1 ) +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) { - return ulTaskGetRunTimeCounter( xIdleTaskHandle ); + configRUN_TIME_COUNTER_TYPE ulReturn = 0; + BaseType_t i; + + for( i = 0; i < configNUMBER_OF_CORES; i++ ) + { + ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; + } + + return ulReturn; } -#endif +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ /*-----------------------------------------------------------*/ -#if ( configGENERATE_RUN_TIME_STATS == 1 ) +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) { - return ulTaskGetRunTimePercent( xIdleTaskHandle ); + configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; + configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; + BaseType_t i; + + ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES; + + /* For percentage calculations. */ + ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) + { + for( i = 0; i < configNUMBER_OF_CORES; i++ ) + { + ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; + } + + ulReturn = ulRunTimeCounter / ulTotalTime; + } + else + { + ulReturn = 0; + } + + return ulReturn; } -#endif +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ /*-----------------------------------------------------------*/ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, From 4c7a8dac5406ed48fd7fec3b5dc2695a1ba87d56 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Tue, 25 Apr 2023 21:11:12 +0800 Subject: [PATCH 087/109] Fix MISRA violation in get idle run time counter --- tasks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks.c b/tasks.c index c5f72711608..2745ae11379 100644 --- a/tasks.c +++ b/tasks.c @@ -7466,7 +7466,7 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulReturn = 0; BaseType_t i; - for( i = 0; i < configNUMBER_OF_CORES; i++ ) + for( i = 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) { ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; } @@ -7493,7 +7493,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - for( i = 0; i < configNUMBER_OF_CORES; i++ ) + for( i = 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) { ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; } From b9470a345329c860dd1d49ecb7204eab2c83dab7 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Tue, 25 Apr 2023 21:21:31 +0800 Subject: [PATCH 088/109] Fix CI check error --- .github/lexicon.txt | 1 + tasks.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/lexicon.txt b/.github/lexicon.txt index 5e7d6dbbf75..78c911c5d91 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -317,6 +317,7 @@ coproc coprocessor coprocessors coreid +coverity covfs cp cpacr diff --git a/tasks.c b/tasks.c index 2745ae11379..58e95cf526b 100644 --- a/tasks.c +++ b/tasks.c @@ -441,7 +441,7 @@ PRIVILEGED_DATA static volatile BaseType_t xYieldPendings[ configNUMBER_OF_CORES PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ -PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ]; /**< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandles[ configNUMBER_OF_CORES ]; /**< Holds the handles of the idle tasks. The idle tasks are created automatically when the scheduler is started. */ /* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. * For tracking the state of remote threads, OpenOCD uses uxTopUsedPriority @@ -795,6 +795,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; BaseType_t xCurrentCoreTaskPriority; BaseType_t xLowestPriorityCore = ( BaseType_t ) -1; BaseType_t xCoreID; + #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) BaseType_t xYieldCount = 0; #endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */ From 56a9c7e882c236a72ba327d582686e37e2fd37d9 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Tue, 25 Apr 2023 22:37:57 +0800 Subject: [PATCH 089/109] Fix single MISRA violation --- include/task.h | 2 +- tasks.c | 56 +++++++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/include/task.h b/include/task.h index 9da6dddb3cf..8b4cf4b4a43 100644 --- a/include/task.h +++ b/include/task.h @@ -747,7 +747,7 @@ typedef enum * \defgroup vTaskAllocateMPURegions vTaskAllocateMPURegions * \ingroup Tasks */ -void vTaskAllocateMPURegions( TaskHandle_t xTask, +void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; /** diff --git a/tasks.c b/tasks.c index 58e95cf526b..30ed4add71e 100644 --- a/tasks.c +++ b/tasks.c @@ -5181,7 +5181,7 @@ void vTaskMissedYield( void ) * */ -portTASK_FUNCTION( prvIdleTask, pvParameters ) +static portTASK_FUNCTION( prvIdleTask, pvParameters ) { /* Stop warnings. */ ( void ) pvParameters; @@ -5375,7 +5375,7 @@ portTASK_FUNCTION( prvIdleTask, pvParameters ) TCB_t * pxTCB; if( ( xIndex >= 0 ) && - ( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) + ( xIndex < ( BaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) { pxTCB = prvGetTCBFromHandle( xTaskToSet ); configASSERT( pxTCB != NULL ); @@ -5395,7 +5395,7 @@ portTASK_FUNCTION( prvIdleTask, pvParameters ) TCB_t * pxTCB; if( ( xIndex >= 0 ) && - ( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) + ( xIndex < ( BaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) { pxTCB = prvGetTCBFromHandle( xTaskToQuery ); pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; @@ -5414,7 +5414,7 @@ portTASK_FUNCTION( prvIdleTask, pvParameters ) #if ( portUSING_MPU_WRAPPERS == 1 ) void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, - const MemoryRegion_t * const xRegions ) + const MemoryRegion_t * const pxRegions ) { TCB_t * pxTCB; @@ -5422,7 +5422,7 @@ portTASK_FUNCTION( prvIdleTask, pvParameters ) * the calling task. */ pxTCB = prvGetTCBFromHandle( xTaskToModify ); - vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), pxRegions, NULL, 0 ); } #endif /* portUSING_MPU_WRAPPERS */ @@ -6507,11 +6507,11 @@ static void prvResetNextTaskUnblockTime( void ) size_t x; /* Start by copying the entire string. */ - strcpy( pcBuffer, pcTaskName ); + ( void ) strcpy( pcBuffer, pcTaskName ); /* Pad the end of the string with spaces to ensure columns line up when * printed out. */ - for( x = strlen( pcBuffer ); x < ( size_t ) ( configMAX_TASK_NAME_LEN - 1 ); x++ ) + for( x = strlen( pcBuffer ); x < ( size_t ) ( ( size_t ) configMAX_TASK_NAME_LEN - 1U ); x++ ) { pcBuffer[ x ] = ' '; } @@ -6786,26 +6786,26 @@ TickType_t uxTaskResetEventItemValue( void ) #if ( configUSE_TASK_NOTIFICATIONS == 1 ) - uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWait, + uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) { uint32_t ulReturn; - configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + configASSERT( uxIndexToWaitOn < configTASK_NOTIFICATION_ARRAY_ENTRIES ); taskENTER_CRITICAL(); { /* Only block if the notification count is not already non-zero. */ - if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] == 0UL ) + if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0UL ) { /* Mark this task as waiting for a notification. */ - pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION; + pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; if( xTicksToWait > ( TickType_t ) 0 ) { prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); - traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWait ); + traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWaitOn ); /* All ports are written to allow a yield in a critical * section (some will yield immediately, others wait until the @@ -6835,18 +6835,18 @@ TickType_t uxTaskResetEventItemValue( void ) taskENTER_CRITICAL(); { - traceTASK_NOTIFY_TAKE( uxIndexToWait ); - ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ]; + traceTASK_NOTIFY_TAKE( uxIndexToWaitOn ); + ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ]; if( ulReturn != 0UL ) { if( xClearCountOnExit != pdFALSE ) { - pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] = 0UL; + pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] = 0UL; } else { - pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] = ulReturn - ( uint32_t ) 1; + pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] = ulReturn - ( uint32_t ) 1; } } else @@ -6854,7 +6854,7 @@ TickType_t uxTaskResetEventItemValue( void ) mtCOVERAGE_TEST_MARKER(); } - pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION; + pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskNOT_WAITING_NOTIFICATION; } taskEXIT_CRITICAL(); @@ -6866,7 +6866,7 @@ TickType_t uxTaskResetEventItemValue( void ) #if ( configUSE_TASK_NOTIFICATIONS == 1 ) - BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWait, + BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t * pulNotificationValue, @@ -6874,25 +6874,25 @@ TickType_t uxTaskResetEventItemValue( void ) { BaseType_t xReturn; - configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + configASSERT( uxIndexToWaitOn < configTASK_NOTIFICATION_ARRAY_ENTRIES ); taskENTER_CRITICAL(); { /* Only block if a notification is not already pending. */ - if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED ) + if( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) { /* Clear bits in the task's notification value as bits may get * set by the notifying task or interrupt. This can be used to * clear the value to zero. */ - pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnEntry; + pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnEntry; /* Mark this task as waiting for a notification. */ - pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION; + pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; if( xTicksToWait > ( TickType_t ) 0 ) { prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); - traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWait ); + traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWaitOn ); /* All ports are written to allow a yield in a critical * section (some will yield immediately, others wait until the @@ -6922,20 +6922,20 @@ TickType_t uxTaskResetEventItemValue( void ) taskENTER_CRITICAL(); { - traceTASK_NOTIFY_WAIT( uxIndexToWait ); + traceTASK_NOTIFY_WAIT( uxIndexToWaitOn ); if( pulNotificationValue != NULL ) { /* Output the current notification value, which may or may not * have changed. */ - *pulNotificationValue = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ]; + *pulNotificationValue = pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ]; } /* If ucNotifyValue is set then either the task never entered the * blocked state (because a notification was already pending) or the * task unblocked because of a notification. Otherwise the task * unblocked because of a timeout. */ - if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED ) + if( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) { /* A notification was not received. */ xReturn = pdFALSE; @@ -6944,11 +6944,11 @@ TickType_t uxTaskResetEventItemValue( void ) { /* A notification was already pending or a notification was * received while the task was waiting. */ - pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnExit; + pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnExit; xReturn = pdTRUE; } - pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION; + pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskNOT_WAITING_NOTIFICATION; } taskEXIT_CRITICAL(); From ea595d97b2c9784ed2e88fd4eab6667b76bdf443 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Wed, 26 Apr 2023 09:52:13 +0800 Subject: [PATCH 090/109] Update for std C90 --- tasks.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tasks.c b/tasks.c index 30ed4add71e..8f0beb13266 100644 --- a/tasks.c +++ b/tasks.c @@ -394,10 +394,7 @@ typedef tskTCB TCB_t; /* MISRA Ref 8.4.1 [Declaration shall be visible] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ /* coverity[misra_c_2012_rule_8_4_violation] */ - portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = - { - [ 0 ... ( configNUMBER_OF_CORES - 1 ) ] = NULL, - }; + portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { NULL }; #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif From a1eab5a383336e017823c94e891b0f0240c2a09a Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Wed, 26 Apr 2023 10:02:10 +0800 Subject: [PATCH 091/109] Fix uncrustify --- tasks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks.c b/tasks.c index 8f0beb13266..fecccc2f1f4 100644 --- a/tasks.c +++ b/tasks.c @@ -391,10 +391,10 @@ typedef tskTCB TCB_t; #if ( configNUMBER_OF_CORES == 1 ) portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; #else - /* MISRA Ref 8.4.1 [Declaration shall be visible] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ - /* coverity[misra_c_2012_rule_8_4_violation] */ - portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { NULL }; +/* MISRA Ref 8.4.1 [Declaration shall be visible] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ +/* coverity[misra_c_2012_rule_8_4_violation] */ +portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { NULL }; #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif From e590e34af108525c11584a57d24af2471967266a Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 27 Apr 2023 18:39:46 +0800 Subject: [PATCH 092/109] Remove unnecessary MISRA suppression --- include/task.h | 36 ++++++++++++++++++++++++++++++++++++ tasks.c | 29 +---------------------------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/include/task.h b/include/task.h index 8b4cf4b4a43..0c87e52d9fb 100644 --- a/include/task.h +++ b/include/task.h @@ -3419,6 +3419,42 @@ void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNC */ void vTaskYieldWithinAPI( void ); +/* + * This function is only intended for use when implementing a port of the scheduler + * and is only available when portCRITICAL_NESTING_IN_TCB is set to 1 or configNUMBER_OF_CORES + * is greater than 1. This function can be used in the implementation of portENTER_CRITICAL + * if port requires maintaing critical nesting count in TCB in single core FreeRTOS. + * It should be used in the implementation of portENTER_CRITICAL if port is running a + * multiple core FreeRTOS. + */ +void vTaskEnterCritical( void ); + +/* + * This function is only intended for use when implementing a port of the scheduler + * and is only available when portCRITICAL_NESTING_IN_TCB is set to 1 or configNUMBER_OF_CORES + * is greater than 1. This function can be used in the implementation of portEXIT_CRITICAL + * if port requires maintaing critical nesting count in TCB in single core FreeRTOS. + * It should be used in the implementation of portEXIT_CRITICAL if port is running a + * multiple core FreeRTOS. + */ +void vTaskExitCritical( void ); + +/* + * This function is only intended for use when implementing a port of the scheduler + * and is only available when configNUMBER_OF_CORES is greater than 1. This function + * should be used in the implementation of portENTER_CRITICAL_FROM_ISR if port is + * running a multiple core FreeRTOS. + */ +portBASE_TYPE vTaskEnterCriticalFromISR( void ); + +/* + * This function is only intended for use when implementing a port of the scheduler + * and is only available when configNUMBER_OF_CORES is greater than 1. This function + * should be used in the implementation of portEXIT_CRITICAL_FROM_ISR if port is + * running a multiple core FreeRTOS. + */ +void vTaskExitCriticalFromISR( portBASE_TYPE xSavedInterruptStatus ); + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/tasks.c b/tasks.c index fecccc2f1f4..414cb2ed289 100644 --- a/tasks.c +++ b/tasks.c @@ -391,9 +391,6 @@ typedef tskTCB TCB_t; #if ( configNUMBER_OF_CORES == 1 ) portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; #else -/* MISRA Ref 8.4.1 [Declaration shall be visible] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ -/* coverity[misra_c_2012_rule_8_4_violation] */ portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { NULL }; #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif @@ -951,9 +948,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxCurrentPriority ] ) ) == pdFALSE ) { List_t * const pxReadyList = &( pxReadyTasksLists[ uxCurrentPriority ] ); - /* MISRA Ref 11.3.2 [Cast to different type] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ - /* coverity[misra_c_2012_rule_11_3_violation] */ const ListItem_t * pxEndMarker = listGET_END_MARKER( pxReadyList ); ListItem_t * pxIterator; @@ -963,10 +957,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; for( pxIterator = listGET_HEAD_ENTRY( pxReadyList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) ) { - /* MISRA Ref 11.5.1 [Cast to different type] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ - TCB_t * pxTCB = listGET_LIST_ITEM_OWNER( pxIterator ); + TCB_t * pxTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxIterator ); #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) { @@ -1311,12 +1302,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( pxTaskDefinition->puxStackBuffer != NULL ) { - /* Allocate space for the TCB. Where the memory comes from depends - * on the implementation of the port malloc function and whether or - * not static allocation is being used. */ - /* MISRA Ref 11.5.1 [Cast to different type] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ) @@ -3140,9 +3125,6 @@ static BaseType_t prvCreateIdleTasks( void ) for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configMAX_TASK_NAME_LEN; x++ ) { - /* MISRA Ref 18.1.1 [Overrun] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-181 */ - /* coverity[misra_c_2012_rule_18_1_violation] */ cIdleName[ x ] = configIDLE_TASK_NAME[ x ]; /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than @@ -5851,12 +5833,6 @@ static void prvResetNextTaskUnblockTime( void ) return xReturn; } #else /* #if ( configNUMBER_OF_CORES == 1 ) */ - /* MISRA Ref 8.5.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-85 */ - /* MISRA Ref 8.6.1 [External function shall be declared once.] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */ - /* coverity[misra_c_2012_rule_8_5_violation] */ - /* coverity[misra_c_2012_rule_8_6_violation] */ TaskHandle_t xTaskGetCurrentTaskHandle( void ) { TaskHandle_t xReturn; @@ -6282,9 +6258,6 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) -/* MISRA Ref 8.4.1 [Declaration shall be visible] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ -/* coverity[misra_c_2012_rule_8_4_violation] */ void vTaskEnterCritical( void ) { portDISABLE_INTERRUPTS(); From 84b19fe0fec45b78f0551d68610f9842e1df19f8 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 27 Apr 2023 18:43:37 +0800 Subject: [PATCH 093/109] Remove unreferenced MISRA suppression in MISRA.md --- MISRA.md | 46 +++++----------------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/MISRA.md b/MISRA.md index 12b41e160a6..107cd4f14cb 100644 --- a/MISRA.md +++ b/MISRA.md @@ -15,29 +15,12 @@ grep 'MISRA Ref 8.4.1' . -rI _Ref 8.4.1_ - MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an object or function with external linkage is defined. - vTaskEnterCriticalFromISR()/vTaskExitCriticalFromISR are used at some ports. - -#### Rule 8.5 - -_Ref 8.5.1_ - -- MISRA C:2012 Rule 8.5: An external object or function shall be declared once in one and only one file. - Function is declared in header file correctly. But the function name in task.h/tasks.c is different if portUSING_MPU_WRAPPERS enabled. - -#### Rule 8.6 - -_Ref 8.6.1_ + This rule requires that a compatiable declaration is made available in a header + file when an object with external linkage is defined. pxCurrentTCB(s) is defined + with external linkage but it is only used in port assembly files. Therefore, adding + a declaration in header file is not useful as the assembly code will still need to + declare it separately. -- MISRA C:2012 Rule 8.6: An identifier with external linkage shall have exactly one external definition. - Function is declared in header file correctly. But the function name in task.h/tasks.c is different if portUSING_MPU_WRAPPERS enabled. - -#### Rule 8.9 - -_Ref 8.9.1_ - -- MISRA C:2012 Rule 8.9: An object should be defined at block scope if its identifier only appears in a single function. - False alarm. This variable is actually used by several different functions. - #### Rule 11.3 _Ref 11.3.1_ @@ -45,25 +28,6 @@ _Ref 11.3.1_ - MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to object type and a pointer to a different object type. Unusual cast is ok as the structures are designed to have the same alignment, this is checked by an assert. -_Ref 11.3.2_ - -- MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to object type and a pointer to a different object type. - The mini list structure is used as the list end to save RAM. This is checked and valid. - -#### Rule 11.5 - -_Ref 11.5.1_ - -- MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to void into pointer to object. - void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. - -#### Rule 18.1 - -_Ref 18.1.1_ - -- MISRA C:2012 Rule 18.1: A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand. - Loop breaks before index overrun. - ### MISRA configuration Copy below content as misra.conf to run coverity on FreeRTOS-Kernel. From 17e55262b957cd1e75bb6cd5cc452587dda7380b Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 27 Apr 2023 18:47:10 +0800 Subject: [PATCH 094/109] Remove 11.3 supression --- tasks.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tasks.c b/tasks.c index 414cb2ed289..2565e0c8e6b 100644 --- a/tasks.c +++ b/tasks.c @@ -1177,9 +1177,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; { /* The memory used for the task's TCB and stack are passed into this * function - use them. */ - /* MISRA Ref 11.3.1 [Cast to different type] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ - /* coverity[misra_c_2012_rule_11_3_violation] */ pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ ( void ) memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; @@ -1239,9 +1236,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* Allocate space for the TCB. Where the memory comes from depends * on the implementation of the port malloc function and whether or * not static allocation is being used. */ - /* MISRA Ref 11.3.1 [Cast to different type] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ - /* coverity[misra_c_2012_rule_11_3_violation] */ pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer; ( void ) memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); From 58da3ffca42a203f63f6a517afc5856fa6376e9b Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 27 Apr 2023 19:21:48 +0800 Subject: [PATCH 095/109] Remove 11.3 in MISRA.md --- MISRA.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/MISRA.md b/MISRA.md index 107cd4f14cb..e82dc74fa06 100644 --- a/MISRA.md +++ b/MISRA.md @@ -21,13 +21,6 @@ _Ref 8.4.1_ a declaration in header file is not useful as the assembly code will still need to declare it separately. -#### Rule 11.3 - -_Ref 11.3.1_ - -- MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to object type and a pointer to a different object type. - Unusual cast is ok as the structures are designed to have the same alignment, this is checked by an assert. - ### MISRA configuration Copy below content as misra.conf to run coverity on FreeRTOS-Kernel. From b3514bdffa3fe3fd4433e20e8c98c1cf9a3ed719 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 27 Apr 2023 20:32:06 +0800 Subject: [PATCH 096/109] Add back the suppression for pxCurrentTCBs --- tasks.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks.c b/tasks.c index 2565e0c8e6b..6fb51c5d5d0 100644 --- a/tasks.c +++ b/tasks.c @@ -391,6 +391,9 @@ typedef tskTCB TCB_t; #if ( configNUMBER_OF_CORES == 1 ) portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; #else +/* MISRA Ref 8.4.1 [Declaration shall be visible] */ +/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ +/* coverity[misra_c_2012_rule_8_4_violation] */ portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { NULL }; #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif @@ -6367,9 +6370,6 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) -/* MISRA Ref 8.4.1 [Declaration shall be visible] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ -/* coverity[misra_c_2012_rule_8_4_violation] */ void vTaskExitCritical( void ) { if( xSchedulerRunning != pdFALSE ) From 28fa91969717f3770b092c34e7ba215d2e963492 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 27 Apr 2023 21:34:36 +0800 Subject: [PATCH 097/109] Fix typo --- include/task.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/task.h b/include/task.h index 0c87e52d9fb..63f8f101fd1 100644 --- a/include/task.h +++ b/include/task.h @@ -3423,7 +3423,7 @@ void vTaskYieldWithinAPI( void ); * This function is only intended for use when implementing a port of the scheduler * and is only available when portCRITICAL_NESTING_IN_TCB is set to 1 or configNUMBER_OF_CORES * is greater than 1. This function can be used in the implementation of portENTER_CRITICAL - * if port requires maintaing critical nesting count in TCB in single core FreeRTOS. + * if port wants to maintain critical nesting count in TCB in single core FreeRTOS. * It should be used in the implementation of portENTER_CRITICAL if port is running a * multiple core FreeRTOS. */ @@ -3433,7 +3433,7 @@ void vTaskEnterCritical( void ); * This function is only intended for use when implementing a port of the scheduler * and is only available when portCRITICAL_NESTING_IN_TCB is set to 1 or configNUMBER_OF_CORES * is greater than 1. This function can be used in the implementation of portEXIT_CRITICAL - * if port requires maintaing critical nesting count in TCB in single core FreeRTOS. + * if port wants to maintain critical nesting count in TCB in single core FreeRTOS. * It should be used in the implementation of portEXIT_CRITICAL if port is running a * multiple core FreeRTOS. */ From b8b6d956651e91ef1c0e6bdd85d793038057da83 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 4 May 2023 17:25:37 +0800 Subject: [PATCH 098/109] Fix more coverity errors --- tasks.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/tasks.c b/tasks.c index 6fb51c5d5d0..efea2335b7a 100644 --- a/tasks.c +++ b/tasks.c @@ -463,14 +463,18 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t /* Do not move these variables to function scope as doing so prevents the * code working with debuggers that need to remove the static qualifier. */ -PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the value of a timer/counter the last time a task was switched in. */ -PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ configNUMBER_OF_CORES ] = { 0UL }; /**< Holds the total amount of execution time as defined by the run time counter clock. */ +PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime[ configNUMBER_OF_CORES ] = { 0U }; /**< Holds the value of a timer/counter the last time a task was switched in. */ +PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ configNUMBER_OF_CORES ] = { 0U }; /**< Holds the total amount of execution time as defined by the run time counter clock. */ #endif #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 ) + +/* Do not move these variables to function scope as doing so prevents the + * code working with debuggers that need to remove the static qualifier. */ static StaticTask_t xIdleTCBBuffers[ configNUMBER_OF_CORES - 1 ]; static StackType_t xIdleTaskStackBuffers[ configNUMBER_OF_CORES - 1 ][ configMINIMAL_STACK_SIZE ]; + #endif /* #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 ) */ /*lint -restore */ @@ -693,7 +697,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; static void prvCheckForRunStateChange( void ) { UBaseType_t uxPrevCriticalNesting; - TCB_t * pxThisTCB; + const TCB_t * pxThisTCB; /* This should be skipped if called from an ISR. If the task on the current * core is no longer running, then vTaskSwitchContext() probably should @@ -929,7 +933,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxCurrentTCBs[ xCoreID ]->uxPriority ] ), &pxCurrentTCBs[ xCoreID ]->xStateListItem ) == pdTRUE ) { - uxListRemove( &pxCurrentTCBs[ xCoreID ]->xStateListItem ); + ( void ) uxListRemove( &pxCurrentTCBs[ xCoreID ]->xStateListItem ); vListInsertEnd( &( pxReadyTasksLists[ pxCurrentTCBs[ xCoreID ]->uxPriority ] ), &pxCurrentTCBs[ xCoreID ]->xStateListItem ); } @@ -950,9 +954,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxCurrentPriority ] ) ) == pdFALSE ) { - List_t * const pxReadyList = &( pxReadyTasksLists[ uxCurrentPriority ] ); + const List_t * const pxReadyList = &( pxReadyTasksLists[ uxCurrentPriority ] ); const ListItem_t * pxEndMarker = listGET_END_MARKER( pxReadyList ); - ListItem_t * pxIterator; + const ListItem_t * pxIterator; /* The ready task list for uxCurrentPriority is not empty, so uxTopReadyPriority * must not be decremented any further. */ @@ -1096,7 +1100,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; UBaseType_t uxCore = ( UBaseType_t ) x; BaseType_t xTaskPriority; - if( ( uxCoreMap & ( 1 << uxCore ) ) != 0 ) + if( ( uxCoreMap & ( ( 1U << ( UBaseType_t ) uxCore ) ) != 0U ) { xTaskPriority = ( BaseType_t ) pxCurrentTCBs[ uxCore ]->uxPriority; @@ -1380,7 +1384,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( pxNewTCB != NULL ) { - memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + ( void ) memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Allocate space for the stack used by the task being created. * The base of the stack memory stored in the TCB so the task can @@ -1409,7 +1413,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; if( pxNewTCB != NULL ) { - memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + ( void ) memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Store the stack location in the TCB. */ pxNewTCB->pxStack = pxStack; @@ -2589,7 +2593,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { /* Calculate the cores on which this task was not allowed to * run previously. */ - uxPrevNotAllowedCores = ( ~uxPrevCoreAffinityMask ) & ( ( 1 << configNUMBER_OF_CORES ) - 1 ); + uxPrevNotAllowedCores = ( ~uxPrevCoreAffinityMask ) & ( ( 1U << configNUMBER_OF_CORES ) - 1U ); /* Does the new core mask enables this task to run on any of the * previously not allowed cores? If yes, check if this task can be @@ -3758,7 +3762,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char char cNextChar; BaseType_t xBreakLoop; const ListItem_t * pxEndMarker = listGET_END_MARKER( pxList ); - ListItem_t * pxIterator; + const ListItem_t * pxIterator; /* This function is called with the scheduler suspended. */ @@ -6735,14 +6739,18 @@ TickType_t uxTaskResetEventItemValue( void ) TaskHandle_t pvTaskIncrementMutexHeldCount( void ) { + TCB_t * pxTCB; + + pxTCB = pxCurrentTCB; + /* If xSemaphoreCreateMutex() is called before any tasks have been created * then pxCurrentTCB will be NULL. */ - if( pxCurrentTCB != NULL ) + if( pxTCB != NULL ) { - ( pxCurrentTCB->uxMutexesHeld )++; + ( pxTCB->uxMutexesHeld )++; } - return pxCurrentTCB; + return pxTCB; } #endif /* configUSE_MUTEXES */ From cf0d10f92b1c0707a919bbdda9851e1115abb08d Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 4 May 2023 17:34:24 +0800 Subject: [PATCH 099/109] Fix error --- tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks.c b/tasks.c index efea2335b7a..d0fa2018faf 100644 --- a/tasks.c +++ b/tasks.c @@ -1100,7 +1100,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; UBaseType_t uxCore = ( UBaseType_t ) x; BaseType_t xTaskPriority; - if( ( uxCoreMap & ( ( 1U << ( UBaseType_t ) uxCore ) ) != 0U ) + if( ( uxCoreMap & ( 1U << ( UBaseType_t ) uxCore ) ) != 0U ) { xTaskPriority = ( BaseType_t ) pxCurrentTCBs[ uxCore ]->uxPriority; From 16f7d7300666e0519a4440d9f3ec98ff89ae61ff Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 4 May 2023 19:13:40 +0800 Subject: [PATCH 100/109] Return pdTRUE or pdFALSE with macros --- include/task.h | 2 +- tasks.c | 45 +++++++++++++++++++++++---------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/include/task.h b/include/task.h index 63f8f101fd1..52d5d40602b 100644 --- a/include/task.h +++ b/include/task.h @@ -272,7 +272,7 @@ typedef enum #define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) /* Checks if core ID is valid. */ -#define taskVALID_CORE_ID( xCoreID ) ( ( ( ( BaseType_t ) 0 <= ( xCoreID ) ) && ( ( xCoreID ) < ( BaseType_t ) configNUMBER_OF_CORES ) ) ) +#define taskVALID_CORE_ID( xCoreID ) ( ( ( ( ( BaseType_t ) 0 <= ( xCoreID ) ) && ( ( xCoreID ) < ( BaseType_t ) configNUMBER_OF_CORES ) ) ) ? ( pdTRUE ) : ( pdFALSE ) ) /*----------------------------------------------------------- * TASK CREATION API diff --git a/tasks.c b/tasks.c index d0fa2018faf..7071ae43ebf 100644 --- a/tasks.c +++ b/tasks.c @@ -274,11 +274,11 @@ typedef BaseType_t TaskRunning_t; * but scheduled to yield. */ #if ( configNUMBER_OF_CORES == 1 ) - #define taskTASK_IS_RUNNING( pxTCB ) ( ( pxTCB ) == pxCurrentTCB ) + #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( pxTCB ) == pxCurrentTCB ) ? ( pdTRUE ) : ( pdFALSE ) ) #define taskTASK_IS_YIELDING( pxTCB ) ( pdFALSE ) #else - #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( pxTCB )->xTaskRunState >= ( BaseType_t ) 0 ) && ( ( pxTCB )->xTaskRunState < ( BaseType_t ) configNUMBER_OF_CORES ) ) - #define taskTASK_IS_YIELDING( pxTCB ) ( ( pxTCB )->xTaskRunState == taskTASK_YIELDING ) + #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( ( pxTCB )->xTaskRunState >= ( BaseType_t ) 0 ) && ( ( pxTCB )->xTaskRunState < ( BaseType_t ) configNUMBER_OF_CORES ) ) ? ( pdTRUE ) : ( pdFALSE ) ) + #define taskTASK_IS_YIELDING( pxTCB ) ( ( ( pxTCB )->xTaskRunState == taskTASK_YIELDING ) ? ( pdTRUE ) : ( pdFALSE ) ) #endif /* Indicates that the task is an Idle task. */ @@ -391,10 +391,10 @@ typedef tskTCB TCB_t; #if ( configNUMBER_OF_CORES == 1 ) portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; #else -/* MISRA Ref 8.4.1 [Declaration shall be visible] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ -/* coverity[misra_c_2012_rule_8_4_violation] */ -portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ] = { NULL }; + /* MISRA Ref 8.4.1 [Declaration shall be visible] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ + /* coverity[misra_c_2012_rule_8_4_violation] */ + portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ]; #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif @@ -511,7 +511,7 @@ static BaseType_t prvCreateIdleTasks( void ); * Yields a core, or cores if multiple priorities are not allowed to run * simultaneously, to allow the task pxTCB to run. */ - static void prvYieldForTask( TCB_t * pxTCB ); + static void prvYieldForTask( const TCB_t * pxTCB ); #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ #if ( configNUMBER_OF_CORES > 1 ) @@ -790,7 +790,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ #if ( configNUMBER_OF_CORES > 1 ) - static void prvYieldForTask( TCB_t * pxTCB ) + static void prvYieldForTask( const TCB_t * pxTCB ) { BaseType_t xLowestPriorityToPreempt; BaseType_t xCurrentCoreTaskPriority; @@ -1100,7 +1100,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; UBaseType_t uxCore = ( UBaseType_t ) x; BaseType_t xTaskPriority; - if( ( uxCoreMap & ( 1U << ( UBaseType_t ) uxCore ) ) != 0U ) + if( ( uxCoreMap & ( ( UBaseType_t ) 1U << uxCore ) ) != 0U ) { xTaskPriority = ( BaseType_t ) pxCurrentTCBs[ uxCore ]->uxPriority; @@ -4187,8 +4187,7 @@ BaseType_t xTaskIncrementTick( void ) BaseType_t xSwitchRequired = pdFALSE; #if ( configUSE_PREEMPTION == 1 ) && ( configNUMBER_OF_CORES > 1 ) - UBaseType_t x; - BaseType_t xYieldRequiredForCore[ configNUMBER_OF_CORES ] = { pdFALSE }; + BaseType_t xYieldRequiredForCore[ configNUMBER_OF_CORES ] = { pdFALSE }; #endif /* #if ( configUSE_PREEMPTION == 1 ) && ( configNUMBER_OF_CORES > 1 ) */ /* Called by the portable layer each time a tick interrupt occurs. @@ -4331,11 +4330,13 @@ BaseType_t xTaskIncrementTick( void ) } #else /* #if ( configNUMBER_OF_CORES == 1 ) */ { - for( x = ( ( UBaseType_t ) 0 ); x < ( ( UBaseType_t ) configNUMBER_OF_CORES ); x++ ) + BaseType_t xCoreID; + + for( xCoreID = 0; xCoreID < ( ( BaseType_t ) configNUMBER_OF_CORES ); xCoreID++ ) { - if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCBs[ x ]->uxPriority ] ) ) > ( UBaseType_t ) 1 ) + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCBs[ xCoreID ]->uxPriority ] ) ) > 1 ) { - xYieldRequiredForCore[ x ] = pdTRUE; + xYieldRequiredForCore[ xCoreID ] = pdTRUE; } else { @@ -4378,24 +4379,24 @@ BaseType_t xTaskIncrementTick( void ) } #else /* #if ( configNUMBER_OF_CORES == 1 ) */ { - BaseType_t xCoreID; - xCoreID = portGET_CORE_ID(); + BaseType_t xCoreID, xCurrentCoreID; + xCurrentCoreID = portGET_CORE_ID(); - for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configNUMBER_OF_CORES; x++ ) + for( xCoreID = 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) { #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - if( pxCurrentTCBs[ x ]->xPreemptionDisable == pdFALSE ) + if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == pdFALSE ) #endif { - if( ( xYieldRequiredForCore[ x ] != pdFALSE ) || ( xYieldPendings[ x ] != pdFALSE ) ) + if( ( xYieldRequiredForCore[ xCoreID ] != pdFALSE ) || ( xYieldPendings[ xCoreID ] != pdFALSE ) ) { - if( x == ( UBaseType_t ) xCoreID ) + if( xCoreID == xCurrentCoreID ) { xSwitchRequired = pdTRUE; } else { - prvYieldCore( x ); + prvYieldCore( xCoreID ); } } else From d4d167aa686ff4799c7af3181b6d691ba805ba62 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 4 May 2023 20:12:43 +0800 Subject: [PATCH 101/109] Fix possible overrun in prvSelectHighestPriority task --- tasks.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tasks.c b/tasks.c index 7071ae43ebf..b0054ed9291 100644 --- a/tasks.c +++ b/tasks.c @@ -1040,10 +1040,20 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * The scheduler should be able to select a task to run when uxCurrentPriority * is tskIDLE_PRIORITY. uxCurrentPriority is never decreased to value blow * tskIDLE_PRIORITY. */ - uxCurrentPriority--; + if( uxCurrentPriority > tskIDLE_PRIORITY ) + { + uxCurrentPriority--; + } + else + { + /* This function is called when idle task is not created. Break the + * loop to prevent uxCurrentPriority overrun. */ + break; + } } #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) + if( xTaskScheduled == pdTRUE ) { if( xPriorityDropped != pdFALSE ) { @@ -1064,6 +1074,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */ #if ( configUSE_CORE_AFFINITY == 1 ) + if( xTaskScheduled == pdTRUE ) { if( ( pxPreviousTCB != NULL ) && ( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxPreviousTCB->uxPriority ] ), &( pxPreviousTCB->xStateListItem ) ) != pdFALSE ) ) { From c515f6b850fcfdfa26a1d6af2cc257eea3c75bf4 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Thu, 4 May 2023 20:36:51 +0800 Subject: [PATCH 102/109] Remove const due to list operation --- tasks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks.c b/tasks.c index b0054ed9291..e14bb46627c 100644 --- a/tasks.c +++ b/tasks.c @@ -956,7 +956,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; { const List_t * const pxReadyList = &( pxReadyTasksLists[ uxCurrentPriority ] ); const ListItem_t * pxEndMarker = listGET_END_MARKER( pxReadyList ); - const ListItem_t * pxIterator; + ListItem_t * pxIterator; /* The ready task list for uxCurrentPriority is not empty, so uxTopReadyPriority * must not be decremented any further. */ @@ -3773,7 +3773,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char char cNextChar; BaseType_t xBreakLoop; const ListItem_t * pxEndMarker = listGET_END_MARKER( pxList ); - const ListItem_t * pxIterator; + ListItem_t * pxIterator; /* This function is called with the scheduler suspended. */ From f02ef0359ef0d6f0573651c5a771ab169ecf93e7 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 8 May 2023 11:07:15 +0800 Subject: [PATCH 103/109] Uncrustify tasks --- tasks.c | 122 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 59 deletions(-) diff --git a/tasks.c b/tasks.c index e14bb46627c..374773e5395 100644 --- a/tasks.c +++ b/tasks.c @@ -1053,20 +1053,22 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; } #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) - if( xTaskScheduled == pdTRUE ) { - if( xPriorityDropped != pdFALSE ) + if( xTaskScheduled == pdTRUE ) { - /* There may be several ready tasks that were being prevented from running because there was - * a higher priority task running. Now that the last of the higher priority tasks is no longer - * running, make sure all the other idle tasks yield. */ - BaseType_t x; - - for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configNUMBER_OF_CORES; x++ ) + if( xPriorityDropped != pdFALSE ) { - if( ( pxCurrentTCBs[ x ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0 ) + /* There may be several ready tasks that were being prevented from running because there was + * a higher priority task running. Now that the last of the higher priority tasks is no longer + * running, make sure all the other idle tasks yield. */ + BaseType_t x; + + for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configNUMBER_OF_CORES; x++ ) { - prvYieldCore( x ); + if( ( pxCurrentTCBs[ x ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0 ) + { + prvYieldCore( x ); + } } } } @@ -1074,72 +1076,74 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */ #if ( configUSE_CORE_AFFINITY == 1 ) - if( xTaskScheduled == pdTRUE ) { - if( ( pxPreviousTCB != NULL ) && ( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxPreviousTCB->uxPriority ] ), &( pxPreviousTCB->xStateListItem ) ) != pdFALSE ) ) + if( xTaskScheduled == pdTRUE ) { - /* A ready task was just evicted from this core. See if it can be - * scheduled on any other core. */ - UBaseType_t uxCoreMap = pxPreviousTCB->uxCoreAffinityMask; - BaseType_t xLowestPriority = ( BaseType_t ) pxPreviousTCB->uxPriority; - BaseType_t xLowestPriorityCore = -1; - BaseType_t x; - - if( ( pxPreviousTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) + if( ( pxPreviousTCB != NULL ) && ( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxPreviousTCB->uxPriority ] ), &( pxPreviousTCB->xStateListItem ) ) != pdFALSE ) ) { - xLowestPriority = xLowestPriority - 1; - } + /* A ready task was just evicted from this core. See if it can be + * scheduled on any other core. */ + UBaseType_t uxCoreMap = pxPreviousTCB->uxCoreAffinityMask; + BaseType_t xLowestPriority = ( BaseType_t ) pxPreviousTCB->uxPriority; + BaseType_t xLowestPriorityCore = -1; + BaseType_t x; - if( ( uxCoreMap & ( ( UBaseType_t ) 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) - { - /* The ready task that was removed from this core is not excluded from it. - * Only look at the intersection of the cores the removed task is allowed to run - * on with the cores that the new task is excluded from. It is possible that the - * new task was only placed onto this core because it is excluded from another. - * Check to see if the previous task could run on one of those cores. */ - uxCoreMap &= ~( pxCurrentTCBs[ xCoreID ]->uxCoreAffinityMask ); - } - else - { - /* The ready task that was removed from this core is excluded from it. */ - } + if( ( pxPreviousTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) + { + xLowestPriority = xLowestPriority - 1; + } - uxCoreMap &= ( ( 1U << configNUMBER_OF_CORES ) - 1U ); + if( ( uxCoreMap & ( ( UBaseType_t ) 1U << ( UBaseType_t ) xCoreID ) ) != 0U ) + { + /* The ready task that was removed from this core is not excluded from it. + * Only look at the intersection of the cores the removed task is allowed to run + * on with the cores that the new task is excluded from. It is possible that the + * new task was only placed onto this core because it is excluded from another. + * Check to see if the previous task could run on one of those cores. */ + uxCoreMap &= ~( pxCurrentTCBs[ xCoreID ]->uxCoreAffinityMask ); + } + else + { + /* The ready task that was removed from this core is excluded from it. */ + } - for( x = ( ( BaseType_t ) configNUMBER_OF_CORES - 1 ); x >= ( BaseType_t ) 0; x-- ) - { - UBaseType_t uxCore = ( UBaseType_t ) x; - BaseType_t xTaskPriority; + uxCoreMap &= ( ( 1U << configNUMBER_OF_CORES ) - 1U ); - if( ( uxCoreMap & ( ( UBaseType_t ) 1U << uxCore ) ) != 0U ) + for( x = ( ( BaseType_t ) configNUMBER_OF_CORES - 1 ); x >= ( BaseType_t ) 0; x-- ) { - xTaskPriority = ( BaseType_t ) pxCurrentTCBs[ uxCore ]->uxPriority; + UBaseType_t uxCore = ( UBaseType_t ) x; + BaseType_t xTaskPriority; - if( ( pxCurrentTCBs[ uxCore ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) + if( ( uxCoreMap & ( ( UBaseType_t ) 1U << uxCore ) ) != 0U ) { - xTaskPriority = xTaskPriority - ( BaseType_t ) 1; - } + xTaskPriority = ( BaseType_t ) pxCurrentTCBs[ uxCore ]->uxPriority; - uxCoreMap &= ~( ( UBaseType_t ) 1U << uxCore ); + if( ( pxCurrentTCBs[ uxCore ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) + { + xTaskPriority = xTaskPriority - ( BaseType_t ) 1; + } - if( ( xTaskPriority < xLowestPriority ) && - ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) && - ( xYieldPendings[ uxCore ] == pdFALSE ) ) - { - #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) - #endif + uxCoreMap &= ~( ( UBaseType_t ) 1U << uxCore ); + + if( ( xTaskPriority < xLowestPriority ) && + ( taskTASK_IS_RUNNING( pxCurrentTCBs[ uxCore ] ) != pdFALSE ) && + ( xYieldPendings[ uxCore ] == pdFALSE ) ) { - xLowestPriority = xTaskPriority; - xLowestPriorityCore = ( BaseType_t ) uxCore; + #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) + if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) + #endif + { + xLowestPriority = xTaskPriority; + xLowestPriorityCore = ( BaseType_t ) uxCore; + } } } } - } - if( xLowestPriorityCore >= 0 ) - { - prvYieldCore( xLowestPriorityCore ); + if( xLowestPriorityCore >= 0 ) + { + prvYieldCore( xLowestPriorityCore ); + } } } } From 5c4114720c2ab568c0c45f554de79e98ad92ed4f Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Mon, 15 May 2023 05:29:27 +0000 Subject: [PATCH 104/109] Code review suggestions Signed-off-by: Gaurav Aggarwal --- MISRA.md | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/MISRA.md b/MISRA.md index e82dc74fa06..51bdfa41b48 100644 --- a/MISRA.md +++ b/MISRA.md @@ -1,29 +1,39 @@ -# MISRA Compliance (for configNUMBER_OF_CORES > 1) +# MISRA Compliance -For now, FreeRTOS-Kernel only conforms [MISRA C:2012](https://www.misra.org.uk/misra-c) guidelines in SMP part (configNUMBER_OF_CORES > 1), -with the deviations listed below. Compliance is checked with Coverity static analysis. Refer to [configuration](#misra-configuration) to build an application for the tool to analyze. +FreeRTOS-Kernel conforms to [MISRA C:2012](https://www.misra.org.uk/misra-c) +guidelines, with the deviations listed below. Compliance is checked with +Coverity static analysis. Since the FreeRTOS kernel is designed for +small-embedded devices, it needs to have a very small memory footprint and +has to be efficient. To achieve that and to increase the performance, it +deviates from some MISRA rules. The specific deviations, suppressed inline, +are listed below. + +Additionally, [MISRA configuration](#misra-configuration) contains project +wide deviations. ### Suppressed with Coverity Comments To find the violation references in the source files run grep on the source code -with ( Assuming rule 4.6 violation; with justification in point 1 ): +with ( Assuming rule 8.4 violation; with justification in point 1 ): ``` grep 'MISRA Ref 8.4.1' . -rI ``` - + #### Rule 8.4 _Ref 8.4.1_ -- MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an object or function with external linkage is defined. - This rule requires that a compatiable declaration is made available in a header - file when an object with external linkage is defined. pxCurrentTCB(s) is defined - with external linkage but it is only used in port assembly files. Therefore, adding - a declaration in header file is not useful as the assembly code will still need to - declare it separately. +- MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an + object or function with external linkage is defined. + This rule requires that a compatible declaration is made available + in a header file when an object with external linkage is defined. + pxCurrentTCB(s) is defined with external linkage but it is only + referenced from the assembly code in the port files. Therefore, adding + a declaration in header file is not useful as the assembly code will + still need to declare it separately. ### MISRA configuration -Copy below content as misra.conf to run coverity on FreeRTOS-Kernel. +Copy below content to `misra.conf` to run Coverity on FreeRTOS-Kernel. ``` // MISRA C-2012 Rules From dc01863623f4bc665b0dbffc70bcccbd41687f02 Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Mon, 15 May 2023 06:28:43 +0000 Subject: [PATCH 105/109] Code review suggestions - 2 Signed-off-by: Gaurav Aggarwal --- MISRA.md | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/MISRA.md b/MISRA.md index 51bdfa41b48..7f3850a5cfb 100644 --- a/MISRA.md +++ b/MISRA.md @@ -45,35 +45,19 @@ Copy below content to `misra.conf` to run Coverity on FreeRTOS-Kernel. // Disable the following rules. { deviation: "Directive 4.8", - reason: "We include lots of header files from other sources such as the kernel which defines structures that violate that Dir" + reason: "HeapRegion_t and HeapStats_t are used only in heap files but declared in portable.h which is included in multiple source files. As a result, these definitions appear in multiple source files where they are not used." }, { deviation: "Directive 4.9", - reason: "It is important the FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, macros are being used." + reason: "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used." }, { deviation: "Rule 1.2", - reason: "Allow FreeRTOS-Kernel to use attributes." - }, - { - deviation: "Rule 2.3", - reason: "The way we declare structures are conformant with the FreeRTOS libraries, which leaves somes types unused." - }, - { - deviation: "Rule 2.4", - reason: "Structures are always declared with both a struct tag and typedef alias. Some of these structs are always referred to by their typedef alias and thus the corresponding tags are unused." - }, - { - deviation: "Rule 2.5", - reason: "We use unused macros for backward compatibility in addition to macros comming from FreeRTOS" + reason: "The __attribute__ tags are used via macros which are defined in port files." }, { deviation: "Rule 3.1", - reason: "We post links which contain // inside comments blocks" - }, - { - deviation: "Rule 21.2", - reason: "Allow use of all names." + reason: "We post HTTP links in code comments which contain // inside comments blocks." } ] } From 4de5931c35e18266748d9498d06c115aa7a55a78 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 15 May 2023 16:21:02 +0800 Subject: [PATCH 106/109] Update for misra rule 2.5 * Remove taskTASK_IS_YIELDING since it is not used anymore. * Define taskYIELD_IF_USING_PREEMPTION for single core only. SMP uses prvYieldForTask or vTaskieldWithinAPI. The conditiion is not the same. * Define taskSELECT_HIGHEST_PRIORITY_TASK for single core only. SMP doesn't support configUSE_PORT_OPTIMISED_TASK_SELECTION now. --- tasks.c | 59 +++++++++++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/tasks.c b/tasks.c index 374773e5395..1634d512e12 100644 --- a/tasks.c +++ b/tasks.c @@ -58,18 +58,15 @@ #include #endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */ -#if ( configUSE_PREEMPTION == 0 ) - -/* If the cooperative scheduler is being used then a yield should not be - * performed just because a higher priority task has been woken. */ - #define taskYIELD_IF_USING_PREEMPTION() -#else - #if ( configNUMBER_OF_CORES == 1 ) - #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#if ( configNUMBER_OF_CORES == 1 ) + #if ( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + * performed just because a higher priority task has been woken. */ + #define taskYIELD_IF_USING_PREEMPTION() #else - #define taskYIELD_IF_USING_PREEMPTION() vTaskYieldWithinAPI() + #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() #endif -#endif +#endif /* if ( configNUMBER_OF_CORES == 1 ) */ /* 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. */ @@ -137,22 +134,24 @@ /*-----------------------------------------------------------*/ - #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - do { \ - UBaseType_t uxTopPriority = uxTopReadyPriority; \ - \ - /* Find the highest priority queue that contains ready tasks. */ \ - while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ - { \ - configASSERT( uxTopPriority ); \ - --uxTopPriority; \ - } \ - \ - /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ - * the same priority get an equal share of the processor time. */ \ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ - uxTopReadyPriority = uxTopPriority; \ - } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ + #if ( configNUMBER_OF_CORES == 1 ) + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + do { \ + UBaseType_t uxTopPriority = uxTopReadyPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ + { \ + configASSERT( uxTopPriority ); \ + --uxTopPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + * the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + uxTopReadyPriority = uxTopPriority; \ + } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ + #endif /* if ( configNUMBER_OF_CORES == 1 ) */ /*-----------------------------------------------------------*/ @@ -268,17 +267,11 @@ typedef BaseType_t TaskRunning_t; /* Indicates that the task is actively running but scheduled to yield. */ #define taskTASK_YIELDING ( TaskRunning_t ) ( -2 ) -/* taskTASK_IS_RUNNING - Returns pdTRUE if the task is actively running - * and not scheduled to yield. - * taskTASK_IS_YIELDING - Returns pdTRUE if the task is actively running - * but scheduled to yield. - */ +/* Returns pdTRUE if the task is actively running and not scheduled to yield. */ #if ( configNUMBER_OF_CORES == 1 ) #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( pxTCB ) == pxCurrentTCB ) ? ( pdTRUE ) : ( pdFALSE ) ) - #define taskTASK_IS_YIELDING( pxTCB ) ( pdFALSE ) #else #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( ( pxTCB )->xTaskRunState >= ( BaseType_t ) 0 ) && ( ( pxTCB )->xTaskRunState < ( BaseType_t ) configNUMBER_OF_CORES ) ) ? ( pdTRUE ) : ( pdFALSE ) ) - #define taskTASK_IS_YIELDING( pxTCB ) ( ( ( pxTCB )->xTaskRunState == taskTASK_YIELDING ) ? ( pdTRUE ) : ( pdFALSE ) ) #endif /* Indicates that the task is an Idle task. */ From 735217191956d4c170f7ae2a5fa9daa57475c540 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 15 May 2023 16:35:37 +0800 Subject: [PATCH 107/109] Fix format --- tasks.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/tasks.c b/tasks.c index 1634d512e12..74a4fce6ee6 100644 --- a/tasks.c +++ b/tasks.c @@ -60,13 +60,14 @@ #if ( configNUMBER_OF_CORES == 1 ) #if ( configUSE_PREEMPTION == 0 ) - /* If the cooperative scheduler is being used then a yield should not be - * performed just because a higher priority task has been woken. */ + +/* If the cooperative scheduler is being used then a yield should not be + * performed just because a higher priority task has been woken. */ #define taskYIELD_IF_USING_PREEMPTION() #else #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() #endif -#endif /* if ( configNUMBER_OF_CORES == 1 ) */ +#endif /* if ( configNUMBER_OF_CORES == 1 ) */ /* 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. */ @@ -135,23 +136,23 @@ /*-----------------------------------------------------------*/ #if ( configNUMBER_OF_CORES == 1 ) - #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - do { \ - UBaseType_t uxTopPriority = uxTopReadyPriority; \ - \ - /* Find the highest priority queue that contains ready tasks. */ \ - while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ - { \ - configASSERT( uxTopPriority ); \ - --uxTopPriority; \ - } \ - \ - /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ - * the same priority get an equal share of the processor time. */ \ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ - uxTopReadyPriority = uxTopPriority; \ - } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ - #endif /* if ( configNUMBER_OF_CORES == 1 ) */ + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + do { \ + UBaseType_t uxTopPriority = uxTopReadyPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ + { \ + configASSERT( uxTopPriority ); \ + --uxTopPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + * the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + uxTopReadyPriority = uxTopPriority; \ + } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ + #endif /* if ( configNUMBER_OF_CORES == 1 ) */ /*-----------------------------------------------------------*/ @@ -269,9 +270,9 @@ typedef BaseType_t TaskRunning_t; /* Returns pdTRUE if the task is actively running and not scheduled to yield. */ #if ( configNUMBER_OF_CORES == 1 ) - #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( pxTCB ) == pxCurrentTCB ) ? ( pdTRUE ) : ( pdFALSE ) ) + #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( pxTCB ) == pxCurrentTCB ) ? ( pdTRUE ) : ( pdFALSE ) ) #else - #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( ( pxTCB )->xTaskRunState >= ( BaseType_t ) 0 ) && ( ( pxTCB )->xTaskRunState < ( BaseType_t ) configNUMBER_OF_CORES ) ) ? ( pdTRUE ) : ( pdFALSE ) ) + #define taskTASK_IS_RUNNING( pxTCB ) ( ( ( ( pxTCB )->xTaskRunState >= ( BaseType_t ) 0 ) && ( ( pxTCB )->xTaskRunState < ( BaseType_t ) configNUMBER_OF_CORES ) ) ? ( pdTRUE ) : ( pdFALSE ) ) #endif /* Indicates that the task is an Idle task. */ From 12a025281576c72a2a5d901ecc90df772a4c06a5 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 15 May 2023 17:41:42 +0800 Subject: [PATCH 108/109] Add rule 8.7 and 11.5 in misra.config --- MISRA.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MISRA.md b/MISRA.md index 7f3850a5cfb..e7ebf77ea6a 100644 --- a/MISRA.md +++ b/MISRA.md @@ -58,6 +58,14 @@ Copy below content to `misra.conf` to run Coverity on FreeRTOS-Kernel. { deviation: "Rule 3.1", reason: "We post HTTP links in code comments which contain // inside comments blocks." + }, + { + deviation: "Rule 8.7", + reason: "API functions are not used by the library outside of the files they are defined; however, they must be externally visible in order to be used by an application." + }, + { + deviation: "Rule 11.5", + reason: "Allow casts from `void *`. List owner, pvOwner, is stored as `void *` and are cast to various types for use in functions." } ] } From 12d08d60736e986f385c415c56984a053c78e745 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 15 May 2023 17:49:44 +0800 Subject: [PATCH 109/109] Fix uncrustify --- tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks.c b/tasks.c index 74a4fce6ee6..5d8d3233ee3 100644 --- a/tasks.c +++ b/tasks.c @@ -151,7 +151,7 @@ * the same priority get an equal share of the processor time. */ \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ uxTopReadyPriority = uxTopPriority; \ - } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ + } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ #endif /* if ( configNUMBER_OF_CORES == 1 ) */ /*-----------------------------------------------------------*/