2 FreeRTOS.org V5.1.0 - Copyright (C) 2003-2008 Richard Barry.
\r
4 This file is part of the FreeRTOS.org distribution.
\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
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
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
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
26 ***************************************************************************
\r
27 ***************************************************************************
\r
29 * SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, *
\r
30 * and even write all or part of your application on your behalf. *
\r
31 * See http://www.OpenRTOS.com for details of the services we provide to *
\r
32 * expedite your project. *
\r
34 ***************************************************************************
\r
35 ***************************************************************************
\r
37 Please ensure to read the configuration and relevant port sections of the
\r
38 online documentation.
\r
40 http://www.FreeRTOS.org - Documentation, latest information, license and
\r
43 http://www.SafeRTOS.com - A version that is certified for use in safety
\r
46 http://www.OpenRTOS.com - Commercial support, development, porting,
\r
47 licensing and training services.
\r
51 /*-----------------------------------------------------------
\r
52 * Components that can be compiled to either ARM or THUMB mode are
\r
53 * contained in port.c The ISR routines, which can only be compiled
\r
54 * to ARM mode, are contained in this file.
\r
55 *----------------------------------------------------------*/
\r
60 /* Scheduler includes. */
\r
61 #include "FreeRTOS.h"
\r
64 /* Constants required to handle critical sections. */
\r
65 #define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
\r
67 volatile unsigned portLONG ulCriticalNesting = 9999UL;
\r
69 /*-----------------------------------------------------------*/
\r
72 * The scheduler can only be started from ARM mode, hence the inclusion of this
\r
75 void vPortISRStartFirstTask( void );
\r
76 /*-----------------------------------------------------------*/
\r
78 void vPortISRStartFirstTask( void )
\r
80 /* Simply start the scheduler. This is included here as it can only be
\r
81 called from ARM mode. */
\r
83 "LDR R0, =pxCurrentTCB \n\t" \
\r
84 "LDR R0, [R0] \n\t" \
\r
85 "LDR LR, [R0] \n\t" \
\r
87 /* The critical nesting depth is the first item on the stack. */ \
\r
88 /* Load it into the ulCriticalNesting variable. */ \
\r
89 "LDR R0, =ulCriticalNesting \n\t" \
\r
90 "LDMFD LR!, {R1} \n\t" \
\r
91 "STR R1, [R0] \n\t" \
\r
93 /* Get the SPSR from the stack. */ \
\r
94 "LDMFD LR!, {R0} \n\t" \
\r
95 "MSR SPSR, R0 \n\t" \
\r
97 /* Restore all system mode registers for the task. */ \
\r
98 "LDMFD LR, {R0-R14}^ \n\t" \
\r
101 /* Restore the return address. */ \
\r
102 "LDR LR, [LR, #+60] \n\t" \
\r
104 /* And return - correcting the offset in the LR to obtain the */ \
\r
105 /* correct address. */ \
\r
106 "SUBS PC, LR, #4 \n\t" \
\r
109 /*-----------------------------------------------------------*/
\r
111 void vPortTickISR( void )
\r
113 /* Increment the RTOS tick count, then look for the highest priority
\r
114 task that is ready to run. */
\r
115 vTaskIncrementTick();
\r
117 #if configUSE_PREEMPTION == 1
\r
118 vTaskSwitchContext();
\r
121 /* Ready for the next interrupt. */
\r
122 TB_ClearITPendingBit( TB_IT_Update );
\r
125 /*-----------------------------------------------------------*/
\r
128 * The interrupt management utilities can only be called from ARM mode. When
\r
129 * THUMB_INTERWORK is defined the utilities are defined as functions here to
\r
130 * ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
\r
131 * the utilities are defined as macros in portmacro.h - as per other ports.
\r
133 #ifdef THUMB_INTERWORK
\r
135 void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
\r
136 void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
\r
138 void vPortDisableInterruptsFromThumb( void )
\r
141 "STMDB SP!, {R0} \n\t" /* Push R0. */
\r
142 "MRS R0, CPSR \n\t" /* Get CPSR. */
\r
143 "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
\r
144 "MSR CPSR, R0 \n\t" /* Write back modified value. */
\r
145 "LDMIA SP!, {R0} \n\t" /* Pop R0. */
\r
146 "BX R14" ); /* Return back to thumb. */
\r
149 void vPortEnableInterruptsFromThumb( void )
\r
152 "STMDB SP!, {R0} \n\t" /* Push R0. */
\r
153 "MRS R0, CPSR \n\t" /* Get CPSR. */
\r
154 "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
\r
155 "MSR CPSR, R0 \n\t" /* Write back modified value. */
\r
156 "LDMIA SP!, {R0} \n\t" /* Pop R0. */
\r
157 "BX R14" ); /* Return back to thumb. */
\r
160 #endif /* THUMB_INTERWORK */
\r
161 /*-----------------------------------------------------------*/
\r
163 void vPortEnterCritical( void )
\r
165 /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
\r
167 "STMDB SP!, {R0} \n\t" /* Push R0. */
\r
168 "MRS R0, CPSR \n\t" /* Get CPSR. */
\r
169 "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
\r
170 "MSR CPSR, R0 \n\t" /* Write back modified value. */
\r
171 "LDMIA SP!, {R0}" ); /* Pop R0. */
\r
173 /* Now interrupts are disabled ulCriticalNesting can be accessed
\r
174 directly. Increment ulCriticalNesting to keep a count of how many times
\r
175 portENTER_CRITICAL() has been called. */
\r
176 ulCriticalNesting++;
\r
178 /*-----------------------------------------------------------*/
\r
180 void vPortExitCritical( void )
\r
182 if( ulCriticalNesting > portNO_CRITICAL_NESTING )
\r
184 /* Decrement the nesting count as we are leaving a critical section. */
\r
185 ulCriticalNesting--;
\r
187 /* If the nesting level has reached zero then interrupts should be
\r
189 if( ulCriticalNesting == portNO_CRITICAL_NESTING )
\r
191 /* Enable interrupts as per portEXIT_CRITICAL(). */
\r
193 "STMDB SP!, {R0} \n\t" /* Push R0. */
\r
194 "MRS R0, CPSR \n\t" /* Get CPSR. */
\r
195 "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
\r
196 "MSR CPSR, R0 \n\t" /* Write back modified value. */
\r
197 "LDMIA SP!, {R0}" ); /* Pop R0. */
\r