]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/portable/IAR/ARM_CM3/port.c
Make CM3/4 tick configuration a weak function to allow application writers to use...
[freertos] / FreeRTOS / Source / portable / IAR / ARM_CM3 / port.c
index 2601d50350453ccef6efb6e4c3852c5f034621e0..c501e72594bbe98c44b8a28ad99bbf4838164d46 100644 (file)
@@ -1,7 +1,7 @@
 /*\r
     FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
 \r
-    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT \r
+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT\r
     http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
 \r
     ***************************************************************************\r
@@ -42,7 +42,7 @@
     FreeRTOS WEB site.\r
 \r
     1 tab == 4 spaces!\r
-    \r
+\r
     ***************************************************************************\r
      *                                                                       *\r
      *    Having a problem?  Start by reading the FAQ "My application does   *\r
      *                                                                       *\r
     ***************************************************************************\r
 \r
-    \r
-    http://www.FreeRTOS.org - Documentation, training, latest versions, license \r
-    and contact details.  \r
-    \r
+\r
+    http://www.FreeRTOS.org - Documentation, training, latest versions, license\r
+    and contact details.\r
+\r
     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
     including FreeRTOS+Trace - an indispensable productivity tool.\r
 \r
-    Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
-    the code with commercial support, indemnification, and middleware, under \r
+    Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+    the code with commercial support, indemnification, and middleware, under\r
     the OpenRTOS brand: http://www.OpenRTOS.com.  High Integrity Systems also\r
-    provide a safety engineered and independently SIL3 certified version under \r
+    provide a safety engineered and independently SIL3 certified version under\r
     the SafeRTOS brand: http://www.SafeRTOS.com.\r
 */\r
 \r
@@ -70,6 +70,9 @@
  * Implementation of functions defined in portable.h for the ARM CM3 port.\r
  *----------------------------------------------------------*/\r
 \r
+/* IAR includes. */\r
+#include <intrinsics.h>\r
+\r
 /* Scheduler includes. */\r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
 \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
 /* Constants required to manipulate the core.  Registers first... */\r
 #define portNVIC_SYSTICK_CTRL_REG                      ( * ( ( volatile unsigned long * ) 0xe000e010 ) )\r
@@ -123,9 +118,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
@@ -142,7 +139,9 @@ extern void vPortStartFirstTask( 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
@@ -152,6 +151,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
@@ -186,7 +193,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
@@ -237,6 +244,10 @@ void xPortSysTickHandler( void )
                portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\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
@@ -300,9 +311,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
@@ -357,16 +371,19 @@ void xPortSysTickHandler( void )
  * Setup the systick timer to generate the tick interrupts at the required\r
  * frequency.\r
  */\r
-void prvSetupTimerInterrupt( void )\r
+__weak void vPortSetupTimerInterrupt( void )\r
 {\r
-       /* Configure the constants required to setup the tick interrupt. */\r
-       ulTimerReloadValueForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\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 = ulTimerReloadValueForOneTick;\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