]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
Update Cortex-M3 and Cortex-M4F ports to allow the SysTick to be clocked at a differe...
[freertos] / FreeRTOS / Source / portable / GCC / ARM_CM4F / port.c
index c009b4bce9ea6a2233601871fd16db55eb2ec3fa..98c301ba70bf52ab1743e008b3d0cb4a5e312e36 100644 (file)
@@ -256,6 +256,7 @@ void vPortSVCHandler( void )
                                        "       ldr r0, [r1]                                    \n" /* The first item in pxCurrentTCB is the task top of stack. */\r
                                        "       ldmia r0!, {r4-r11, r14}                \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */\r
                                        "       msr psp, r0                                             \n" /* Restore the task stack pointer. */\r
+                                       "       isb                                                             \n"\r
                                        "       mov r0, #0                                              \n"\r
                                        "       msr     basepri, r0                                     \n"\r
                                        "       bx r14                                                  \n"\r
@@ -274,6 +275,8 @@ static void prvPortStartFirstTask( void )
                                        " ldr r0, [r0]                  \n"\r
                                        " msr msp, r0                   \n" /* Set the msp back to the start of the stack. */\r
                                        " cpsie i                               \n" /* Globally enable interrupts. */\r
+                                       " dsb                                   \n"\r
+                                       " isb                                   \n"\r
                                        " svc 0                                 \n" /* System call to start first task. */\r
                                        " nop                                   \n"\r
                                );\r
@@ -366,8 +369,9 @@ portBASE_TYPE xPortStartScheduler( void )
 \r
 void vPortEndScheduler( void )\r
 {\r
-       /* It is unlikely that the CM4F port will require this function as there\r
-       is nothing to return to.  */\r
+       /* Not implemented in ports where there is nothing to return to.\r
+       Artificially force an assert. */\r
+       configASSERT( uxCriticalNesting == 1000UL );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -394,6 +398,7 @@ void vPortEnterCritical( void )
 \r
 void vPortExitCritical( void )\r
 {\r
+       configASSERT( uxCriticalNesting );\r
        uxCriticalNesting--;\r
        if( uxCriticalNesting == 0 )\r
        {\r
@@ -440,6 +445,7 @@ void xPortPendSVHandler( void )
        __asm volatile\r
        (\r
        "       mrs r0, psp                                                     \n"\r
+       "       isb                                                                     \n"\r
        "                                                                               \n"\r
        "       ldr     r3, pxCurrentTCBConst                   \n" /* Get the location of the current TCB. */\r
        "       ldr     r2, [r3]                                                \n"\r
@@ -470,6 +476,7 @@ void xPortPendSVHandler( void )
        "       vldmiaeq r0!, {s16-s31}                         \n"\r
        "                                                                               \n"\r
        "       msr psp, r0                                                     \n"\r
+       "       isb                                                                     \n"\r
        "                                                                               \n"\r
        #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */\r
                #if WORKAROUND_PMU_CM001 == 1\r
@@ -511,7 +518,7 @@ void xPortSysTickHandler( void )
 \r
        __attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )\r
        {\r
-       unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;\r
+       unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;\r
        portTickType xModifiableIdleTime;\r
 \r
                /* Make sure the SysTick reload value does not overflow the counter. */\r
@@ -524,7 +531,7 @@ void xPortSysTickHandler( void )
                is accounted for as best it can be, but using the tickless mode will\r
                inevitably result in some tiny drift of the time maintained by the\r
                kernel with respect to calendar time. */\r
-               portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;\r
+               portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;\r
 \r
                /* Calculate the reload value required to wait xExpectedIdleTime\r
                tick periods.  -1 is used because this code will execute part way\r
@@ -548,7 +555,7 @@ void xPortSysTickHandler( void )
                        portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;\r
 \r
                        /* Restart SysTick. */\r
-                       portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;\r
+                       portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;\r
 \r
                        /* Reset the reload register to the value required for normal tick\r
                        periods. */\r
@@ -568,7 +575,7 @@ void xPortSysTickHandler( void )
                        portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
 \r
                        /* Restart SysTick. */\r
-                       portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;\r
+                       portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;\r
 \r
                        /* Sleep until something happens.  configPRE_SLEEP_PROCESSING() can\r
                        set its parameter to 0 to indicate that its implementation contains\r
@@ -589,13 +596,14 @@ void xPortSysTickHandler( void )
                        accounted for as best it can be, but using the tickless mode will\r
                        inevitably result in some tiny drift of the time maintained by the\r
                        kernel with respect to calendar time. */\r
-                       portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;\r
+                       ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;\r
+                       portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );\r
 \r
                        /* Re-enable interrupts - see comments above the cpsid instruction()\r
                        above. */\r
                        __asm volatile( "cpsie i" );\r
 \r
-                       if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
+                       if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
                        {\r
                                unsigned long ulCalculatedLoadValue;\r
 \r
@@ -647,7 +655,7 @@ void xPortSysTickHandler( void )
                        portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;\r
                        portENTER_CRITICAL();\r
                        {\r
-                               portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;\r
+                               portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;\r
                                vTaskStepTick( ulCompleteTickPeriods );\r
                                portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;\r
                        }\r
@@ -675,7 +683,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
 \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
+       portNVIC_SYSTICK_CTRL_REG |= ( portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r