2 FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
\r
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 This file is part of the FreeRTOS distribution.
\r
9 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
10 the terms of the GNU General Public License (version 2) as published by the
\r
11 Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
\r
13 ***************************************************************************
\r
14 >>! NOTE: The modification to the GPL is included to allow you to !<<
\r
15 >>! distribute a combined work that includes FreeRTOS without being !<<
\r
16 >>! obliged to provide the source code for proprietary components !<<
\r
17 >>! outside of the FreeRTOS kernel. !<<
\r
18 ***************************************************************************
\r
20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
\r
23 link: http://www.freertos.org/a00114.html
\r
25 ***************************************************************************
\r
27 * FreeRTOS provides completely free yet professionally developed, *
\r
28 * robust, strictly quality controlled, supported, and cross *
\r
29 * platform software that is more than just the market leader, it *
\r
30 * is the industry's de facto standard. *
\r
32 * Help yourself get started quickly while simultaneously helping *
\r
33 * to support the FreeRTOS project by purchasing a FreeRTOS *
\r
34 * tutorial book, reference manual, or both: *
\r
35 * http://www.FreeRTOS.org/Documentation *
\r
37 ***************************************************************************
\r
39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
\r
40 the FAQ page "My application does not run, what could be wrong?". Have you
\r
41 defined configASSERT()?
\r
43 http://www.FreeRTOS.org/support - In return for receiving this top quality
\r
44 embedded software for free we request you assist our global community by
\r
45 participating in the support forum.
\r
47 http://www.FreeRTOS.org/training - Investing in training allows your team to
\r
48 be as productive as possible as early as possible. Now you can receive
\r
49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
\r
50 Ltd, and the world's leading authority on the world's leading RTOS.
\r
52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
\r
54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
\r
56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
\r
57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
\r
59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
\r
60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
\r
61 licenses offer ticketed support, indemnification and commercial middleware.
\r
63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
\r
64 engineered and independently SIL3 certified version for use in safety and
\r
65 mission critical applications that require provable dependability.
\r
71 #include "FreeRTOSConfig.h"
\r
72 #include "ISR_Support.h"
\r
74 .extern pxCurrentTCB
\r
75 .extern vTaskSwitchContext
\r
76 .extern vPortCentralInterruptHandler
\r
77 .extern xTaskIncrementTick
\r
78 .extern vPortAPICErrorHandler
\r
79 .extern pucPortTaskFPUContextBuffer
\r
80 .extern ulPortYieldPending
\r
82 .global vPortStartFirstTask
\r
83 .global vPortCentralInterruptWrapper
\r
84 .global vPortAPICErrorHandlerWrapper
\r
85 .global vPortTimerHandler
\r
86 .global vPortYieldCall
\r
87 .global vPortAPICSpuriousHandler
\r
91 /*-----------------------------------------------------------*/
\r
94 .func vPortYieldCall
\r
96 /* Save general purpose registers. */
\r
99 .if configSUPPORT_FPU == 1
\r
101 /* If the task has a buffer allocated to save the FPU context then save
\r
102 the FPU context now. */
\r
103 movl pucPortTaskFPUContextBuffer, %eax
\r
111 /* Save the address of the FPU context, if any. */
\r
112 push pucPortTaskFPUContextBuffer
\r
114 .endif /* configSUPPORT_FPU */
\r
116 /* Find the TCB. */
\r
117 movl pxCurrentTCB, %eax
\r
119 /* Stack location is first item in the TCB. */
\r
122 call vTaskSwitchContext
\r
124 /* Find the location of pxCurrentTCB again - a callee saved register could
\r
125 be used in place of eax to prevent this second load, but that then relies
\r
126 on the compiler and other asm code. */
\r
127 movl pxCurrentTCB, %eax
\r
130 .if configSUPPORT_FPU == 1
\r
132 /* Restore address of task's FPU context buffer. */
\r
133 pop pucPortTaskFPUContextBuffer
\r
135 /* If the task has a buffer allocated in which its FPU context is saved,
\r
136 then restore it now. */
\r
137 movl pucPortTaskFPUContextBuffer, %eax
\r
148 /*-----------------------------------------------------------*/
\r
151 .func vPortStartFirstTask
\r
152 vPortStartFirstTask:
\r
154 /* Find the TCB. */
\r
155 movl pxCurrentTCB, %eax
\r
157 /* Stack location is first item in the TCB. */
\r
160 /* Restore FPU context flag. */
\r
161 .if configSUPPORT_FPU == 1
\r
163 pop pucPortTaskFPUContextBuffer
\r
165 .endif /* configSUPPORT_FPU */
\r
167 /* Restore general purpose registers. */
\r
171 /*-----------------------------------------------------------*/
\r
174 .func vPortAPICErrorHandlerWrapper
\r
175 vPortAPICErrorHandlerWrapper:
\r
177 call vPortAPICErrorHandler
\r
180 movl $0x00, (0xFEE000B0)
\r
183 /*-----------------------------------------------------------*/
\r
186 .func vPortTimerHandler
\r
189 /* Save general purpose registers. */
\r
192 /* Interrupts are not nested, so save the rest of the task context. */
\r
193 .if configSUPPORT_FPU == 1
\r
195 /* If the task has a buffer allocated to save the FPU context then save the
\r
196 FPU context now. */
\r
197 movl pucPortTaskFPUContextBuffer, %eax
\r
200 fnsave ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */
\r
204 /* Save the address of the FPU context, if any. */
\r
205 push pucPortTaskFPUContextBuffer
\r
207 .endif /* configSUPPORT_FPU */
\r
209 /* Find the TCB. */
\r
210 movl pxCurrentTCB, %eax
\r
212 /* Stack location is first item in the TCB. */
\r
215 /* Switch stacks. */
\r
216 movl ulTopOfSystemStack, %esp
\r
219 /* Increment nesting count. */
\r
220 add $1, ulInterruptNesting
\r
222 call xTaskIncrementTick
\r
226 /* Is a switch to another task required? */
\r
228 je _skip_context_switch
\r
230 call vTaskSwitchContext
\r
232 _skip_context_switch:
\r
235 /* Decrement the variable used to determine if a switch to a system
\r
236 stack is necessary. */
\r
237 sub $1, ulInterruptNesting
\r
239 /* Stack location is first item in the TCB. */
\r
240 movl pxCurrentTCB, %eax
\r
243 .if configSUPPORT_FPU == 1
\r
245 /* Restore address of task's FPU context buffer. */
\r
246 pop pucPortTaskFPUContextBuffer
\r
248 /* If the task has a buffer allocated in which its FPU context is saved,
\r
249 then restore it now. */
\r
250 movl pucPortTaskFPUContextBuffer, %eax
\r
260 movl $0x00, (0xFEE000B0)
\r
264 /*-----------------------------------------------------------*/
\r
266 .if configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1
\r
269 .func vPortCentralInterruptWrapper
\r
270 vPortCentralInterruptWrapper:
\r
272 portFREERTOS_INTERRUPT_ENTRY
\r
274 movl $0xFEE00170, %eax /* Highest In Service Register (ISR) long word. */
\r
275 movl $8, %ecx /* Loop counter. */
\r
277 next_isr_long_word:
\r
278 test %ecx, %ecx /* Loop counter reached 0? */
\r
279 je wrapper_epilogue /* Looked at all ISR registers without finding a bit set. */
\r
280 sub $1, %ecx /* Sub 1 from loop counter. */
\r
281 movl (%eax), %ebx /* Load next ISR long word. */
\r
282 sub $0x10, %eax /* Point to next ISR long word in case no bits are set in the current long word. */
\r
283 test %ebx, %ebx /* Are there any bits set? */
\r
284 je next_isr_long_word /* Look at next ISR long word if no bits were set. */
\r
286 bsr %ebx, %ebx /* A bit was set, which one? */
\r
287 movl $32, %eax /* Destination operand for following multiplication. */
\r
288 mul %ecx /* Calculate base vector for current register, 32 vectors per register. */
\r
289 add %ebx, %eax /* Add bit offset into register to get final vector number. */
\r
290 push %eax /* Vector number is function parameter. */
\r
291 call vPortCentralInterruptHandler
\r
292 pop %eax /* Remove parameter. */
\r
295 portFREERTOS_INTERRUPT_EXIT
\r
299 .endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
\r
300 /*-----------------------------------------------------------*/
\r
303 .func vPortAPISpuriousHandler
\r
304 vPortAPICSpuriousHandler:
\r