2 FreeRTOS.org V4.1.2 - Copyright (C) 2003-2006 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 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
34 /*-----------------------------------------------------------
\r
35 * Components that can be compiled to either ARM or THUMB mode are
\r
36 * contained in port.c The ISR routines, which can only be compiled
\r
37 * to ARM mode, are contained in this file.
\r
38 *----------------------------------------------------------*/
\r
43 /* Scheduler includes. */
\r
44 #include "FreeRTOS.h"
\r
47 /* Constants required to handle critical sections. */
\r
48 #define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
\r
50 volatile unsigned portLONG ulCriticalNesting = 9999UL;
\r
52 /*-----------------------------------------------------------*/
\r
55 * The scheduler can only be started from ARM mode, hence the inclusion of this
\r
58 void vPortISRStartFirstTask( void );
\r
59 /*-----------------------------------------------------------*/
\r
61 void vPortISRStartFirstTask( void )
\r
63 /* Simply start the scheduler. This is included here as it can only be
\r
64 called from ARM mode. */
\r
66 "LDR R0, =pxCurrentTCB \n\t" \
\r
67 "LDR R0, [R0] \n\t" \
\r
68 "LDR LR, [R0] \n\t" \
\r
70 /* The critical nesting depth is the first item on the stack. */ \
\r
71 /* Load it into the ulCriticalNesting variable. */ \
\r
72 "LDR R0, =ulCriticalNesting \n\t" \
\r
73 "LDMFD LR!, {R1} \n\t" \
\r
74 "STR R1, [R0] \n\t" \
\r
76 /* Get the SPSR from the stack. */ \
\r
77 "LDMFD LR!, {R0} \n\t" \
\r
78 "MSR SPSR, R0 \n\t" \
\r
80 /* Restore all system mode registers for the task. */ \
\r
81 "LDMFD LR, {R0-R14}^ \n\t" \
\r
84 /* Restore the return address. */ \
\r
85 "LDR LR, [LR, #+60] \n\t" \
\r
87 /* And return - correcting the offset in the LR to obtain the */ \
\r
88 /* correct address. */ \
\r
89 "SUBS PC, LR, #4 \n\t" \
\r
92 /*-----------------------------------------------------------*/
\r
94 void vPortTickISR( void )
\r
96 /* Increment the RTOS tick count, then look for the highest priority
\r
97 task that is ready to run. */
\r
98 vTaskIncrementTick();
\r
100 #if configUSE_PREEMPTION == 1
\r
101 vTaskSwitchContext();
\r
104 /* Ready for the next interrupt. */
\r
105 TB_ClearITPendingBit( TB_IT_Update );
\r
108 /*-----------------------------------------------------------*/
\r
111 * The interrupt management utilities can only be called from ARM mode. When
\r
112 * THUMB_INTERWORK is defined the utilities are defined as functions here to
\r
113 * ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
\r
114 * the utilities are defined as macros in portmacro.h - as per other ports.
\r
116 #ifdef THUMB_INTERWORK
\r
118 void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
\r
119 void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
\r
121 void vPortDisableInterruptsFromThumb( void )
\r
124 "STMDB SP!, {R0} \n\t" /* Push R0. */
\r
125 "MRS R0, CPSR \n\t" /* Get CPSR. */
\r
126 "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
\r
127 "MSR CPSR, R0 \n\t" /* Write back modified value. */
\r
128 "LDMIA SP!, {R0} \n\t" /* Pop R0. */
\r
129 "BX R14" ); /* Return back to thumb. */
\r
132 void vPortEnableInterruptsFromThumb( void )
\r
135 "STMDB SP!, {R0} \n\t" /* Push R0. */
\r
136 "MRS R0, CPSR \n\t" /* Get CPSR. */
\r
137 "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
\r
138 "MSR CPSR, R0 \n\t" /* Write back modified value. */
\r
139 "LDMIA SP!, {R0} \n\t" /* Pop R0. */
\r
140 "BX R14" ); /* Return back to thumb. */
\r
143 #endif /* THUMB_INTERWORK */
\r
144 /*-----------------------------------------------------------*/
\r
146 void vPortEnterCritical( void )
\r
148 /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
\r
150 "STMDB SP!, {R0} \n\t" /* Push R0. */
\r
151 "MRS R0, CPSR \n\t" /* Get CPSR. */
\r
152 "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
\r
153 "MSR CPSR, R0 \n\t" /* Write back modified value. */
\r
154 "LDMIA SP!, {R0}" ); /* Pop R0. */
\r
156 /* Now interrupts are disabled ulCriticalNesting can be accessed
\r
157 directly. Increment ulCriticalNesting to keep a count of how many times
\r
158 portENTER_CRITICAL() has been called. */
\r
159 ulCriticalNesting++;
\r
161 /*-----------------------------------------------------------*/
\r
163 void vPortExitCritical( void )
\r
165 if( ulCriticalNesting > portNO_CRITICAL_NESTING )
\r
167 /* Decrement the nesting count as we are leaving a critical section. */
\r
168 ulCriticalNesting--;
\r
170 /* If the nesting level has reached zero then interrupts should be
\r
172 if( ulCriticalNesting == portNO_CRITICAL_NESTING )
\r
174 /* Enable interrupts as per portEXIT_CRITICAL(). */
\r
176 "STMDB SP!, {R0} \n\t" /* Push R0. */
\r
177 "MRS R0, CPSR \n\t" /* Get CPSR. */
\r
178 "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
\r
179 "MSR CPSR, R0 \n\t" /* Write back modified value. */
\r
180 "LDMIA SP!, {R0}" ); /* Pop R0. */
\r