mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-05-03 11:50:59 -04:00
Update Cortex-M3 and Cortex-M4F ports to allow the SysTick to be clocked at a different speed than the system clock (as is done in the recent STM32L demo. ).
Add additional asserts and isb instructions into the Cortex-M3 and Cortex-M4F ports.
This commit is contained in:
parent
6b3393b4b6
commit
0d1e12522b
|
@ -237,6 +237,7 @@ void vPortSVCHandler( void )
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
" ldmia r0!, {r4-r11} \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. */
|
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||||
|
" isb \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" orr r14, #0xd \n"
|
" orr r14, #0xd \n"
|
||||||
|
@ -256,6 +257,8 @@ static void prvPortStartFirstTask( void )
|
||||||
" ldr r0, [r0] \n"
|
" ldr r0, [r0] \n"
|
||||||
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
" svc 0 \n" /* System call to start first task. */
|
" svc 0 \n" /* System call to start first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
);
|
);
|
||||||
|
@ -342,8 +345,9 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the CM3 port will require this function as there
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
is nothing to return to. */
|
Artificially force an assert. */
|
||||||
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -370,6 +374,7 @@ void vPortEnterCritical( void )
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
|
configASSERT( uxCriticalNesting );
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
if( uxCriticalNesting == 0 )
|
if( uxCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
|
@ -416,6 +421,7 @@ void xPortPendSVHandler( void )
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
|
" isb \n"
|
||||||
" \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"
|
" ldr r2, [r3] \n"
|
||||||
|
@ -435,6 +441,7 @@ void xPortPendSVHandler( void )
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
||||||
" msr psp, r0 \n"
|
" msr psp, r0 \n"
|
||||||
|
" isb \n"
|
||||||
" bx r14 \n"
|
" bx r14 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 2 \n"
|
" .align 2 \n"
|
||||||
|
@ -468,7 +475,7 @@ void xPortSysTickHandler( void )
|
||||||
|
|
||||||
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
|
||||||
portTickType xModifiableIdleTime;
|
portTickType xModifiableIdleTime;
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
|
@ -481,7 +488,7 @@ void xPortSysTickHandler( void )
|
||||||
is accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
tick periods. -1 is used because this code will execute part way
|
||||||
|
@ -505,7 +512,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
periods. */
|
||||||
|
@ -525,7 +532,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
set its parameter to 0 to indicate that its implementation contains
|
||||||
|
@ -546,13 +553,14 @@ void xPortSysTickHandler( void )
|
||||||
accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
above. */
|
above. */
|
||||||
__asm volatile( "cpsie i" );
|
__asm volatile( "cpsie i" );
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
unsigned long ulCalculatedLoadValue;
|
unsigned long ulCalculatedLoadValue;
|
||||||
|
|
||||||
|
@ -604,7 +612,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
}
|
}
|
||||||
|
@ -632,7 +640,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
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;
|
portNVIC_SYSTICK_CTRL_REG |= ( portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,7 @@ void vPortSVCHandler( void )
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" 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. */
|
" 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. */
|
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||||
|
" isb \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" bx r14 \n"
|
" bx r14 \n"
|
||||||
|
@ -274,6 +275,8 @@ static void prvPortStartFirstTask( void )
|
||||||
" ldr r0, [r0] \n"
|
" ldr r0, [r0] \n"
|
||||||
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
" svc 0 \n" /* System call to start first task. */
|
" svc 0 \n" /* System call to start first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
);
|
);
|
||||||
|
@ -366,8 +369,9 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the CM4F port will require this function as there
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
is nothing to return to. */
|
Artificially force an assert. */
|
||||||
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -394,6 +398,7 @@ void vPortEnterCritical( void )
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
|
configASSERT( uxCriticalNesting );
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
if( uxCriticalNesting == 0 )
|
if( uxCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
|
@ -440,6 +445,7 @@ void xPortPendSVHandler( void )
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
|
" isb \n"
|
||||||
" \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"
|
" ldr r2, [r3] \n"
|
||||||
|
@ -470,6 +476,7 @@ void xPortPendSVHandler( void )
|
||||||
" vldmiaeq r0!, {s16-s31} \n"
|
" vldmiaeq r0!, {s16-s31} \n"
|
||||||
" \n"
|
" \n"
|
||||||
" msr psp, r0 \n"
|
" msr psp, r0 \n"
|
||||||
|
" isb \n"
|
||||||
" \n"
|
" \n"
|
||||||
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
|
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
|
||||||
#if WORKAROUND_PMU_CM001 == 1
|
#if WORKAROUND_PMU_CM001 == 1
|
||||||
|
@ -511,7 +518,7 @@ void xPortSysTickHandler( void )
|
||||||
|
|
||||||
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
|
||||||
portTickType xModifiableIdleTime;
|
portTickType xModifiableIdleTime;
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
|
@ -524,7 +531,7 @@ void xPortSysTickHandler( void )
|
||||||
is accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
tick periods. -1 is used because this code will execute part way
|
||||||
|
@ -548,7 +555,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
periods. */
|
||||||
|
@ -568,7 +575,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
set its parameter to 0 to indicate that its implementation contains
|
||||||
|
@ -589,13 +596,14 @@ void xPortSysTickHandler( void )
|
||||||
accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
above. */
|
above. */
|
||||||
__asm volatile( "cpsie i" );
|
__asm volatile( "cpsie i" );
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
unsigned long ulCalculatedLoadValue;
|
unsigned long ulCalculatedLoadValue;
|
||||||
|
|
||||||
|
@ -647,7 +655,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
}
|
}
|
||||||
|
@ -675,7 +683,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
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;
|
portNVIC_SYSTICK_CTRL_REG |= ( portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -357,7 +357,7 @@ void xPortSysTickHandler( void )
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
|
||||||
portTickType xModifiableIdleTime;
|
portTickType xModifiableIdleTime;
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
|
@ -370,7 +370,7 @@ void xPortSysTickHandler( void )
|
||||||
is accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
tick periods. -1 is used because this code will execute part way
|
||||||
|
@ -394,7 +394,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
periods. */
|
||||||
|
@ -414,7 +414,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
set its parameter to 0 to indicate that its implementation contains
|
||||||
|
@ -435,13 +435,14 @@ void xPortSysTickHandler( void )
|
||||||
accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
/* Re-enable interrupts - see comments above __disable_interrupt()
|
||||||
call above. */
|
call above. */
|
||||||
__enable_interrupt();
|
__enable_interrupt();
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
unsigned long ulCalculatedLoadValue;
|
unsigned long ulCalculatedLoadValue;
|
||||||
|
|
||||||
|
@ -493,7 +494,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
}
|
}
|
||||||
|
@ -521,7 +522,7 @@ __weak void vPortSetupTimerInterrupt( void )
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
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;
|
portNVIC_SYSTICK_CTRL_REG |= ( portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||||
All rights reserved
|
All rights reserved
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
@ -82,9 +82,10 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
xPortPendSVHandler:
|
xPortPendSVHandler:
|
||||||
mrs r0, psp
|
mrs r0, psp
|
||||||
|
isb
|
||||||
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
||||||
ldr r2, [r3]
|
ldr r2, [r3]
|
||||||
|
|
||||||
stmdb r0!, {r4-r11} /* Save the remaining registers. */
|
stmdb r0!, {r4-r11} /* Save the remaining registers. */
|
||||||
str r0, [r2] /* Save the new top of stack into the first member of the TCB. */
|
str r0, [r2] /* Save the new top of stack into the first member of the TCB. */
|
||||||
|
@ -92,16 +93,17 @@ xPortPendSVHandler:
|
||||||
stmdb sp!, {r3, r14}
|
stmdb sp!, {r3, r14}
|
||||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
bl vTaskSwitchContext
|
bl vTaskSwitchContext
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
ldmia sp!, {r3, r14}
|
ldmia sp!, {r3, r14}
|
||||||
|
|
||||||
ldr r1, [r3]
|
ldr r1, [r3]
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
ldmia r0!, {r4-r11} /* Pop the registers. */
|
ldmia r0!, {r4-r11} /* Pop the registers. */
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
bx r14
|
isb
|
||||||
|
bx r14
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -111,7 +113,7 @@ ulPortSetInterruptMask:
|
||||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
msr basepri, r1
|
msr basepri, r1
|
||||||
bx r14
|
bx r14
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
vPortClearInterruptMask:
|
vPortClearInterruptMask:
|
||||||
|
@ -128,6 +130,7 @@ vPortSVCHandler:
|
||||||
/* Pop the core registers. */
|
/* Pop the core registers. */
|
||||||
ldmia r0!, {r4-r11}
|
ldmia r0!, {r4-r11}
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
orr r14, r14, #13
|
orr r14, r14, #13
|
||||||
|
@ -144,7 +147,8 @@ vPortStartFirstTask
|
||||||
msr msp, r0
|
msr msp, r0
|
||||||
/* Call SVC to start the first task. */
|
/* Call SVC to start the first task. */
|
||||||
cpsie i
|
cpsie i
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
svc 0
|
svc 0
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
|
@ -383,7 +383,7 @@ void xPortSysTickHandler( void )
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
|
||||||
portTickType xModifiableIdleTime;
|
portTickType xModifiableIdleTime;
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
|
@ -396,7 +396,7 @@ void xPortSysTickHandler( void )
|
||||||
is accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
tick periods. -1 is used because this code will execute part way
|
||||||
|
@ -420,7 +420,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
periods. */
|
||||||
|
@ -440,7 +440,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
set its parameter to 0 to indicate that its implementation contains
|
||||||
|
@ -461,13 +461,14 @@ void xPortSysTickHandler( void )
|
||||||
accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
/* Re-enable interrupts - see comments above __disable_interrupt()
|
||||||
call above. */
|
call above. */
|
||||||
__enable_interrupt();
|
__enable_interrupt();
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
unsigned long ulCalculatedLoadValue;
|
unsigned long ulCalculatedLoadValue;
|
||||||
|
|
||||||
|
@ -519,7 +520,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
}
|
}
|
||||||
|
@ -547,7 +548,7 @@ __weak void vPortSetupTimerInterrupt( void )
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
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;
|
portNVIC_SYSTICK_CTRL_REG |= ( portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
|
|
||||||
xPortPendSVHandler:
|
xPortPendSVHandler:
|
||||||
mrs r0, psp
|
mrs r0, psp
|
||||||
|
isb
|
||||||
/* Get the location of the current TCB. */
|
/* Get the location of the current TCB. */
|
||||||
ldr r3, =pxCurrentTCB
|
ldr r3, =pxCurrentTCB
|
||||||
ldr r2, [r3]
|
ldr r2, [r3]
|
||||||
|
@ -121,7 +121,7 @@ xPortPendSVHandler:
|
||||||
vldmiaeq r0!, {s16-s31}
|
vldmiaeq r0!, {s16-s31}
|
||||||
|
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
|
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
|
||||||
#if WORKAROUND_PMU_CM001 == 1
|
#if WORKAROUND_PMU_CM001 == 1
|
||||||
push { r14 }
|
push { r14 }
|
||||||
|
@ -156,6 +156,7 @@ vPortSVCHandler:
|
||||||
/* Pop the core registers. */
|
/* Pop the core registers. */
|
||||||
ldmia r0!, {r4-r11, r14}
|
ldmia r0!, {r4-r11, r14}
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
bx r14
|
bx r14
|
||||||
|
@ -171,6 +172,8 @@ vPortStartFirstTask
|
||||||
msr msp, r0
|
msr msp, r0
|
||||||
/* Call SVC to start the first task. */
|
/* Call SVC to start the first task. */
|
||||||
cpsie i
|
cpsie i
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
svc 0
|
svc 0
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -243,6 +243,7 @@ __asm void vPortSVCHandler( void )
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
ldmia r0!, {r4-r11} /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
ldmia r0!, {r4-r11} /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
||||||
msr psp, r0 /* Restore the task stack pointer. */
|
msr psp, r0 /* Restore the task stack pointer. */
|
||||||
|
isb
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
orr r14, #0xd
|
orr r14, #0xd
|
||||||
|
@ -262,6 +263,8 @@ __asm void prvStartFirstTask( void )
|
||||||
msr msp, r0
|
msr msp, r0
|
||||||
/* Globally enable interrupts. */
|
/* Globally enable interrupts. */
|
||||||
cpsie i
|
cpsie i
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
/* Call SVC to start the first task. */
|
/* Call SVC to start the first task. */
|
||||||
svc 0
|
svc 0
|
||||||
nop
|
nop
|
||||||
|
@ -385,6 +388,7 @@ __asm void xPortPendSVHandler( void )
|
||||||
PRESERVE8
|
PRESERVE8
|
||||||
|
|
||||||
mrs r0, psp
|
mrs r0, psp
|
||||||
|
isb
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
||||||
ldr r2, [r3]
|
ldr r2, [r3]
|
||||||
|
@ -404,6 +408,7 @@ __asm void xPortPendSVHandler( void )
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
ldmia r0!, {r4-r11} /* Pop the registers and the critical nesting count. */
|
ldmia r0!, {r4-r11} /* Pop the registers and the critical nesting count. */
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
bx r14
|
bx r14
|
||||||
nop
|
nop
|
||||||
}
|
}
|
||||||
|
@ -433,7 +438,7 @@ void xPortSysTickHandler( void )
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
|
||||||
portTickType xModifiableIdleTime;
|
portTickType xModifiableIdleTime;
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
|
@ -446,7 +451,7 @@ void xPortSysTickHandler( void )
|
||||||
is accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
tick periods. -1 is used because this code will execute part way
|
||||||
|
@ -470,7 +475,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
periods. */
|
||||||
|
@ -490,7 +495,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
set its parameter to 0 to indicate that its implementation contains
|
||||||
|
@ -511,13 +516,14 @@ void xPortSysTickHandler( void )
|
||||||
accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_irq() call
|
/* Re-enable interrupts - see comments above __disable_irq() call
|
||||||
above. */
|
above. */
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
unsigned long ulCalculatedLoadValue;
|
unsigned long ulCalculatedLoadValue;
|
||||||
|
|
||||||
|
@ -569,7 +575,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
}
|
}
|
||||||
|
@ -600,7 +606,7 @@ void xPortSysTickHandler( void )
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
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;
|
portNVIC_SYSTICK_CTRL_REG |= ( portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
||||||
|
|
|
@ -266,6 +266,7 @@ __asm void vPortSVCHandler( void )
|
||||||
/* Pop the core registers. */
|
/* Pop the core registers. */
|
||||||
ldmia r0!, {r4-r11, r14}
|
ldmia r0!, {r4-r11, r14}
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
bx r14
|
bx r14
|
||||||
|
@ -284,6 +285,8 @@ __asm void prvStartFirstTask( void )
|
||||||
msr msp, r0
|
msr msp, r0
|
||||||
/* Globally enable interrupts. */
|
/* Globally enable interrupts. */
|
||||||
cpsie i
|
cpsie i
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
/* Call SVC to start the first task. */
|
/* Call SVC to start the first task. */
|
||||||
svc 0
|
svc 0
|
||||||
nop
|
nop
|
||||||
|
@ -429,7 +432,7 @@ __asm void xPortPendSVHandler( void )
|
||||||
PRESERVE8
|
PRESERVE8
|
||||||
|
|
||||||
mrs r0, psp
|
mrs r0, psp
|
||||||
|
isb
|
||||||
/* Get the location of the current TCB. */
|
/* Get the location of the current TCB. */
|
||||||
ldr r3, =pxCurrentTCB
|
ldr r3, =pxCurrentTCB
|
||||||
ldr r2, [r3]
|
ldr r2, [r3]
|
||||||
|
@ -467,11 +470,12 @@ __asm void xPortPendSVHandler( void )
|
||||||
vldmiaeq r0!, {s16-s31}
|
vldmiaeq r0!, {s16-s31}
|
||||||
|
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
|
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
|
||||||
#if WORKAROUND_PMU_CM001 == 1
|
#if WORKAROUND_PMU_CM001 == 1
|
||||||
push { r14 }
|
push { r14 }
|
||||||
pop { pc }
|
pop { pc }
|
||||||
|
nop
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -504,7 +508,7 @@ void xPortSysTickHandler( void )
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
|
||||||
portTickType xModifiableIdleTime;
|
portTickType xModifiableIdleTime;
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
|
@ -517,7 +521,7 @@ void xPortSysTickHandler( void )
|
||||||
is accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
tick periods. -1 is used because this code will execute part way
|
||||||
|
@ -541,7 +545,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
periods. */
|
||||||
|
@ -561,7 +565,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
set its parameter to 0 to indicate that its implementation contains
|
||||||
|
@ -582,13 +586,14 @@ void xPortSysTickHandler( void )
|
||||||
accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_irq() call
|
/* Re-enable interrupts - see comments above __disable_irq() call
|
||||||
above. */
|
above. */
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
unsigned long ulCalculatedLoadValue;
|
unsigned long ulCalculatedLoadValue;
|
||||||
|
|
||||||
|
@ -640,7 +645,7 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
}
|
}
|
||||||
|
@ -671,7 +676,7 @@ void xPortSysTickHandler( void )
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
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;
|
portNVIC_SYSTICK_CTRL_REG |= ( portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
_vector_14: .type func
|
_vector_14: .type func
|
||||||
|
|
||||||
mrs r0, psp
|
mrs r0, psp
|
||||||
|
isb
|
||||||
|
|
||||||
;Get the location of the current TCB.
|
;Get the location of the current TCB.
|
||||||
ldr.w r3, =pxCurrentTCB
|
ldr.w r3, =pxCurrentTCB
|
||||||
|
@ -110,6 +111,7 @@ _vector_14: .type func
|
||||||
vldmiaeq r0!, {s16-s31}
|
vldmiaeq r0!, {s16-s31}
|
||||||
|
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
bx r14
|
bx r14
|
||||||
|
|
||||||
.size _vector_14, $-_vector_14
|
.size _vector_14, $-_vector_14
|
||||||
|
@ -125,6 +127,7 @@ _vector_14: .type func
|
||||||
_lc_ref__vector_pp_14: .type func
|
_lc_ref__vector_pp_14: .type func
|
||||||
|
|
||||||
mrs r0, psp
|
mrs r0, psp
|
||||||
|
isb
|
||||||
|
|
||||||
;Get the location of the current TCB.
|
;Get the location of the current TCB.
|
||||||
ldr.w r3, =pxCurrentTCB
|
ldr.w r3, =pxCurrentTCB
|
||||||
|
@ -162,6 +165,7 @@ _lc_ref__vector_pp_14: .type func
|
||||||
vldmiaeq r0!, {s16-s31}
|
vldmiaeq r0!, {s16-s31}
|
||||||
|
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
push { lr }
|
push { lr }
|
||||||
pop { pc } ; XMC4000 specific errata workaround. Do not used "bx lr" here.
|
pop { pc } ; XMC4000 specific errata workaround. Do not used "bx lr" here.
|
||||||
|
|
||||||
|
@ -181,6 +185,7 @@ SVC_Handler: .type func
|
||||||
;Pop the core registers.
|
;Pop the core registers.
|
||||||
ldmia r0!, {r4-r11, r14}
|
ldmia r0!, {r4-r11, r14}
|
||||||
msr psp, r0
|
msr psp, r0
|
||||||
|
isb
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
bx r14
|
bx r14
|
||||||
|
@ -201,6 +206,8 @@ vPortStartFirstTask .type func
|
||||||
msr msp, r0
|
msr msp, r0
|
||||||
;Call SVC to start the first task.
|
;Call SVC to start the first task.
|
||||||
cpsie i
|
cpsie i
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
svc 0
|
svc 0
|
||||||
.size vPortStartFirstTask, $-vPortStartFirstTask
|
.size vPortStartFirstTask, $-vPortStartFirstTask
|
||||||
.endsec
|
.endsec
|
||||||
|
|
|
@ -242,12 +242,12 @@ portBASE_TYPE xReturn = pdFAIL;
|
||||||
{
|
{
|
||||||
/* Create the timer task, storing its handle in xTimerTaskHandle so
|
/* Create the timer task, storing its handle in xTimerTaskHandle so
|
||||||
it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
|
it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
|
||||||
xReturn = xTaskCreate( prvTimerTask, ( const signed char * const ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );
|
xReturn = xTaskCreate( prvTimerTask, ( signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
/* Create the timer task without storing its handle. */
|
/* Create the timer task without storing its handle. */
|
||||||
xReturn = xTaskCreate( prvTimerTask, ( const signed char * const ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL);
|
xReturn = xTaskCreate( prvTimerTask, ( signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue