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.

This commit is contained in:
Richard Barry 2019-12-30 21:16:09 +00:00
parent e23d638afd
commit e292c67933
6 changed files with 68 additions and 49 deletions

View File

@ -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 )

View File

@ -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 );

View File

@ -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 )

View File

@ -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 );

View File

@ -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

View File

@ -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 )