2 FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
\r
4 FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
\r
5 http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 ***************************************************************************
\r
9 * FreeRTOS tutorial books are available in pdf and paperback. *
\r
10 * Complete, revised, and edited pdf reference manuals are also *
\r
13 * Purchasing FreeRTOS documentation will not only help you, by *
\r
14 * ensuring you get running as quickly as possible and with an *
\r
15 * in-depth knowledge of how to use FreeRTOS, it will also help *
\r
16 * the FreeRTOS project to continue with its mission of providing *
\r
17 * professional grade, cross platform, de facto standard solutions *
\r
18 * for microcontrollers - completely free of charge! *
\r
20 * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
\r
22 * Thank you for using FreeRTOS, and thank you for your support! *
\r
24 ***************************************************************************
\r
27 This file is part of the FreeRTOS distribution.
\r
29 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
30 the terms of the GNU General Public License (version 2) as published by the
\r
31 Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
\r
32 >>>NOTE<<< The modification to the GPL is included to allow you to
\r
33 distribute a combined work that includes FreeRTOS without being obliged to
\r
34 provide the source code for proprietary components outside of the FreeRTOS
\r
35 kernel. FreeRTOS is distributed in the hope that it will be useful, but
\r
36 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
37 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
38 more details. You should have received a copy of the GNU General Public
\r
39 License and the FreeRTOS license exception along with FreeRTOS; if not it
\r
40 can be viewed here: http://www.freertos.org/a00114.html and also obtained
\r
41 by writing to Richard Barry, contact details for whom are available on the
\r
46 ***************************************************************************
\r
48 * Having a problem? Start by reading the FAQ "My application does *
\r
49 * not run, what could be wrong?" *
\r
51 * http://www.FreeRTOS.org/FAQHelp.html *
\r
53 ***************************************************************************
\r
56 http://www.FreeRTOS.org - Documentation, training, latest versions, license
\r
57 and contact details.
\r
59 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
60 including FreeRTOS+Trace - an indispensable productivity tool.
\r
62 Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
\r
63 the code with commercial support, indemnification, and middleware, under
\r
64 the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
\r
65 provide a safety engineered and independently SIL3 certified version under
\r
66 the SafeRTOS brand: http://www.SafeRTOS.com.
\r
69 #include "FreeRTOS.h"
\r
71 #include "mb91467d.h"
\r
73 /*-----------------------------------------------------------*/
\r
75 /* We require the address of the pxCurrentTCB variable, but don't want to know
\r
76 any details of its type. */
\r
77 typedef void tskTCB;
\r
78 extern volatile tskTCB * volatile pxCurrentTCB;
\r
80 /*-----------------------------------------------------------*/
\r
84 ORCCR #0x20 ;Switch to user stack
\r
85 ST RP,@-R15 ;Store RP
\r
86 STM0 (R7,R6,R5,R4,R3,R2,R1,R0) ;Store R7-R0
\r
87 STM1 (R14,R13,R12,R11,R10,R9,R8) ;Store R14-R8
\r
88 ST MDH, @-R15 ;Store MDH
\r
89 ST MDL, @-R15 ;Store MDL
\r
91 ANDCCR #0xDF ;Switch back to system stack
\r
92 LD @R15+,R0 ;Store PC to R0
\r
93 ORCCR #0x20 ;Switch to user stack
\r
94 ST R0,@-R15 ;Store PC to User stack
\r
96 ANDCCR #0xDF ;Switch back to system stack
\r
97 LD @R15+,R0 ;Store PS to R0
\r
98 ORCCR #0x20 ;Switch to user stack
\r
99 ST R0,@-R15 ;Store PS to User stack
\r
101 LDI #_pxCurrentTCB, R0 ;Get pxCurrentTCB address
\r
102 LD @R0, R0 ;Get the pxCurrentTCB->pxTopOfStack address
\r
103 ST R15,@R0 ;Store USP to pxCurrentTCB->pxTopOfStack
\r
105 ANDCCR #0xDF ;Switch back to system stack for the rest of tick ISR
\r
108 #macro RestoreContext
\r
109 LDI #_pxCurrentTCB, R0 ;Get pxCurrentTCB address
\r
110 LD @R0, R0 ;Get the pxCurrentTCB->pxTopOfStack address
\r
111 ORCCR #0x20 ;Switch to user stack
\r
112 LD @R0, R15 ;Restore USP from pxCurrentTCB->pxTopOfStack
\r
114 LD @R15+,R0 ;Store PS to R0
\r
115 ANDCCR #0xDF ;Switch to system stack
\r
116 ST R0,@-R15 ;Store PS to system stack
\r
118 ORCCR #0x20 ;Switch to user stack
\r
119 LD @R15+,R0 ;Store PC to R0
\r
120 ANDCCR #0xDF ;Switch to system stack
\r
121 ST R0,@-R15 ;Store PC to system stack
\r
123 ORCCR #0x20 ;Switch back to retrieve the remaining context
\r
125 LD @R15+, MDL ;Restore MDL
\r
126 LD @R15+, MDH ;Restore MDH
\r
127 LDM1 (R14,R13,R12,R11,R10,R9,R8) ;Restore R14-R8
\r
128 LDM0 (R7,R6,R5,R4,R3,R2,R1,R0) ;Restore R7-R0
\r
129 LD @R15+, RP ;Restore RP
\r
131 ANDCCR #0xDF ;Switch back to system stack for the rest of tick ISR
\r
135 /*-----------------------------------------------------------*/
\r
138 * Perform hardware setup to enable ticks from timer 1,
\r
140 static void prvSetupTimerInterrupt( void );
\r
141 /*-----------------------------------------------------------*/
\r
144 * Initialise the stack of a task to look exactly as if a call to
\r
145 * portSAVE_CONTEXT had been called.
\r
147 * See the header file portable.h.
\r
149 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
\r
151 /* Place a few bytes of known values on the bottom of the stack.
\r
152 This is just useful for debugging. */
\r
154 *pxTopOfStack = 0x11111111;
\r
156 *pxTopOfStack = 0x22222222;
\r
158 *pxTopOfStack = 0x33333333;
\r
161 /* This is a redundant push to the stack, it may be required if
\r
162 in some implementations of the compiler the parameter to the task
\r
163 is passed on to the stack rather than in R4 register. */
\r
164 *pxTopOfStack = (portSTACK_TYPE)(pvParameters);
\r
167 *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* RP */
\r
169 *pxTopOfStack = ( portSTACK_TYPE ) 0x00007777; /* R7 */
\r
171 *pxTopOfStack = ( portSTACK_TYPE ) 0x00006666; /* R6 */
\r
173 *pxTopOfStack = ( portSTACK_TYPE ) 0x00005555; /* R5 */
\r
176 /* In the current implementation of the compiler the first
\r
177 parameter to the task (or function) is passed via R4 parameter
\r
178 to the task, hence the pvParameters pointer is copied into the R4
\r
179 register. See compiler manual section 4.6.2 for more information. */
\r
180 *pxTopOfStack = ( portSTACK_TYPE ) (pvParameters); /* R4 */
\r
182 *pxTopOfStack = ( portSTACK_TYPE ) 0x00003333; /* R3 */
\r
184 *pxTopOfStack = ( portSTACK_TYPE ) 0x00002222; /* R2 */
\r
186 *pxTopOfStack = ( portSTACK_TYPE ) 0x00001111; /* R1 */
\r
188 *pxTopOfStack = ( portSTACK_TYPE ) 0x00000001; /* R0 */
\r
190 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000EEEE; /* R14 */
\r
192 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000DDDD; /* R13 */
\r
194 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000CCCC; /* R12 */
\r
196 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000BBBB; /* R11 */
\r
198 *pxTopOfStack = ( portSTACK_TYPE ) 0x0000AAAA; /* R10 */
\r
200 *pxTopOfStack = ( portSTACK_TYPE ) 0x00009999; /* R9 */
\r
202 *pxTopOfStack = ( portSTACK_TYPE ) 0x00008888; /* R8 */
\r
204 *pxTopOfStack = ( portSTACK_TYPE ) 0x11110000; /* MDH */
\r
206 *pxTopOfStack = ( portSTACK_TYPE ) 0x22220000; /* MDL */
\r
209 /* The start of the task code. */
\r
210 *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
\r
213 /* PS - User Mode, USP, ILM=31, Interrupts enabled */
\r
214 *pxTopOfStack = ( portSTACK_TYPE ) 0x001F0030; /* PS */
\r
216 return pxTopOfStack;
\r
218 /*-----------------------------------------------------------*/
\r
220 portBASE_TYPE xPortStartScheduler( void )
\r
222 /* Setup the hardware to generate the tick. */
\r
223 prvSetupTimerInterrupt();
\r
225 /* Restore the context of the first task that is going to run. */
\r
230 /* Simulate a function call end as generated by the compiler. We will now
\r
231 jump to the start of the task the context of which we have just restored. */
\r
234 /* Should not get here. */
\r
237 /*-----------------------------------------------------------*/
\r
239 void vPortEndScheduler( void )
\r
241 /* Not implemented - unlikely to ever be required as there is nothing to
\r
244 /*-----------------------------------------------------------*/
\r
246 static void prvSetupTimerInterrupt( void )
\r
248 /* The peripheral clock divided by 32 is used by the timer. */
\r
249 const unsigned short usReloadValue = ( unsigned short ) ( ( ( configPER_CLOCK_HZ / configTICK_RATE_HZ ) / 32UL ) - 1UL );
\r
251 /* Setup RLT0 to generate a tick interrupt. */
\r
253 TMCSR0_CNTE = 0; /* Count Disable */
\r
254 TMCSR0_CSL = 0x2; /* CLKP/32 */
\r
255 TMCSR0_MOD = 0; /* Software trigger */
\r
256 TMCSR0_RELD = 1; /* Reload */
\r
258 TMCSR0_UF = 0; /* Clear underflow flag */
\r
259 TMRLR0 = usReloadValue;
\r
260 TMCSR0_INTE = 1; /* Interrupt Enable */
\r
261 TMCSR0_CNTE = 1; /* Count Enable */
\r
262 TMCSR0_TRG = 1; /* Trigger */
\r
264 PORTEN = 0x3; /* Port Enable */
\r
266 /*-----------------------------------------------------------*/
\r
268 #if configUSE_PREEMPTION == 1
\r
271 * Tick ISR for preemptive scheduler. The tick count is incremented
\r
272 * after the context is saved. Then the context is switched if required,
\r
273 * and last the context of the task which is to be resumed is restored.
\r
278 .global _ReloadTimer0_IRQHandler
\r
279 _ReloadTimer0_IRQHandler:
\r
281 ANDCCR #0xEF ;Disable Interrupts
\r
282 SaveContext ;Save context
\r
283 ORCCR #0x10 ;Re-enable Interrupts
\r
287 AND R1,@R0 ;Clear RLT0 interrupt flag
\r
289 CALL32 _vTaskIncrementTick,R12 ;Increment Tick
\r
290 CALL32 _vTaskSwitchContext,R12 ;Switch context if required
\r
292 ANDCCR #0xEF ;Disable Interrupts
\r
293 RestoreContext ;Restore context
\r
294 ORCCR #0x10 ;Re-enable Interrupts
\r
303 * Tick ISR for the cooperative scheduler. All this does is increment the
\r
304 * tick count. We don't need to switch context, this can only be done by
\r
305 * manual calls to taskYIELD();
\r
307 __interrupt void ReloadTimer0_IRQHandler( void )
\r
309 /* Clear RLT0 interrupt flag */
\r
311 vTaskIncrementTick();
\r
317 * Manual context switch. We can use a __nosavereg attribute as the context
\r
318 * would be saved by PortSAVE_CONTEXT(). The context is switched and then
\r
319 * the context of the new task is restored saved.
\r
323 .global _vPortYieldDelayed
\r
324 _vPortYieldDelayed:
\r
326 ANDCCR #0xEF ;Disable Interrupts
\r
327 SaveContext ;Save context
\r
328 ORCCR #0x10 ;Re-enable Interrupts
\r
331 BANDL #0x0E, @R0 ;Clear Delayed interrupt flag
\r
333 CALL32 _vTaskSwitchContext,R12 ;Switch context if required
\r
335 ANDCCR #0xEF ;Disable Interrupts
\r
336 RestoreContext ;Restore context
\r
337 ORCCR #0x10 ;Re-enable Interrupts
\r
342 /*-----------------------------------------------------------*/
\r
345 * Manual context switch. We can use a __nosavereg attribute as the context
\r
346 * would be saved by PortSAVE_CONTEXT(). The context is switched and then
\r
347 * the context of the new task is restored saved.
\r
351 .global _vPortYield
\r
354 SaveContext ;Save context
\r
355 CALL32 _vTaskSwitchContext,R12 ;Switch context if required
\r
356 RestoreContext ;Restore context
\r
361 /*-----------------------------------------------------------*/
\r