From fde7256c0ade116f5da31210daa61f204a14bb45 Mon Sep 17 00:00:00 2001 From: Jeff Tenney Date: Mon, 16 Oct 2023 13:54:10 -0700 Subject: [PATCH] Add configCHECK_HANDLER_INSTALLATION --- portable/ARMv8M/non_secure/port.c | 36 +++++++++++--------- portable/ARMv8M/non_secure/portmacrocommon.h | 14 ++++++++ portable/GCC/ARM_CM0/port.c | 4 +-- portable/GCC/ARM_CM0/portmacro.h | 14 ++++++++ portable/GCC/ARM_CM4F/port.c | 36 +++++++++++--------- portable/GCC/ARM_CM4F/portmacro.h | 14 ++++++++ 6 files changed, 84 insertions(+), 34 deletions(-) diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 0aea6033f9c..fe5a232db94 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -1693,11 +1693,30 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { + #if ( configCHECK_HANDLER_INSTALLATION == 1 ) + { + const portISR_t * const pxVectorTable = portSCB_VTOR_REG; + + /* Verify correct installation of the FreeRTOS handlers for SVCall and + * PendSV. Do not check the installation of the SysTick handler because + * the application may provide the OS tick without using the SysTick + * timer by overriding the weak function vPortSetupTimerInterrupt(). + * + * Assertion failures here can be caused by incorrect installation of + * the FreeRTOS handlers. For help installing the handlers, see + * https://www.FreeRTOS.org/FAQHelp.html + * + * Systems with a configurable address for the interrupt vector table + * can also encounter assertion failures or even system faults here if + * VTOR is not set correctly to point to the application's vector table. */ + configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler ); + configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler ); + } /* configCHECK_HANDLER_INSTALLATION */ + #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { volatile uint32_t ulImplementedPrioBits = 0; volatile uint8_t ucMaxPriorityValue; - const portISR_t * const pxVectorTable = portSCB_VTOR_REG; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in @@ -1765,21 +1784,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; - - /* Verify correct installation of the FreeRTOS handlers for SVCall and - * PendSV. Do not check the installation of the SysTick handler because - * the application may provide the OS tick without using the SysTick - * timer by overriding the weak function vPortSetupTimerInterrupt(). - * - * Assertion failures here can be caused by incorrect installation of - * the FreeRTOS handlers. For help installing the handlers, see - * https://www.FreeRTOS.org/FAQHelp.html - * - * Systems with a configurable address for the interrupt vector table - * can also encounter assertion failures or even system faults here if - * VTOR is not set correctly to point to the application's vector table. */ - configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler ); - configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler ); } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 60ef37380a4..dc096021f79 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -370,6 +370,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ +/* Runtime Checks on Port Configuration */ +#ifndef configCHECK_HANDLER_INSTALLATION + #if ( configASSERT_DEFINED == 1 ) + #define configCHECK_HANDLER_INSTALLATION 1 + #else + #define configCHECK_HANDLER_INSTALLATION 0 + #endif +#else + #if ( configCHECK_HANDLER_INSTALLATION == 1 && configASSERT_DEFINED == 0 ) + #error You must define configASSERT() when configCHECK_HANDLER_INSTALLATION is 1. + #endif +#endif +/*-----------------------------------------------------------*/ + /** * @brief Tickless idle/low power functionality. */ diff --git a/portable/GCC/ARM_CM0/port.c b/portable/GCC/ARM_CM0/port.c index 9679c9e3c28..e990dd1c32d 100644 --- a/portable/GCC/ARM_CM0/port.c +++ b/portable/GCC/ARM_CM0/port.c @@ -238,7 +238,7 @@ void vPortStartFirstTask( void ) */ BaseType_t xPortStartScheduler( void ) { - #if ( configASSERT_DEFINED == 1 ) + #if ( configCHECK_HANDLER_INSTALLATION == 1 ) { /* Point pxVectorTable at the interrupt vector table. Systems without * a VTOR register provide the value zero in place of the VTOR register @@ -259,7 +259,7 @@ BaseType_t xPortStartScheduler( void ) * VTOR is not set correctly to point to the application's vector table. */ configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler ); } - #endif /* configASSERT_DEFINED */ + #endif /* configCHECK_HANDLER_INSTALLATION */ /* Make PendSV and SysTick the lowest priority interrupt. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; diff --git a/portable/GCC/ARM_CM0/portmacro.h b/portable/GCC/ARM_CM0/portmacro.h index 3c55b5d0c48..606a94f4a73 100644 --- a/portable/GCC/ARM_CM0/portmacro.h +++ b/portable/GCC/ARM_CM0/portmacro.h @@ -143,6 +143,20 @@ extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( nake /*-----------------------------------------------------------*/ +/* Runtime Checks on Port Configuration */ +#ifndef configCHECK_HANDLER_INSTALLATION + #if ( configASSERT_DEFINED == 1 ) + #define configCHECK_HANDLER_INSTALLATION 1 + #else + #define configCHECK_HANDLER_INSTALLATION 0 + #endif +#else + #if ( configCHECK_HANDLER_INSTALLATION == 1 && configASSERT_DEFINED == 0 ) + #error You must define configASSERT() when configCHECK_HANDLER_INSTALLATION is 1. + #endif +#endif +/*-----------------------------------------------------------*/ + portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c index fe0a96c2d45..cf667d31244 100644 --- a/portable/GCC/ARM_CM4F/port.c +++ b/portable/GCC/ARM_CM4F/port.c @@ -310,6 +310,26 @@ BaseType_t xPortStartScheduler( void ) * /source/portable/GCC/ARM_CM7/r0p1 directory. */ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); + + #if ( configCHECK_HANDLER_INSTALLATION == 1 ) + { + const portISR_t * const pxVectorTable = portSCB_VTOR_REG; + + /* Verify correct installation of the FreeRTOS handlers for SVCall and + * PendSV. Do not check the installation of the SysTick handler because + * the application may provide the OS tick without using the SysTick + * timer by overriding the weak function vPortSetupTimerInterrupt(). + * + * Assertion failures here can be caused by incorrect installation of + * the FreeRTOS handlers. For help installing the handlers, see + * https://www.FreeRTOS.org/FAQHelp.html + * + * Systems with a configurable address for the interrupt vector table + * can also encounter assertion failures or even system faults here if + * VTOR is not set correctly to point to the application's vector table. */ + configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler ); + configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler ); + } /* configCHECK_HANDLER_INSTALLATION */ #if ( configASSERT_DEFINED == 1 ) { @@ -317,7 +337,6 @@ BaseType_t xPortStartScheduler( void ) 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; - const portISR_t * const pxVectorTable = portSCB_VTOR_REG; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in @@ -393,21 +412,6 @@ BaseType_t xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ucOriginalPriority; - - /* Verify correct installation of the FreeRTOS handlers for SVCall and - * PendSV. Do not check the installation of the SysTick handler because - * the application may provide the OS tick without using the SysTick - * timer by overriding the weak function vPortSetupTimerInterrupt(). - * - * Assertion failures here can be caused by incorrect installation of - * the FreeRTOS handlers. For help installing the handlers, see - * https://www.FreeRTOS.org/FAQHelp.html - * - * Systems with a configurable address for the interrupt vector table - * can also encounter assertion failures or even system faults here if - * VTOR is not set correctly to point to the application's vector table. */ - configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler ); - configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler ); } #endif /* configASSERT_DEFINED */ diff --git a/portable/GCC/ARM_CM4F/portmacro.h b/portable/GCC/ARM_CM4F/portmacro.h index 40b2d03e91a..956f9ed0b74 100644 --- a/portable/GCC/ARM_CM4F/portmacro.h +++ b/portable/GCC/ARM_CM4F/portmacro.h @@ -133,6 +133,20 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ +/* Runtime Checks on Port Configuration */ +#ifndef configCHECK_HANDLER_INSTALLATION + #if ( configASSERT_DEFINED == 1 ) + #define configCHECK_HANDLER_INSTALLATION 1 + #else + #define configCHECK_HANDLER_INSTALLATION 0 + #endif +#else + #if ( configCHECK_HANDLER_INSTALLATION == 1 && configASSERT_DEFINED == 0 ) + #error You must define configASSERT() when configCHECK_HANDLER_INSTALLATION is 1. + #endif +#endif +/*-----------------------------------------------------------*/ + /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );