From e292c6793340ddede2700861316cf77eeb24a574 Mon Sep 17 00:00:00 2001 From: Richard Barry Date: Mon, 30 Dec 2019 21:16:09 +0000 Subject: [PATCH] Replace the static prvSetupTimerInterrupt() function in the Cortex-M port layers that still used it (other than MPU ports so far) with a weakly defined function call vPortSetupTimerInterrupt() - which allows application writers to override the function with one that uses a different clock. --- FreeRTOS/Source/portable/GCC/ARM_CM0/port.c | 10 ++-- FreeRTOS/Source/portable/IAR/ARM_CM0/port.c | 22 ++++---- FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c | 51 ++++++++++++------- FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c | 22 ++++---- FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c | 10 ++-- .../Source/portable/RVDS/ARM_CM7/r0p1/port.c | 2 +- 6 files changed, 68 insertions(+), 49 deletions(-) diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c index 18a668b9b..15a5795ef 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c +++ b/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c @@ -71,9 +71,11 @@ debugger. */ #endif /* - * Setup the timer to generate the tick interrupts. + * 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. */ -static void prvSetupTimerInterrupt( void ); +void vPortSetupTimerInterrupt( void ); /* * Exception handlers. @@ -217,7 +219,7 @@ BaseType_t xPortStartScheduler( void ) /* Start the timer that generates the tick ISR. Interrupts are disabled here already. */ - prvSetupTimerInterrupt(); + vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; @@ -370,7 +372,7 @@ uint32_t ulPreviousMask; * Setup the systick timer to generate the tick interrupts at the required * frequency. */ -void prvSetupTimerInterrupt( void ) +__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if( configUSE_TICKLESS_IDLE == 1 ) diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c index 3dd08209d..84f1e66e0 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c +++ b/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c @@ -92,9 +92,11 @@ power functionality only. */ #endif /* configUSE_TICKLESS_IDLE */ /* - * Setup the timer to generate the tick interrupts. + * 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. */ -static void prvSetupTimerInterrupt( void ); +void vPortSetupTimerInterrupt( void ); /* * Exception handlers. @@ -159,7 +161,7 @@ BaseType_t xPortStartScheduler( void ) /* Start the timer that generates the tick ISR. Interrupts are disabled here already. */ - prvSetupTimerInterrupt(); + vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; @@ -233,7 +235,7 @@ uint32_t ulPreviousMask; * Setup the systick timer to generate the tick interrupts at the required * frequency. */ -static void prvSetupTimerInterrupt( void ) +__weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if( configUSE_TICKLESS_IDLE == 1 ) @@ -243,7 +245,7 @@ static void prvSetupTimerInterrupt( void ) ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR; } #endif /* configUSE_TICKLESS_IDLE */ - + /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; @@ -349,12 +351,12 @@ TickType_t xModifiableIdleTime; __DSB(); __ISB(); - /* Disable the SysTick clock without reading the + /* 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 + 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 | portNVIC_SYSTICK_INT_BIT ); diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c index 8282984b5..be659fd4f 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c @@ -64,6 +64,15 @@ /* Constants used with memory barrier intrinsics. */ #define portSY_FULL_READ_WRITE ( 15 ) +/* Legacy macro for backward compatibility only. This macro used to be used to +replace the function that configures the clock used to generate the tick +interrupt (prvSetupTimerInterrupt()), but now the function is declared weak so +the application writer can override it by simply defining a function of the +same name (vApplicationSetupTickInterrupt()). */ +#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION + #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 +#endif + /* Each task maintains its own interrupt status in the critical nesting variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; @@ -87,9 +96,11 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; #endif /* configUSE_TICKLESS_IDLE */ /* - * Setup the timer to generate the tick interrupts. + * 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. */ -static void prvSetupTimerInterrupt( void ); +void vPortSetupTimerInterrupt( void ); /* * Exception handlers. @@ -192,7 +203,7 @@ BaseType_t xPortStartScheduler( void ) /* Start the timer that generates the tick ISR. Interrupts are disabled here already. */ - prvSetupTimerInterrupt(); + vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; @@ -327,23 +338,27 @@ uint32_t ulPreviousMask; * Setup the systick timer to generate the tick interrupts at the required * frequency. */ -void prvSetupTimerInterrupt( void ) -{ - /* Calculate the constants required to configure the tick interrupt. */ - #if( configUSE_TICKLESS_IDLE == 1 ) - ulTimerCountsForOneTick = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ); - xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; - ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR; - #endif /* configUSE_TICKLESS_IDLE */ +#if( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 ) - /* Stop and reset the SysTick. */ - portNVIC_SYSTICK_CTRL_REG = 0UL; - portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + __weak void vPortSetupTimerInterrupt( void ) + { + /* Calculate the constants required to configure the tick interrupt. */ + #if( configUSE_TICKLESS_IDLE == 1 ) + ulTimerCountsForOneTick = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR; + #endif /* configUSE_TICKLESS_IDLE */ - /* Configure SysTick to interrupt at the requested rate. */ - portNVIC_SYSTICK_LOAD_REG = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; - portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; -} + /* 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 = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + } + +#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */ /*-----------------------------------------------------------*/ #if( configUSE_TICKLESS_IDLE == 1 ) diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c index 76dcb5727..6e4e77f97 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c @@ -51,11 +51,11 @@ #define portNVIC_SYSTICK_CLK_BIT ( 0 ) #endif -/* The __weak attribute does not work as you might expect with the Keil tools -so the configOVERRIDE_DEFAULT_TICK_CONFIGURATION constant must be set to 1 if -the application writer wants to provide their own implementation of -vPortSetupTimerInterrupt(). Ensure configOVERRIDE_DEFAULT_TICK_CONFIGURATION -is defined. */ +/* Legacy macro for backward compatibility only. This macro used to be used to +replace the function that configures the clock used to generate the tick +interrupt (prvSetupTimerInterrupt()), but now the function is declared weak so +the application writer can override it by simply defining a function of the +same name (vApplicationSetupTickInterrupt()). */ #ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 #endif @@ -523,13 +523,13 @@ void xPortSysTickHandler( void ) __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); - - /* Disable the SysTick clock without reading the + + /* 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 + 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 | portNVIC_SYSTICK_INT_BIT ); diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c index 6a9cbbf25..99ffeaa39 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c @@ -51,11 +51,11 @@ #define portNVIC_SYSTICK_CLK_BIT ( 0 ) #endif -/* The __weak attribute does not work as you might expect with the Keil tools -so the configOVERRIDE_DEFAULT_TICK_CONFIGURATION constant must be set to 1 if -the application writer wants to provide their own implementation of -vPortSetupTimerInterrupt(). Ensure configOVERRIDE_DEFAULT_TICK_CONFIGURATION -is defined. */ +/* Legacy macro for backward compatibility only. This macro used to be used to +replace the function that configures the clock used to generate the tick +interrupt (prvSetupTimerInterrupt()), but now the function is declared weak so +the application writer can override it by simply defining a function of the +same name (vApplicationSetupTickInterrupt()). */ #ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 #endif diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c index 967f5f10e..fa63025a2 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c @@ -679,7 +679,7 @@ void xPortSysTickHandler( void ) */ #if( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 ) - void vPortSetupTimerInterrupt( void ) + __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if( configUSE_TICKLESS_IDLE == 1 )