]> begriffs open source - freertos/blob - Source/portable/IAR/ARM_CM3/port.c
Updated version numbers to V4.1.3.
[freertos] / Source / portable / IAR / ARM_CM3 / port.c
1 /*\r
2         FreeRTOS.org V4.1.3 - Copyright (C) 2003-2006 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section \r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26         ***************************************************************************\r
27         See http://www.FreeRTOS.org for documentation, latest information, license \r
28         and contact details.  Please ensure to read the configuration and relevant \r
29         port sections of the online documentation.\r
30         ***************************************************************************\r
31 */\r
32 \r
33 \r
34 /*-----------------------------------------------------------\r
35  * Implementation of functions defined in portable.h for the ARM CM3 port.\r
36  *----------------------------------------------------------*/\r
37 \r
38 /* Scheduler includes. */\r
39 #include "FreeRTOS.h"\r
40 #include "task.h"\r
41 \r
42 /* Constants required to manipulate the NVIC. */\r
43 #define portNVIC_SYSTICK_CTRL           ( ( volatile unsigned portLONG *) 0xe000e010 )\r
44 #define portNVIC_SYSTICK_LOAD           ( ( volatile unsigned portLONG *) 0xe000e014 )\r
45 #define portNVIC_INT_CTRL                       ( ( volatile unsigned portLONG *) 0xe000ed04 )\r
46 #define portNVIC_SYSPRI2                        ( ( volatile unsigned portLONG *) 0xe000ed20 )\r
47 #define portNVIC_SYSPRI1                        ( ( volatile unsigned portLONG *) 0xe000ed1c )\r
48 #define portNVIC_SYSTICK_CLK            0x00000004\r
49 #define portNVIC_SYSTICK_INT            0x00000002\r
50 #define portNVIC_SYSTICK_ENABLE         0x00000001\r
51 #define portNVIC_PENDSVSET                      0x10000000\r
52 #define portNVIC_PENDSV_PRI                     0x00ff0000\r
53 #define portNVIC_SVCALL_PRI                     0xff000000\r
54 #define portNVIC_SYSTICK_PRI            0xff000000\r
55 \r
56 /* Constants required to set up the initial stack. */\r
57 #define portINITIAL_XPSR                        ( 0x01000000 )\r
58 \r
59 /* Each task maintains its own interrupt status in the critical nesting\r
60 variable. */\r
61 unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;\r
62 \r
63 /* \r
64  * Setup the timer to generate the tick interrupts.\r
65  */\r
66 static void prvSetupTimerInterrupt( void );\r
67 \r
68 /*\r
69  * Set the MSP/PSP to a known value.\r
70  */\r
71 extern void vSetMSP( unsigned long ulValue );\r
72 extern void vSetPSP( unsigned long ulValue );\r
73 \r
74 /*-----------------------------------------------------------*/\r
75 \r
76 /* \r
77  * See header file for description. \r
78  */\r
79 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
80 {\r
81         /* Simulate the stack frame as it would be created by a context switch\r
82         interrupt. */\r
83         *pxTopOfStack = portINITIAL_XPSR;       /* xPSR */\r
84         pxTopOfStack--;\r
85         *pxTopOfStack = ( portSTACK_TYPE ) pxCode;      /* PC */\r
86         pxTopOfStack--;\r
87         *pxTopOfStack = 0xfffffffd;     /* LR */\r
88         pxTopOfStack -= 5;      /* R12, R3, R2 and R1. */\r
89         *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;        /* R0 */\r
90         pxTopOfStack -= 9;      /* R11, R10, R9, R8, R7, R6, R5 and R4. */\r
91         *pxTopOfStack = 0x00000000; /* uxCriticalNesting. */\r
92 \r
93         return pxTopOfStack;\r
94 }\r
95 /*-----------------------------------------------------------*/\r
96 \r
97 /* \r
98  * See header file for description. \r
99  */\r
100 portBASE_TYPE xPortStartScheduler( void )\r
101 {\r
102         /* Make PendSV, CallSV and SysTick the lowest priority interrupts. */\r
103         *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;\r
104         *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;\r
105 \r
106         /* Start the timer that generates the tick ISR.  Interrupts are disabled\r
107         here already. */\r
108         prvSetupTimerInterrupt();\r
109         \r
110         /* Start the first task. */\r
111         vSetPSP( 0 );\r
112         vSetMSP( *((unsigned portLONG *) 0 ) );\r
113         *(portNVIC_INT_CTRL) |= portNVIC_PENDSVSET;\r
114 \r
115         /* Enable interrupts */\r
116         portENABLE_INTERRUPTS();\r
117 \r
118         /* Should not get here! */\r
119         return 0;\r
120 }\r
121 /*-----------------------------------------------------------*/\r
122 \r
123 void vPortEndScheduler( void )\r
124 {\r
125         /* It is unlikely that the CM3 port will require this function as there\r
126         is nothing to return to.  */\r
127 }\r
128 /*-----------------------------------------------------------*/\r
129 \r
130 void vPortYieldFromISR( void )\r
131 {\r
132         /* Set a PendSV to request a context switch. */\r
133         *(portNVIC_INT_CTRL) |= portNVIC_PENDSVSET;\r
134 \r
135         /* This function is also called in response to a Yield(), so we want\r
136         the yield to occur immediately. */\r
137         portENABLE_INTERRUPTS();\r
138 }\r
139 /*-----------------------------------------------------------*/\r
140 \r
141 void vPortEnterCritical( void )\r
142 {\r
143         portDISABLE_INTERRUPTS();\r
144         uxCriticalNesting++;\r
145 }\r
146 /*-----------------------------------------------------------*/\r
147 \r
148 void vPortExitCritical( void )\r
149 {\r
150         uxCriticalNesting--;\r
151         if( uxCriticalNesting == 0 )\r
152         {\r
153                 portENABLE_INTERRUPTS();\r
154         }\r
155 }\r
156 /*-----------------------------------------------------------*/\r
157 \r
158 \r
159 /*\r
160  * Setup the systick timer to generate the tick interrupts at the required\r
161  * frequency.\r
162  */\r
163 void prvSetupTimerInterrupt( void )\r
164 {\r
165         /* Configure SysTick to interrupt at the requested rate. */\r
166         *(portNVIC_SYSTICK_LOAD) = configCPU_CLOCK_HZ / configTICK_RATE_HZ;\r
167         *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
168 }\r
169 \r
170 \r