2 FreeRTOS.org V4.0.4 - 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
37 /*-----------------------------------------------------------
\r
38 * Port specific definitions.
\r
40 * The settings in this file configure FreeRTOS correctly for the
\r
41 * given hardware and compiler.
\r
43 * These settings should not be altered.
\r
44 *-----------------------------------------------------------
\r
47 /* Type definitions. */
\r
48 #define portCHAR char
\r
49 #define portFLOAT float
\r
50 #define portDOUBLE double
\r
51 #define portLONG long
\r
52 #define portSHORT short
\r
53 #define portSTACK_TYPE unsigned portLONG
\r
54 #define portBASE_TYPE portLONG
\r
56 #if( configUSE_16_BIT_TICKS == 1 )
\r
57 typedef unsigned portSHORT portTickType;
\r
58 #define portMAX_DELAY ( portTickType ) 0xffff
\r
60 typedef unsigned portLONG portTickType;
\r
61 #define portMAX_DELAY ( portTickType ) 0xffffffff
\r
63 /*-----------------------------------------------------------*/
\r
65 /* Hardware specifics. */
\r
66 #define portSTACK_GROWTH ( -1 )
\r
67 #define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
\r
68 #define portBYTE_ALIGNMENT 4
\r
69 /*-----------------------------------------------------------*/
\r
71 /* Task utilities. */
\r
72 #define portRESTORE_CONTEXT() \
\r
74 extern volatile unsigned portLONG ulCriticalNesting; \
\r
75 extern volatile void * volatile pxCurrentTCB; \
\r
77 __asm{ LDR R1, =pxCurrentTCB };/* Set the LR to the task stack. The location was ... */ \
\r
78 __asm{ LDR R0, [R1] }; /* ... stored in pxCurrentTCB. */ \
\r
79 __asm{ LDR LR, [R0] }; \
\r
81 __asm{ LDR R0, =ulCriticalNesting }; /* The critical nesting depth is the first item on ... */ \
\r
82 __asm{ LDMFD LR!, {R1 } } /* ... the stack. Load it into the ulCriticalNesting var. */ \
\r
83 __asm{ STR R1, [R0] } \
\r
85 __asm{ LDMFD LR!, {R0} }; /* Get the SPSR from the stack. */ \
\r
86 __asm{ MSR SPSR_CXSF, R0 }; \
\r
88 __asm{ LDMFD LR, {R0-R14}^ }; /* Restore all system mode registers for the task. */ \
\r
91 __asm{ LDR LR, [LR, #+60] }; /* Restore the return address. */ \
\r
93 /* And return - correcting the offset in the LR to obtain ... */ \
\r
94 __asm{ SUBS PC, LR, #4 }; /* ... the correct address. */ \
\r
96 /*----------------------------------------------------------*/
\r
98 #define portSAVE_CONTEXT() \
\r
100 extern volatile unsigned portLONG ulCriticalNesting; \
\r
101 extern volatile void * volatile pxCurrentTCB; \
\r
103 __asm{ STMDB SP!, {R0} }; /* Store R0 first as we need to use it. */ \
\r
105 __asm{ STMDB SP,{SP}^ }; /* Set R0 to point to the task stack pointer. */ \
\r
107 __asm{ SUB SP, SP, #4 }; \
\r
108 __asm{ LDMIA SP!,{R0} }; \
\r
110 __asm{ STMDB R0!, {LR} }; /* Push the return address onto the stack. */ \
\r
111 __asm{ MOV LR, R0 }; /* Now we have saved LR we can use it instead of R0. */ \
\r
112 __asm{ LDMIA SP!, {R0} }; /* Pop R0 so we can save it onto the system mode stack. */ \
\r
114 __asm{ STMDB LR,{R0-LR}^ }; /* Push all the system mode registers onto the task stack. */ \
\r
116 __asm{ SUB LR, LR, #60 }; \
\r
118 __asm{ MRS R0, SPSR }; /* Push the SPSR onto the task stack. */ \
\r
119 __asm{ STMDB LR!, {R0} }; \
\r
121 __asm{ LDR R0, =ulCriticalNesting }; \
\r
122 __asm{ LDR R0, [R0] }; \
\r
123 __asm{ STMDB LR!, {R0} }; \
\r
125 __asm{ LDR R0, =pxCurrentTCB };/* Store the new top of stack for the task. */ \
\r
126 __asm{ LDR R1, [R0] }; \
\r
127 __asm{ STR LR, [R1] }; \
\r
130 /*-----------------------------------------------------------
\r
131 * ISR entry and exit macros. These are only required if a task switch
\r
132 * is required from an ISR.
\r
133 *----------------------------------------------------------*/
\r
135 #define portENTER_SWITCHING_ISR() \
\r
136 portSAVE_CONTEXT(); \
\r
139 #define portEXIT_SWITCHING_ISR( SwitchRequired ) \
\r
140 /* If a switch is required then we just need to call */ \
\r
141 /* vTaskSwitchContext() as the context has already been */ \
\r
143 if( SwitchRequired ) \
\r
145 vTaskSwitchContext(); \
\r
148 /* Restore the context of which ever task is now the highest */ \
\r
149 /* priority that is ready to run. */ \
\r
150 portRESTORE_CONTEXT();
\r
153 /* Yield the processor - force a context switch. */
\r
154 #define portYIELD() __asm{ SWI 0 };
\r
155 /*-----------------------------------------------------------*/
\r
157 /* Critical section management. */
\r
159 /*-----------------------------------------------------------
\r
160 * Interrupt control macros.
\r
162 * The interrupt management utilities can only be called from ARM mode. When
\r
163 * KEIL_THUMB_INTERWORK is defined the utilities are defined as functions in
\r
164 * portISR.c to ensure a switch to ARM mode. When KEIL_THUMB_INTERWORK is not
\r
165 * defined then the utilities are defined as macros here - as per other ports.
\r
166 *----------------------------------------------------------*/
\r
168 #ifdef KEIL_THUMB_INTERWORK
\r
170 extern void vPortDisableInterruptsFromThumb( void ) __task;
\r
171 extern void vPortEnableInterruptsFromThumb( void ) __task;
\r
173 #define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
\r
174 #define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
\r
178 /*-----------------------------------------------------------*/
\r
180 #define portDISABLE_INTERRUPTS() \
\r
181 __asm{ STMDB SP!, {R0} }; /* Push R0. */ \
\r
182 __asm{ MRS R0, CPSR }; /* Get CPSR. */ \
\r
183 __asm{ ORR R0, R0, #0xC0 }; /* Disable IRQ, FIQ. */ \
\r
184 __asm{ MSR CPSR_CXSF, R0 }; /* Write back modified value. */ \
\r
185 __asm{ LDMIA SP!, {R0} } /* Pop R0. */
\r
187 #define portENABLE_INTERRUPTS() \
\r
188 __asm{ STMDB SP!, {R0} }; /* Push R0. */ \
\r
189 __asm{ MRS R0, CPSR }; /* Get CPSR. */ \
\r
190 __asm{ BIC R0, R0, #0xC0 }; /* Enable IRQ, FIQ. */ \
\r
191 __asm{ MSR CPSR_CXSF, R0 }; /* Write back modified value. */ \
\r
192 __asm{ LDMIA SP!, {R0} } /* Pop R0. */
\r
194 #endif /* KEIL_THUMB_INTERWORK */
\r
196 /*-----------------------------------------------------------
\r
197 * Critical section control
\r
199 * The code generated by the Keil compiler does not maintain separate
\r
200 * stack and frame pointers. The portENTER_CRITICAL macro cannot therefore
\r
201 * use the stack as per other ports. Instead a variable is used to keep
\r
202 * track of the critical section nesting. This necessitates the use of a
\r
203 * function in place of the macro.
\r
204 *----------------------------------------------------------*/
\r
206 extern void vPortEnterCritical( void );
\r
207 extern void vPortExitCritical( void );
\r
209 #define portENTER_CRITICAL() vPortEnterCritical();
\r
210 #define portEXIT_CRITICAL() vPortExitCritical();
\r
211 /*-----------------------------------------------------------*/
\r
213 /* Compiler specifics. */
\r
216 #define portNOP() __asm{ NOP }
\r
217 /*-----------------------------------------------------------*/
\r
219 /* Task function macros as described on the FreeRTOS.org WEB site. */
\r
220 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __task
\r
221 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
\r
223 #endif /* PORTMACRO_H */
\r