]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c
Make CM3/4 tick configuration a weak function to allow application writers to use...
[freertos] / FreeRTOS / Source / portable / RVDS / ARM_CM3 / port.c
index 5c3a5534ecfa10a96d53d963c66cd3369246a863..be3d8e64331d99a665e20a4b0bffbafc8e512372 100644 (file)
 \r
 #ifndef configSYSTICK_CLOCK_HZ\r
        #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ\r
-       #if configUSE_TICKLESS_IDLE == 1\r
-               static const unsigned long ulStoppedTimerCompensation = 45UL;\r
-       #endif\r
-#else /* configSYSTICK_CLOCK_HZ */\r
-       #if configUSE_TICKLESS_IDLE == 1\r
-               /* Assumes the SysTick clock is slower than the CPU clock. */\r
-               static const unsigned long ulStoppedTimerCompensation = 45UL / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );\r
-       #endif\r
-#endif /* configSYSTICK_CLOCK_HZ */\r
+#endif\r
+\r
+/* The __weak attribute does not work as you might expect with the Keil tools\r
+so the configOVERRIDE_DEFAULT_TICK_CONFIGURATION constant must be set to 1 if\r
+the application writer wants to provide their own implementation of \r
+vPortSetupTimerInterrupt().  Ensure configOVERRIDE_DEFAULT_TICK_CONFIGURATION\r
+is defined. */\r
+#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION\r
+       #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0\r
+#endif\r
 \r
 /* Constants required to manipulate the core.  Registers first... */\r
 #define portNVIC_SYSTICK_CTRL_REG                      ( * ( ( volatile unsigned long * ) 0xe000e010 ) )\r
@@ -120,9 +121,11 @@ variable. */
 static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;\r
 \r
 /*\r
- * Setup the timer to generate the tick interrupts.\r
+ * Setup the timer to generate the tick interrupts.  The implementation in this\r
+ * file is weak to allow application writers to change the timer used to \r
+ * generate the tick interrupt.\r
  */\r
-static void prvSetupTimerInterrupt( void );\r
+void vPortSetupTimerInterrupt( void );\r
 \r
 /*\r
  * Exception handlers.\r
@@ -141,7 +144,9 @@ static void prvStartFirstTask( void );
 /*\r
  * The number of SysTick increments that make up one tick period.\r
  */\r
-static unsigned long ulTimerReloadValueForOneTick = 0;\r
+#if configUSE_TICKLESS_IDLE == 1\r
+       static unsigned long ulTimerReloadValueForOneTick = 0;\r
+#endif\r
 \r
 /*\r
  * The maximum number of tick periods that can be suppressed is limited by the\r
@@ -151,6 +156,14 @@ static unsigned long ulTimerReloadValueForOneTick = 0;
        static unsigned long xMaximumPossibleSuppressedTicks = 0;\r
 #endif /* configUSE_TICKLESS_IDLE */\r
 \r
+/*\r
+ * Compensate for the CPU cycles that pass while the SysTick is stopped (low\r
+ * power functionality only.\r
+ */\r
+#if configUSE_TICKLESS_IDLE == 1\r
+       static unsigned long ulStoppedTimerCompensation = 0;\r
+#endif /* configUSE_TICKLESS_IDLE */\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -219,7 +232,7 @@ portBASE_TYPE xPortStartScheduler( void )
 \r
        /* Start the timer that generates the tick ISR.  Interrupts are disabled\r
        here already. */\r
-       prvSetupTimerInterrupt();\r
+       vPortSetupTimerInterrupt();\r
 \r
        /* Initialise the critical nesting count ready for the first task. */\r
        uxCriticalNesting = 0;\r
@@ -305,6 +318,10 @@ void xPortSysTickHandler( void )
        }\r
        #endif\r
 \r
+       /* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to\r
+       1.  If it is set to 0 tickless idle is not being used.  If it is set to a \r
+       value other than 0 or 1 then a timer other than the SysTick is being used\r
+       to generate the tick interrupt. */\r
        #if configUSE_TICKLESS_IDLE == 1\r
                portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;\r
        #endif\r
@@ -368,9 +385,12 @@ void xPortSysTickHandler( void )
                        portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;\r
 \r
                        /* Sleep until something happens. */\r
-                       configPRE_SLEEP_PROCESSING();\r
-                       __wfi();\r
-                       configPOST_SLEEP_PROCESSING();\r
+                       configPRE_SLEEP_PROCESSING( xExpectedIdleTime );\r
+                       if( xExpectedIdleTime > 0 )\r
+                       {\r
+                               __wfi();\r
+                       }\r
+                       configPOST_SLEEP_PROCESSING( xExpectedIdleTime );\r
 \r
                        /* Stop SysTick.  Again, the time the SysTick is stopped for is\r
                        accounted for as best it can be, but using the tickless mode will\r
@@ -426,18 +446,25 @@ void xPortSysTickHandler( void )
  * Setup the SysTick timer to generate the tick interrupts at the required\r
  * frequency.\r
  */\r
-void prvSetupTimerInterrupt( void )\r
-{\r
-       /* Calculate the constants required to configure the tick interrupt. */\r
-       ulTimerReloadValueForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
-       #if configUSE_TICKLESS_IDLE == 1\r
-               xMaximumPossibleSuppressedTicks = 0xffffffUL / ( ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );\r
-       #endif /* configUSE_TICKLESS_IDLE */\r
+#if configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0\r
 \r
-       /* Configure SysTick to interrupt at the requested rate. */\r
-       portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;\r
-       portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;\r
-}\r
+       void vPortSetupTimerInterrupt( void )\r
+       {\r
+               /* Calculate the constants required to configure the tick interrupt. */         \r
+               #if configUSE_TICKLESS_IDLE == 1\r
+               {\r
+                       ulTimerReloadValueForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
+                       xMaximumPossibleSuppressedTicks = 0xffffffUL / ( ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );\r
+                       ulStoppedTimerCompensation = 45UL / ( 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
+       \r
+#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */\r
 /*-----------------------------------------------------------*/\r
 \r
 __asm unsigned long ulPortSetInterruptMask( void )\r
@@ -449,7 +476,6 @@ __asm unsigned long ulPortSetInterruptMask( void )
        msr basepri, r1\r
        bx r14\r
 }\r
-\r
 /*-----------------------------------------------------------*/\r
 \r
 __asm void vPortClearInterruptMask( unsigned long ulNewMask )\r