]> git.sur5r.net Git - freertos/commitdiff
Improvements to the Cortex-M ports:
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 27 Jun 2016 13:13:05 +0000 (13:13 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 27 Jun 2016 13:13:05 +0000 (13:13 +0000)
- 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.

git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2465 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

23 files changed:
FreeRTOS/Source/include/FreeRTOS.h
FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c
FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm
FreeRTOS/Source/portable/GCC/ARM_CM0/port.c
FreeRTOS/Source/portable/GCC/ARM_CM3/port.c
FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c
FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c
FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c
FreeRTOS/Source/portable/IAR/ARM_CM0/port.c
FreeRTOS/Source/portable/IAR/ARM_CM3/port.c
FreeRTOS/Source/portable/IAR/ARM_CM3/portasm.s
FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c
FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s
FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c
FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s
FreeRTOS/Source/portable/MikroC/ARM_CM4F/port.c
FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c
FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c
FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c
FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c
FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c
FreeRTOS/Source/tasks.c

index 08a6be4f6445d30487503733823997f430580f25..292f3e2290cf46c9c805cd38ecfc6d1941c23f96 100644 (file)
@@ -126,6 +126,10 @@ extern "C" {
        #error Missing definition:  configMAX_PRIORITIES must be defined in FreeRTOSConfig.h.  See the Configuration section of the FreeRTOS API documentation for details.\r
 #endif\r
 \r
+#if configMAX_PRIORITIES < 1\r
+       #error configMAX_PRIORITIES must be defined to be greater than or equal to 1.\r
+#endif\r
+\r
 #ifndef configUSE_PREEMPTION\r
        #error Missing definition:  configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.\r
 #endif\r
@@ -142,10 +146,6 @@ extern "C" {
        #error Missing definition:  configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.\r
 #endif\r
 \r
-#ifndef configMAX_PRIORITIES\r
-       #error configMAX_PRIORITIES must be defined to be greater than or equal to 1.\r
-#endif\r
-\r
 #ifndef configUSE_CO_ROUTINES\r
        #define configUSE_CO_ROUTINES 0\r
 #endif\r
index 631d68ec170eb578a06021532d3cad712ab14010..65a2a5fad97c99d510c7fab6ad3318f6b75bfbe8 100644 (file)
@@ -563,6 +563,10 @@ void vPortSetupTimerInterrupt( void )
        }\r
        #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+       /* Stop and clear the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index a392583b07b72f59842f7f38d14ae86cd25f5594..aa42559800c40ed1a63c172c0ca1d0489c7ab92e 100644 (file)
@@ -123,6 +123,9 @@ xPortPendSVHandler: .asmfunc
        ;/* Save the new top of stack into the first member of the TCB. */\r
        str r0, [r2]\r
 \r
+       ;/* Ensure thread safety of atomic operations. */\r
+       clrex\r
+\r
        stmdb sp!, {r3}\r
        ldr r0, ulMaxSyscallInterruptPriorityConst\r
        ldr r1, [r0]\r
index 191d19c438a15083e3d6d230b52920f252e72a8c..0b5888c63144aeb8f1709ba2b6569292d74cb09e 100644 (file)
@@ -76,8 +76,9 @@
 #include "task.h"\r
 \r
 /* Constants required to manipulate the NVIC. */\r
-#define portNVIC_SYSTICK_CTRL          ( ( volatile uint32_t *) 0xe000e010 )\r
-#define portNVIC_SYSTICK_LOAD          ( ( volatile uint32_t *) 0xe000e014 )\r
+#define portNVIC_SYSTICK_CTRL                  ( ( volatile uint32_t * ) 0xe000e010 )\r
+#define portNVIC_SYSTICK_LOAD                  ( ( volatile uint32_t * ) 0xe000e014 )\r
+#define portNVIC_SYSTICK_CURRENT_VALUE ( ( volatile uint32_t * ) 0xe000e018 )\r
 #define portNVIC_INT_CTRL                      ( ( volatile uint32_t *) 0xe000ed04 )\r
 #define portNVIC_SYSPRI2                       ( ( volatile uint32_t *) 0xe000ed20 )\r
 #define portNVIC_SYSTICK_CLK           0x00000004\r
@@ -310,7 +311,7 @@ void xPortPendSVHandler( void )
        "       mov r5, r9                                                      \n"\r
        "       mov r6, r10                                                     \n"\r
        "       mov r7, r11                                                     \n"\r
-       "       stmia r0!, {r4-r7}                      \n"\r
+       "       stmia r0!, {r4-r7}                                      \n"\r
        "                                                                               \n"\r
        "       push {r3, r14}                                          \n"\r
        "       cpsid i                                                         \n"\r
@@ -330,7 +331,7 @@ void xPortPendSVHandler( void )
        "       msr psp, r0                                                     \n" /* Remember the new top of stack for the task. */\r
        "                                                                               \n"\r
        "       sub r0, r0, #32                                         \n" /* Go back for the low registers that are not automatically restored. */\r
-       "       ldmia r0!, {r4-r7}                      \n" /* Pop low registers.  */\r
+       "       ldmia r0!, {r4-r7}                                      \n" /* Pop low registers.  */\r
        "                                                                               \n"\r
        "       bx r3                                                           \n"\r
        "                                                                               \n"\r
@@ -363,6 +364,10 @@ uint32_t ulPreviousMask;
  */\r
 void prvSetupTimerInterrupt( void )\r
 {\r
+       /* Stop and reset the SysTick. */\r
+       *(portNVIC_SYSTICK_CTRL) = 0UL;\r
+       *(portNVIC_SYSTICK_CURRENT_VALUE) = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
index 6f3611b0b1332007827863735d9bc6a07f6db243..0888579f87ca5dc949ed9cc3d5e8a47f0aa39ee6 100644 (file)
@@ -410,6 +410,7 @@ void xPortPendSVHandler( void )
        "                                                                               \n"\r
        "       stmdb r0!, {r4-r11}                                     \n" /* Save the remaining registers. */\r
        "       str r0, [r2]                                            \n" /* Save the new top of stack into the first member of the TCB. */\r
+       "       clrex                                                           \n" /* Ensure thread safety of atomic operations. */\r
        "                                                                               \n"\r
        "       stmdb sp!, {r3, r14}                            \n"\r
        "       mov r0, %0                                                      \n"\r
@@ -622,6 +623,10 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
        }\r
        #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+       /* Stop and clear the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index 0f30f01615f2b316883d7226a0f3cf5d3d7b23bf..986b988240fd418bfaa9c9b7684c805471504737 100644 (file)
@@ -89,6 +89,7 @@ task.h is included from an application file. */
 /* Constants required to access and manipulate the NVIC. */\r
 #define portNVIC_SYSTICK_CTRL_REG                              ( * ( ( volatile uint32_t * ) 0xe000e010 ) )\r
 #define portNVIC_SYSTICK_LOAD_REG                              ( * ( ( volatile uint32_t * ) 0xe000e014 ) )\r
+#define portNVIC_SYSTICK_CURRENT_VALUE_REG             ( * ( ( volatile uint32_t * ) 0xe000e018 ) )\r
 #define portNVIC_SYSPRI2_REG                                   ( *     ( ( volatile uint32_t * ) 0xe000ed20 ) )\r
 #define portNVIC_SYSPRI1_REG                                   ( * ( ( volatile uint32_t * ) 0xe000ed1c ) )\r
 #define portNVIC_SYS_CTRL_STATE_REG                            ( * ( ( volatile uint32_t * ) 0xe000ed24 ) )\r
@@ -449,6 +450,7 @@ void xPortPendSVHandler( void )
                "       mrs r1, control                                         \n"\r
                "       stmdb r0!, {r1, r4-r11}                         \n" /* Save the remaining registers. */\r
                "       str r0, [r2]                                            \n" /* Save the new top of stack into the first member of the TCB. */\r
+               "       clrex                                                           \n" /* Ensure thread safety of atomic operations. */\r
                "                                                                               \n"\r
                "       stmdb sp!, {r3, r14}                            \n"\r
                "       mov r0, %0                                                      \n"\r
@@ -500,6 +502,10 @@ uint32_t ulDummy;
  */\r
 static void prvSetupTimerInterrupt( void )\r
 {\r
+       /* Reset the SysTick timer. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
index 42f5b378bddb29f6787fac34a7dffeceedf4fbce..2cb58683e79047483c54d07e63fd73b0a05841ec 100644 (file)
@@ -449,8 +449,8 @@ void xPortPendSVHandler( void )
        "       vstmdbeq r0!, {s16-s31}                         \n"\r
        "                                                                               \n"\r
        "       stmdb r0!, {r4-r11, r14}                        \n" /* Save the core registers. */\r
-       "                                                                               \n"\r
        "       str r0, [r2]                                            \n" /* Save the new top of stack into the first member of the TCB. */\r
+       "       clrex                                                           \n" /* Ensure thread safety of atomic operations. */\r
        "                                                                               \n"\r
        "       stmdb sp!, {r3}                                         \n"\r
        "       mov r0, %0                                                      \n"\r
@@ -679,6 +679,10 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
        }\r
        #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+       /* Stop and clear the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index 83e175301901680ecb55b2a9680b7a0d85902930..a6b4c5a84e57d4fae6775b55b1cc1ee779bce02d 100644 (file)
@@ -91,6 +91,7 @@ task.h is included from an application file. */
 /* Constants required to access and manipulate the NVIC. */\r
 #define portNVIC_SYSTICK_CTRL_REG                              ( * ( ( volatile uint32_t * ) 0xe000e010 ) )\r
 #define portNVIC_SYSTICK_LOAD_REG                              ( * ( ( volatile uint32_t * ) 0xe000e014 ) )\r
+#define portNVIC_SYSTICK_CURRENT_VALUE_REG             ( * ( ( volatile uint32_t * ) 0xe000e018 ) )\r
 #define portNVIC_SYSPRI2_REG                                   ( *     ( ( volatile uint32_t * ) 0xe000ed20 ) )\r
 #define portNVIC_SYSPRI1_REG                                   ( * ( ( volatile uint32_t * ) 0xe000ed1c ) )\r
 #define portNVIC_SYS_CTRL_STATE_REG                            ( * ( ( volatile uint32_t * ) 0xe000ed24 ) )\r
@@ -196,7 +197,7 @@ static void prvSVCHandler( uint32_t *pulRegisters ) __attribute__(( noinline ))
  * Function to enable the VFP.\r
  */\r
  static void vPortEnableVFP( void ) __attribute__ (( naked ));\r
\r
+\r
 /*\r
  * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure\r
  * FreeRTOS API functions are not called from interrupts that have been assigned\r
@@ -225,12 +226,12 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
        *pxTopOfStack = 0;      /* LR */\r
        pxTopOfStack -= 5;      /* R12, R3, R2 and R1. */\r
        *pxTopOfStack = ( StackType_t ) pvParameters;   /* R0 */\r
-       \r
+\r
        /* A save method is being used that requires each task to maintain its\r
        own exec return value. */\r
        pxTopOfStack--;\r
        *pxTopOfStack = portINITIAL_EXEC_RETURN;\r
-       \r
+\r
        pxTopOfStack -= 9;      /* R11, R10, R9, R8, R7, R6, R5 and R4. */\r
 \r
        if( xRunPrivileged == pdTRUE )\r
@@ -476,6 +477,7 @@ void xPortPendSVHandler( void )
                "       mrs r1, control                                         \n"\r
                "       stmdb r0!, {r1, r4-r11, r14}            \n" /* Save the remaining registers. */\r
                "       str r0, [r2]                                            \n" /* Save the new top of stack into the first member of the TCB. */\r
+               "       clrex                                                           \n" /* Ensure thread safety of atomic operations. */\r
                "                                                                               \n"\r
                "       stmdb sp!, {r3}                                         \n"\r
                "       mov r0, %0                                                      \n"\r
@@ -533,6 +535,10 @@ uint32_t ulDummy;
  */\r
 static void prvSetupTimerInterrupt( void )\r
 {\r
+       /* Clear the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
index ce19d6af5593fdf6023d08a7ff641b29f71b75f1..51d1c1a661a22b2d125565059bfb5461dea6f8f7 100644 (file)
@@ -437,8 +437,8 @@ void xPortPendSVHandler( void )
        "       vstmdbeq r0!, {s16-s31}                         \n"\r
        "                                                                               \n"\r
        "       stmdb r0!, {r4-r11, r14}                        \n" /* Save the core registers. */\r
-       "                                                                               \n"\r
        "       str r0, [r2]                                            \n" /* Save the new top of stack into the first member of the TCB. */\r
+       "       clrex                                                           \n" /* Ensure thread safety of atomic operations. */\r
        "                                                                               \n"\r
        "       stmdb sp!, {r3}                                         \n"\r
        "       mov r0, %0                                                      \n"\r
@@ -669,6 +669,10 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
        }\r
        #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+       /* Stop and clear the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index ed00f224758892b43ed629fd462670ed6c50cc07..7ab3635f5407b9cc3949ada6f5f90f83bdc962a9 100644 (file)
@@ -79,8 +79,9 @@
 #include "task.h"\r
 \r
 /* Constants required to manipulate the NVIC. */\r
-#define portNVIC_SYSTICK_CTRL          ( ( volatile uint32_t *) 0xe000e010 )\r
-#define portNVIC_SYSTICK_LOAD          ( ( volatile uint32_t *) 0xe000e014 )\r
+#define portNVIC_SYSTICK_CTRL                  ( ( volatile uint32_t * ) 0xe000e010 )\r
+#define portNVIC_SYSTICK_LOAD                  ( ( volatile uint32_t * ) 0xe000e014 )\r
+#define portNVIC_SYSTICK_CURRENT_VALUE ( ( volatile uint32_t * ) 0xe000e018 )\r
 #define portNVIC_SYSPRI2                       ( ( volatile uint32_t *) 0xe000ed20 )\r
 #define portNVIC_SYSTICK_CLK           0x00000004\r
 #define portNVIC_SYSTICK_INT           0x00000002\r
@@ -247,6 +248,10 @@ uint32_t ulPreviousMask;
  */\r
 static void prvSetupTimerInterrupt( void )\r
 {\r
+       /* Stop and reset the SysTick. */\r
+       *(portNVIC_SYSTICK_CTRL) = 0UL;\r
+       *(portNVIC_SYSTICK_CURRENT_VALUE) = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
index c6f4ac291e834e4b2e7e4844a4922dabf7426adc..595b49de80be410e58859b0c2bcd1ab696bf6127 100644 (file)
@@ -535,6 +535,10 @@ __weak void vPortSetupTimerInterrupt( void )
        }\r
        #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+       /* Stop and clear the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index cf7a6a3a1bc5999352f98384a461c00d9b88ff19..756602121dd670eca26f61ea2489d21de9b4262f 100644 (file)
@@ -91,6 +91,7 @@ xPortPendSVHandler:
 \r
        stmdb r0!, {r4-r11}                             /* Save the remaining registers. */\r
        str r0, [r2]                                    /* Save the new top of stack into the first member of the TCB. */\r
+       clrex                                                   /* Ensure thread safety of atomic operations. */\r
 \r
        stmdb sp!, {r3, r14}\r
        mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
index 3d102b6c64518e7f60ee9afe3687822ec98feabf..094965f88dcbb79eea0efba8178f02efd7492877 100644 (file)
@@ -576,6 +576,10 @@ __weak void vPortSetupTimerInterrupt( void )
        }\r
        #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+       /* Stop and clear the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index 758d6fa9718a7a65fe516403b289a0c299a4ad11..a6e07773db658e5062a65924e77cc67081893f76 100644 (file)
@@ -101,6 +101,9 @@ xPortPendSVHandler:
        /* Save the new top of stack into the first member of the TCB. */\r
        str r0, [r2]\r
 \r
+       /* Ensure thread safety of atomic operations. */\r
+       clrex\r
+\r
        stmdb sp!, {r3}\r
        mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
        msr basepri, r0\r
index da08e49711b1ff4d47a0379d4a3eb057e1368dcb..34a1b25a4762856925107b71815ff4fb2caa2fee 100644 (file)
@@ -559,6 +559,10 @@ __weak void vPortSetupTimerInterrupt( void )
        }\r
        #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+       /* Stop and clear the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index 2ab809a0e3282f3969749c8a2effee1f5e768706..e90dfb26124c11880c6656795eb5a91439eff5e0 100644 (file)
@@ -101,6 +101,9 @@ xPortPendSVHandler:
        /* Save the new top of stack into the first member of the TCB. */\r
        str r0, [r2]\r
 \r
+       /* Ensure thread safety of atomic operations. */\r
+       clrex\r
+\r
        stmdb sp!, {r3}\r
        mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
        cpsid i\r
index 97a7c8dd1e2a22943c246b8953c95d05896d739f..8bd991d3cafbbec789db64a6797827d8fa1a3340 100644 (file)
@@ -457,7 +457,8 @@ void xPortPendSVHandler( void ) iv IVT_INT_PendSV ics ICS_OFF
        stmdb r0!, (r4-r11, r14)                 /* Save the core registers. */\r
 \r
        str r0, [r2]                     /* Save the new top of stack into the first member of the TCB. */\r
-/*_RB_?        mrs r0, psp why was this here? */\r
+\r
+       clrex                                   /* Ensure thread safety of atomic operations. */\r
 \r
        stmdb sp!, (r3)\r
        ldr r0, =_ucMaxSyscallInterruptPriority\r
@@ -670,20 +671,24 @@ void xPortSysTickHandler( void ) iv IVT_INT_SysTick ics ICS_AUTO
 #if( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 )\r
 \r
        void vPortSetupTimerInterrupt( void )\r
-               {\r
-                               /* Calculate the constants required to configure the tick interrupt. */\r
-                               #if configUSE_TICKLESS_IDLE == 1\r
-                               {\r
-                                               ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );\r
-                                               xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;\r
-                                               ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );\r
-                               }\r
-                               #endif /* configUSE_TICKLESS_IDLE */\r
+       {\r
+                       /* Calculate the constants required to configure the tick interrupt. */\r
+                       #if configUSE_TICKLESS_IDLE == 1\r
+                       {\r
+                                       ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );\r
+                                       xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;\r
+                                       ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );\r
+                       }\r
+                       #endif /* configUSE_TICKLESS_IDLE */\r
 \r
-                               /* Configure SysTick to interrupt at the requested rate. */\r
-                               portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
-                               portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
-               }\r
+                       /* Reset SysTick. */\r
+                       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+                       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
+                       /* Configure SysTick to interrupt at the requested rate. */\r
+                       portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
+                       portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
+       }\r
 \r
 #endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */\r
 /*-----------------------------------------------------------*/\r
index 6fc1e94b67020a73146b7d14f7f59fd6cb966273..1de444935591c743b6d62766fb1131798789a9bf 100644 (file)
@@ -76,8 +76,9 @@
 #include "task.h"\r
 \r
 /* Constants required to manipulate the NVIC. */\r
-#define portNVIC_SYSTICK_CTRL          ( ( volatile uint32_t *) 0xe000e010 )\r
-#define portNVIC_SYSTICK_LOAD          ( ( volatile uint32_t *) 0xe000e014 )\r
+#define portNVIC_SYSTICK_CTRL                  ( ( volatile uint32_t * ) 0xe000e010 )\r
+#define portNVIC_SYSTICK_LOAD                  ( ( volatile uint32_t * ) 0xe000e014 )\r
+#define portNVIC_SYSTICK_CURRENT_VALUE ( ( volatile uint32_t * ) 0xe000e018 )\r
 #define portNVIC_INT_CTRL                      ( ( volatile uint32_t *) 0xe000ed04 )\r
 #define portNVIC_SYSPRI2                       ( ( volatile uint32_t *) 0xe000ed20 )\r
 #define portNVIC_SYSTICK_CLK           0x00000004\r
@@ -341,6 +342,10 @@ uint32_t ulPreviousMask;
  */\r
 void prvSetupTimerInterrupt( void )\r
 {\r
+       /* Stop and reset the SysTick. */\r
+       *(portNVIC_SYSTICK_CTRL) = 0UL;\r
+       *(portNVIC_SYSTICK_CURRENT_VALUE) = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
index 61d85967d7c1420f9e0fcaed12115e9e8af987d9..8ce6d098d2e1b35d3ee9e5af2c5d0a8fa851cc1d 100644 (file)
@@ -407,6 +407,7 @@ __asm void xPortPendSVHandler( void )
 \r
        stmdb r0!, {r4-r11}                     /* Save the remaining registers. */\r
        str r0, [r2]                            /* Save the new top of stack into the first member of the TCB. */\r
+       clrex                                           /* Ensure thread safety of atomic operations. */\r
 \r
        stmdb sp!, {r3, r14}\r
        mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
@@ -621,6 +622,10 @@ void xPortSysTickHandler( void )
                }\r
                #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+               /* Stop and clear the SysTick. */\r
+               portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+               portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
                /* Configure SysTick to interrupt at the requested rate. */\r
                portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
                portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index 1dc1b5b005541e7ea7d251e64ca0c5b7c502d52f..aaf9efd21ecf09e71c8158007709d99231bf6857 100644 (file)
@@ -479,6 +479,9 @@ __asm void xPortPendSVHandler( void )
        /* Save the new top of stack into the first member of the TCB. */\r
        str r0, [r2]\r
 \r
+       /* Ensure thread safety of atomic operations. */\r
+       clrex\r
+\r
        stmdb sp!, {r3}\r
        mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
        msr basepri, r0\r
@@ -696,7 +699,7 @@ void xPortSysTickHandler( void )
  * Setup the SysTick timer to generate the tick interrupts at the required\r
  * frequency.\r
  */\r
-#if configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0\r
+#if( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 )\r
 \r
        void vPortSetupTimerInterrupt( void )\r
        {\r
@@ -709,6 +712,10 @@ void xPortSysTickHandler( void )
                }\r
                #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+               /* Stop and clear the SysTick. */\r
+               portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+               portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
                /* Configure SysTick to interrupt at the requested rate. */\r
                portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
                portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index bbe2a96a88f4bb1cc45a1579e5f72e466ba92449..0623859e8417921b9ec8049671c7c78007ba353b 100644 (file)
@@ -91,6 +91,7 @@ task.h is included from an application file. */
 /* Constants required to access and manipulate the NVIC. */\r
 #define portNVIC_SYSTICK_CTRL_REG                              ( * ( ( volatile uint32_t * ) 0xe000e010 ) )\r
 #define portNVIC_SYSTICK_LOAD_REG                              ( * ( ( volatile uint32_t * ) 0xe000e014 ) )\r
+#define portNVIC_SYSTICK_CURRENT_VALUE_REG             ( * ( ( volatile uint32_t * ) 0xe000e018 ) )\r
 #define portNVIC_SYSPRI2_REG                                   ( *     ( ( volatile uint32_t * ) 0xe000ed20 ) )\r
 #define portNVIC_SYSPRI1_REG                                   ( * ( ( volatile uint32_t * ) 0xe000ed1c ) )\r
 #define portNVIC_SYS_CTRL_STATE_REG                            ( * ( ( volatile uint32_t * ) 0xe000ed24 ) )\r
@@ -206,7 +207,7 @@ static void vPortEnableVFP( void );
  * Utility function.\r
  */\r
 static uint32_t prvPortGetIPSR( void );\r
-       \r
+\r
 /*\r
  * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure\r
  * FreeRTOS API functions are not called from interrupts that have been assigned\r
@@ -297,7 +298,7 @@ uint32_t ulReg;
 __asm void vPortSVCHandler( void )\r
 {\r
        extern prvSVCHandler\r
-               \r
+\r
        PRESERVE8\r
 \r
        /* Assumes psp was in use. */\r
@@ -424,7 +425,7 @@ BaseType_t xPortStartScheduler( void )
 __asm void prvStartFirstTask( void )\r
 {\r
        PRESERVE8\r
-       \r
+\r
        ldr r0, =0xE000ED08     /* Use the NVIC offset register to locate the stack. */\r
        ldr r0, [r0]\r
        ldr r0, [r0]\r
@@ -491,6 +492,7 @@ __asm void xPortPendSVHandler( void )
        mrs r1, control\r
        stmdb r0!, {r1, r4-r11, r14}    /* Save the remaining registers. */\r
        str r0, [r2]                                    /* Save the new top of stack into the first member of the TCB. */\r
+       clrex                                                   /* Ensure thread safety of atomic operations. */\r
 \r
        stmdb sp!, {r3}\r
        mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
@@ -544,6 +546,10 @@ uint32_t ulDummy;
  */\r
 static void prvSetupTimerInterrupt( void )\r
 {\r
+       /* Reset the SysTick. */\r
+       portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+       portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
        /* Configure SysTick to interrupt at the requested rate. */\r
        portNVIC_SYSTICK_LOAD_REG = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
        portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
@@ -553,18 +559,18 @@ static void prvSetupTimerInterrupt( void )
 __asm void vPortSwitchToUserMode( void )\r
 {\r
        PRESERVE8\r
-       \r
+\r
        mrs r0, control\r
        orr r0, #1\r
        msr control, r0\r
        bx r14\r
 }\r
 /*-----------------------------------------------------------*/\r
-       \r
+\r
 __asm void vPortEnableVFP( void )\r
 {\r
        PRESERVE8\r
-       \r
+\r
        ldr.w r0, =0xE000ED88           /* The FPU enable bits are in the CPACR. */\r
        ldr r1, [r0]\r
 \r
@@ -682,7 +688,7 @@ extern uint32_t __SRAM_segment_end__;
 extern uint32_t __privileged_data_start__;\r
 extern uint32_t __privileged_data_end__;\r
 \r
-       \r
+\r
 int32_t lIndex;\r
 uint32_t ul;\r
 \r
index ef34402f689f7058b1802eabd226bbbbddbe259d..9f0dc3330ebd8076db67ee36f8bdc20604105d31 100644 (file)
@@ -463,6 +463,9 @@ __asm void xPortPendSVHandler( void )
        /* Save the new top of stack into the first member of the TCB. */\r
        str r0, [r2]\r
 \r
+       /* Ensure thread safety of atomic operations. */\r
+       clrex\r
+\r
        stmdb sp!, {r3}\r
        mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
        cpsid i\r
@@ -695,6 +698,10 @@ void xPortSysTickHandler( void )
                }\r
                #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+               /* Stop and clear the SysTick. */\r
+               portNVIC_SYSTICK_CTRL_REG = 0UL;\r
+               portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
+\r
                /* Configure SysTick to interrupt at the requested rate. */\r
                portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
                portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
index 8aea1cd9155284522fbdf8c3100fcd02093a0c3b..d2d7b1159e4f3e806c50cdaa784582e73a20a6b5 100644 (file)
@@ -1901,7 +1901,10 @@ BaseType_t xReturn;
 \r
                /* If configGENERATE_RUN_TIME_STATS is defined then the following\r
                macro must be defined to configure the timer/counter used to generate\r
-               the run time counter time base. */\r
+               the run time counter time base.   NOTE:  If configGENERATE_RUN_TIME_STATS\r
+               is set to 0 and the following line fails to build then ensure you do not\r
+               have portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() defined in your\r
+               FreeRTOSConfig.h file. */\r
                portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();\r
 \r
                /* Setting up the timer tick is hardware specific and thus in the\r