Improvements to the Cortex-M ports:

- Clear the SysTick current value register before starting the SysTick (only required if something uses SysTick before starting the scheduler).
- Ensure atomic operations are thread safe by executing clrex in the context switch.
This commit is contained in:
Richard Barry 2016-06-27 13:13:05 +00:00
parent 6c975cd46a
commit c296e2cff8
23 changed files with 139 additions and 40 deletions

View file

@ -79,8 +79,9 @@
#include "task.h"
/* Constants required to manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL ( ( volatile uint32_t *) 0xe000e010 )
#define portNVIC_SYSTICK_LOAD ( ( volatile uint32_t *) 0xe000e014 )
#define portNVIC_SYSTICK_CTRL ( ( volatile uint32_t * ) 0xe000e010 )
#define portNVIC_SYSTICK_LOAD ( ( volatile uint32_t * ) 0xe000e014 )
#define portNVIC_SYSTICK_CURRENT_VALUE ( ( volatile uint32_t * ) 0xe000e018 )
#define portNVIC_SYSPRI2 ( ( volatile uint32_t *) 0xe000ed20 )
#define portNVIC_SYSTICK_CLK 0x00000004
#define portNVIC_SYSTICK_INT 0x00000002
@ -247,6 +248,10 @@ uint32_t ulPreviousMask;
*/
static void prvSetupTimerInterrupt( void )
{
/* Stop and reset the SysTick. */
*(portNVIC_SYSTICK_CTRL) = 0UL;
*(portNVIC_SYSTICK_CURRENT_VALUE) = 0UL;
/* 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;

View file

@ -535,6 +535,10 @@ __weak void vPortSetupTimerInterrupt( void )
}
#endif /* configUSE_TICKLESS_IDLE */
/* Stop and clear 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 | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );

View file

@ -91,6 +91,7 @@ xPortPendSVHandler:
stmdb r0!, {r4-r11} /* Save the remaining registers. */
str r0, [r2] /* Save the new top of stack into the first member of the TCB. */
clrex /* Ensure thread safety of atomic operations. */
stmdb sp!, {r3, r14}
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY

View file

@ -576,6 +576,10 @@ __weak void vPortSetupTimerInterrupt( void )
}
#endif /* configUSE_TICKLESS_IDLE */
/* Stop and clear 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 | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );

View file

@ -101,6 +101,9 @@ xPortPendSVHandler:
/* Save the new top of stack into the first member of the TCB. */
str r0, [r2]
/* Ensure thread safety of atomic operations. */
clrex
stmdb sp!, {r3}
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0

View file

@ -559,6 +559,10 @@ __weak void vPortSetupTimerInterrupt( void )
}
#endif /* configUSE_TICKLESS_IDLE */
/* Stop and clear 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 | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );

View file

@ -101,6 +101,9 @@ xPortPendSVHandler:
/* Save the new top of stack into the first member of the TCB. */
str r0, [r2]
/* Ensure thread safety of atomic operations. */
clrex
stmdb sp!, {r3}
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
cpsid i