2 FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
\r
5 FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
\r
6 Atollic AB - Atollic provides professional embedded systems development
\r
7 tools for C/C++ development, code analysis and test automation.
\r
8 See http://www.atollic.com
\r
11 ***************************************************************************
\r
13 * FreeRTOS tutorial books are available in pdf and paperback. *
\r
14 * Complete, revised, and edited pdf reference manuals are also *
\r
17 * Purchasing FreeRTOS documentation will not only help you, by *
\r
18 * ensuring you get running as quickly as possible and with an *
\r
19 * in-depth knowledge of how to use FreeRTOS, it will also help *
\r
20 * the FreeRTOS project to continue with its mission of providing *
\r
21 * professional grade, cross platform, de facto standard solutions *
\r
22 * for microcontrollers - completely free of charge! *
\r
24 * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
\r
26 * Thank you for using FreeRTOS, and thank you for your support! *
\r
28 ***************************************************************************
\r
31 This file is part of the FreeRTOS distribution.
\r
33 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
34 the terms of the GNU General Public License (version 2) as published by the
\r
35 Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
\r
36 >>>NOTE<<< The modification to the GPL is included to allow you to
\r
37 distribute a combined work that includes FreeRTOS without being obliged to
\r
38 provide the source code for proprietary components outside of the FreeRTOS
\r
39 kernel. FreeRTOS is distributed in the hope that it will be useful, but
\r
40 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
41 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
42 more details. You should have received a copy of the GNU General Public
\r
43 License and the FreeRTOS license exception along with FreeRTOS; if not it
\r
44 can be viewed here: http://www.freertos.org/a00114.html and also obtained
\r
45 by writing to Richard Barry, contact details for whom are available on the
\r
50 http://www.FreeRTOS.org - Documentation, latest information, license and
\r
53 http://www.SafeRTOS.com - A version that is certified for use in safety
\r
56 http://www.OpenRTOS.com - Commercial support, development, porting,
\r
57 licensing and training services.
\r
60 #include "FreeRTOSConfig.h"
\r
61 #include "xparameters.h"
\r
63 /* The context is oversized to allow functions called from the ISR to write
\r
64 back into the caller stack. */
\r
65 #if XPAR_MICROBLAZE_0_USE_FPU == 1
\r
66 #define portCONTEXT_SIZE 136
\r
68 #define portCONTEXT_SIZE 132
\r
71 /* Offsets from the stack pointer at which saved registers are placed. */
\r
72 #define portR31_OFFSET 4
\r
73 #define portR30_OFFSET 8
\r
74 #define portR29_OFFSET 12
\r
75 #define portR28_OFFSET 16
\r
76 #define portR27_OFFSET 20
\r
77 #define portR26_OFFSET 24
\r
78 #define portR25_OFFSET 28
\r
79 #define portR24_OFFSET 32
\r
80 #define portR23_OFFSET 36
\r
81 #define portR22_OFFSET 40
\r
82 #define portR21_OFFSET 44
\r
83 #define portR20_OFFSET 48
\r
84 #define portR19_OFFSET 52
\r
85 #define portR18_OFFSET 56
\r
86 #define portR17_OFFSET 60
\r
87 #define portR16_OFFSET 64
\r
88 #define portR15_OFFSET 68
\r
89 #define portR14_OFFSET 72
\r
90 #define portR13_OFFSET 76
\r
91 #define portR12_OFFSET 80
\r
92 #define portR11_OFFSET 84
\r
93 #define portR10_OFFSET 88
\r
94 #define portR9_OFFSET 92
\r
95 #define portR8_OFFSET 96
\r
96 #define portR7_OFFSET 100
\r
97 #define portR6_OFFSET 104
\r
98 #define portR5_OFFSET 108
\r
99 #define portR4_OFFSET 112
\r
100 #define portR3_OFFSET 116
\r
101 #define portR2_OFFSET 120
\r
102 #define portCRITICAL_NESTING_OFFSET 124
\r
103 #define portMSR_OFFSET 128
\r
104 #define portFSR_OFFSET 132
\r
106 .extern pxCurrentTCB
\r
107 .extern XIntc_DeviceInterruptHandler
\r
108 .extern vTaskSwitchContext
\r
109 .extern uxCriticalNesting
\r
110 .extern pulISRStack
\r
112 .global _interrupt_handler
\r
113 .global VPortYieldASM
\r
114 .global vPortStartFirstTask
\r
117 .macro portSAVE_CONTEXT
\r
119 /* Make room for the context on the stack. */
\r
120 addik r1, r1, -portCONTEXT_SIZE
\r
122 /* Stack general registers. */
\r
123 swi r31, r1, portR31_OFFSET
\r
124 swi r30, r1, portR30_OFFSET
\r
125 swi r29, r1, portR29_OFFSET
\r
126 swi r28, r1, portR28_OFFSET
\r
127 swi r27, r1, portR27_OFFSET
\r
128 swi r26, r1, portR26_OFFSET
\r
129 swi r25, r1, portR25_OFFSET
\r
130 swi r24, r1, portR24_OFFSET
\r
131 swi r23, r1, portR23_OFFSET
\r
132 swi r22, r1, portR22_OFFSET
\r
133 swi r21, r1, portR21_OFFSET
\r
134 swi r20, r1, portR20_OFFSET
\r
135 swi r19, r1, portR19_OFFSET
\r
136 swi r18, r1, portR18_OFFSET
\r
137 swi r17, r1, portR17_OFFSET
\r
138 swi r16, r1, portR16_OFFSET
\r
139 swi r15, r1, portR15_OFFSET
\r
140 /* R14 is saved later as it needs adjustment if a yield is performed. */
\r
141 swi r13, r1, portR13_OFFSET
\r
142 swi r12, r1, portR12_OFFSET
\r
143 swi r11, r1, portR11_OFFSET
\r
144 swi r10, r1, portR10_OFFSET
\r
145 swi r9, r1, portR9_OFFSET
\r
146 swi r8, r1, portR8_OFFSET
\r
147 swi r7, r1, portR7_OFFSET
\r
148 swi r6, r1, portR6_OFFSET
\r
149 swi r5, r1, portR5_OFFSET
\r
150 swi r4, r1, portR4_OFFSET
\r
151 swi r3, r1, portR3_OFFSET
\r
152 swi r2, r1, portR2_OFFSET
\r
154 /* Stack the critical section nesting value. */
\r
155 lwi r18, r0, uxCriticalNesting
\r
156 swi r18, r1, portCRITICAL_NESTING_OFFSET
\r
160 swi r18, r1, portMSR_OFFSET
\r
162 #if XPAR_MICROBLAZE_0_USE_FPU == 1
\r
165 swi r18, r1, portFSR_OFFSET
\r
168 /* Save the top of stack value to the TCB. */
\r
169 lwi r3, r0, pxCurrentTCB
\r
174 .macro portRESTORE_CONTEXT
\r
176 /* Load the top of stack value from the TCB. */
\r
177 lwi r18, r0, pxCurrentTCB
\r
180 /* Restore the general registers. */
\r
181 lwi r31, r1, portR31_OFFSET
\r
182 lwi r30, r1, portR30_OFFSET
\r
183 lwi r29, r1, portR29_OFFSET
\r
184 lwi r28, r1, portR28_OFFSET
\r
185 lwi r27, r1, portR27_OFFSET
\r
186 lwi r26, r1, portR26_OFFSET
\r
187 lwi r25, r1, portR25_OFFSET
\r
188 lwi r24, r1, portR24_OFFSET
\r
189 lwi r23, r1, portR23_OFFSET
\r
190 lwi r22, r1, portR22_OFFSET
\r
191 lwi r21, r1, portR21_OFFSET
\r
192 lwi r20, r1, portR20_OFFSET
\r
193 lwi r19, r1, portR19_OFFSET
\r
194 lwi r17, r1, portR17_OFFSET
\r
195 lwi r16, r1, portR16_OFFSET
\r
196 lwi r15, r1, portR15_OFFSET
\r
197 lwi r14, r1, portR14_OFFSET
\r
198 lwi r13, r1, portR13_OFFSET
\r
199 lwi r12, r1, portR12_OFFSET
\r
200 lwi r11, r1, portR11_OFFSET
\r
201 lwi r10, r1, portR10_OFFSET
\r
202 lwi r9, r1, portR9_OFFSET
\r
203 lwi r8, r1, portR8_OFFSET
\r
204 lwi r7, r1, portR7_OFFSET
\r
205 lwi r6, r1, portR6_OFFSET
\r
206 lwi r5, r1, portR5_OFFSET
\r
207 lwi r4, r1, portR4_OFFSET
\r
208 lwi r3, r1, portR3_OFFSET
\r
209 lwi r2, r1, portR2_OFFSET
\r
211 /* Reload the rmsr from the stack. */
\r
212 lwi r18, r1, portMSR_OFFSET
\r
215 #if XPAR_MICROBLAZE_0_USE_FPU == 1
\r
216 /* Reload the FSR from the stack. */
\r
217 lwi r18, r1, portFSR_OFFSET
\r
221 /* Load the critical nesting value. */
\r
222 lwi r18, r1, portCRITICAL_NESTING_OFFSET
\r
223 swi r18, r0, uxCriticalNesting
\r
225 /* Test the critical nesting value. If it is non zero then the task last
\r
226 exited the running state using a yield. If it is zero, then the task
\r
227 last exited the running state through an interrupt. */
\r
229 bnei r18, exit_from_yield
\r
231 /* r18 was being used as a temporary. Now restore its true value from the
\r
233 lwi r18, r1, portR18_OFFSET
\r
235 /* Remove the stack frame. */
\r
236 addik r1, r1, portCONTEXT_SIZE
\r
238 /* Return using rtid so interrupts are re-enabled as this function is
\r
245 /* This function is used to exit portRESTORE_CONTEXT() if the task being
\r
246 returned to last left the Running state by calling taskYIELD() (rather than
\r
247 being preempted by an interrupt. */
\r
252 /* r18 was being used as a temporary. Now restore its true value from the
\r
254 lwi r18, r1, portR18_OFFSET
\r
256 /* Remove the stack frame. */
\r
257 addik r1, r1, portCONTEXT_SIZE
\r
259 /* Return to the task. */
\r
266 _interrupt_handler:
\r
270 /* Stack the return address. */
\r
271 swi r14, r1, portR14_OFFSET
\r
273 /* Switch to the ISR stack. The pulISRStack value has already been set to
\r
274 leave space for the caller function to write back into the stack of this
\r
276 lwi r1, r0, pulISRStack
\r
278 /* The parameter to the interrupt handler. */
\r
279 ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE
\r
281 /* Execute any pending interrupts. */
\r
282 bralid r15, XIntc_DeviceInterruptHandler
\r
285 /* Restore the context of the next task scheduled to execute. */
\r
286 portRESTORE_CONTEXT
\r
295 /* Modify the return address so a return is done to the instruction after
\r
296 the call to VPortYieldASM. */
\r
298 swi r14, r1, portR14_OFFSET
\r
300 /* Switch to use the ISR stack. */
\r
301 lwi r1, r0, pulISRStack
\r
303 /* Select the next task to execute. */
\r
304 bralid r15, vTaskSwitchContext
\r
307 /* Restore the context of the next task scheduled to execute. */
\r
308 portRESTORE_CONTEXT
\r
312 vPortStartFirstTask:
\r
314 portRESTORE_CONTEXT
\r