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
70 #include "FreeRTOS.h"
\r
72 #include "mb91467d.h"
\r
74 /*-----------------------------------------------------------*/
\r
76 /* We require the address of the pxCurrentTCB variable, but don't want to know
\r
77 any details of its type. */
\r
79 extern volatile TCB_t * volatile pxCurrentTCB;
\r
81 /*-----------------------------------------------------------*/
\r
85 ORCCR #0x20 ;Switch to user stack
\r
86 ST RP,@-R15 ;Store RP
\r
87 STM0 (R7,R6,R5,R4,R3,R2,R1,R0) ;Store R7-R0
\r
88 STM1 (R14,R13,R12,R11,R10,R9,R8) ;Store R14-R8
\r
89 ST MDH, @-R15 ;Store MDH
\r
90 ST MDL, @-R15 ;Store MDL
\r
92 ANDCCR #0xDF ;Switch back to system stack
\r
93 LD @R15+,R0 ;Store PC to R0
\r
94 ORCCR #0x20 ;Switch to user stack
\r
95 ST R0,@-R15 ;Store PC to User stack
\r
97 ANDCCR #0xDF ;Switch back to system stack
\r
98 LD @R15+,R0 ;Store PS to R0
\r
99 ORCCR #0x20 ;Switch to user stack
\r
100 ST R0,@-R15 ;Store PS to User stack
\r
102 LDI #_pxCurrentTCB, R0 ;Get pxCurrentTCB address
\r
103 LD @R0, R0 ;Get the pxCurrentTCB->pxTopOfStack address
\r
104 ST R15,@R0 ;Store USP to pxCurrentTCB->pxTopOfStack
\r
106 ANDCCR #0xDF ;Switch back to system stack for the rest of tick ISR
\r
109 #macro RestoreContext
\r
110 LDI #_pxCurrentTCB, R0 ;Get pxCurrentTCB address
\r
111 LD @R0, R0 ;Get the pxCurrentTCB->pxTopOfStack address
\r
112 ORCCR #0x20 ;Switch to user stack
\r
113 LD @R0, R15 ;Restore USP from pxCurrentTCB->pxTopOfStack
\r
115 LD @R15+,R0 ;Store PS to R0
\r
116 ANDCCR #0xDF ;Switch to system stack
\r
117 ST R0,@-R15 ;Store PS to system stack
\r
119 ORCCR #0x20 ;Switch to user stack
\r
120 LD @R15+,R0 ;Store PC to R0
\r
121 ANDCCR #0xDF ;Switch to system stack
\r
122 ST R0,@-R15 ;Store PC to system stack
\r
124 ORCCR #0x20 ;Switch back to retrieve the remaining context
\r
126 LD @R15+, MDL ;Restore MDL
\r
127 LD @R15+, MDH ;Restore MDH
\r
128 LDM1 (R14,R13,R12,R11,R10,R9,R8) ;Restore R14-R8
\r
129 LDM0 (R7,R6,R5,R4,R3,R2,R1,R0) ;Restore R7-R0
\r
130 LD @R15+, RP ;Restore RP
\r
132 ANDCCR #0xDF ;Switch back to system stack for the rest of tick ISR
\r
136 /*-----------------------------------------------------------*/
\r
139 * Perform hardware setup to enable ticks from timer 1,
\r
141 static void prvSetupTimerInterrupt( void );
\r
142 /*-----------------------------------------------------------*/
\r
145 * Initialise the stack of a task to look exactly as if a call to
\r
146 * portSAVE_CONTEXT had been called.
\r
148 * See the header file portable.h.
\r
150 StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
\r
152 /* Place a few bytes of known values on the bottom of the stack.
\r
153 This is just useful for debugging. */
\r
155 *pxTopOfStack = 0x11111111;
\r
157 *pxTopOfStack = 0x22222222;
\r
159 *pxTopOfStack = 0x33333333;
\r
162 /* This is a redundant push to the stack, it may be required if
\r
163 in some implementations of the compiler the parameter to the task
\r
164 is passed on to the stack rather than in R4 register. */
\r
165 *pxTopOfStack = (StackType_t)(pvParameters);
\r
168 *pxTopOfStack = ( StackType_t ) 0x00000000; /* RP */
\r
170 *pxTopOfStack = ( StackType_t ) 0x00007777; /* R7 */
\r
172 *pxTopOfStack = ( StackType_t ) 0x00006666; /* R6 */
\r
174 *pxTopOfStack = ( StackType_t ) 0x00005555; /* R5 */
\r
177 /* In the current implementation of the compiler the first
\r
178 parameter to the task (or function) is passed via R4 parameter
\r
179 to the task, hence the pvParameters pointer is copied into the R4
\r
180 register. See compiler manual section 4.6.2 for more information. */
\r
181 *pxTopOfStack = ( StackType_t ) (pvParameters); /* R4 */
\r
183 *pxTopOfStack = ( StackType_t ) 0x00003333; /* R3 */
\r
185 *pxTopOfStack = ( StackType_t ) 0x00002222; /* R2 */
\r
187 *pxTopOfStack = ( StackType_t ) 0x00001111; /* R1 */
\r
189 *pxTopOfStack = ( StackType_t ) 0x00000001; /* R0 */
\r
191 *pxTopOfStack = ( StackType_t ) 0x0000EEEE; /* R14 */
\r
193 *pxTopOfStack = ( StackType_t ) 0x0000DDDD; /* R13 */
\r
195 *pxTopOfStack = ( StackType_t ) 0x0000CCCC; /* R12 */
\r
197 *pxTopOfStack = ( StackType_t ) 0x0000BBBB; /* R11 */
\r
199 *pxTopOfStack = ( StackType_t ) 0x0000AAAA; /* R10 */
\r
201 *pxTopOfStack = ( StackType_t ) 0x00009999; /* R9 */
\r
203 *pxTopOfStack = ( StackType_t ) 0x00008888; /* R8 */
\r
205 *pxTopOfStack = ( StackType_t ) 0x11110000; /* MDH */
\r
207 *pxTopOfStack = ( StackType_t ) 0x22220000; /* MDL */
\r
210 /* The start of the task code. */
\r
211 *pxTopOfStack = ( StackType_t ) pxCode; /* PC */
\r
214 /* PS - User Mode, USP, ILM=31, Interrupts enabled */
\r
215 *pxTopOfStack = ( StackType_t ) 0x001F0030; /* PS */
\r
217 return pxTopOfStack;
\r
219 /*-----------------------------------------------------------*/
\r
221 BaseType_t xPortStartScheduler( void )
\r
223 /* Setup the hardware to generate the tick. */
\r
224 prvSetupTimerInterrupt();
\r
226 /* Restore the context of the first task that is going to run. */
\r
231 /* Simulate a function call end as generated by the compiler. We will now
\r
232 jump to the start of the task the context of which we have just restored. */
\r
235 /* Should not get here. */
\r
238 /*-----------------------------------------------------------*/
\r
240 void vPortEndScheduler( void )
\r
242 /* Not implemented - unlikely to ever be required as there is nothing to
\r
245 /*-----------------------------------------------------------*/
\r
247 static void prvSetupTimerInterrupt( void )
\r
249 /* The peripheral clock divided by 32 is used by the timer. */
\r
250 const uint16_t usReloadValue = ( uint16_t ) ( ( ( configPER_CLOCK_HZ / configTICK_RATE_HZ ) / 32UL ) - 1UL );
\r
252 /* Setup RLT0 to generate a tick interrupt. */
\r
254 TMCSR0_CNTE = 0; /* Count Disable */
\r
255 TMCSR0_CSL = 0x2; /* CLKP/32 */
\r
256 TMCSR0_MOD = 0; /* Software trigger */
\r
257 TMCSR0_RELD = 1; /* Reload */
\r
259 TMCSR0_UF = 0; /* Clear underflow flag */
\r
260 TMRLR0 = usReloadValue;
\r
261 TMCSR0_INTE = 1; /* Interrupt Enable */
\r
262 TMCSR0_CNTE = 1; /* Count Enable */
\r
263 TMCSR0_TRG = 1; /* Trigger */
\r
265 PORTEN = 0x3; /* Port Enable */
\r
267 /*-----------------------------------------------------------*/
\r
269 #if configUSE_PREEMPTION == 1
\r
272 * Tick ISR for preemptive scheduler. The tick count is incremented
\r
273 * after the context is saved. Then the context is switched if required,
\r
274 * and last the context of the task which is to be resumed is restored.
\r
279 .global _ReloadTimer0_IRQHandler
\r
280 _ReloadTimer0_IRQHandler:
\r
282 ANDCCR #0xEF ;Disable Interrupts
\r
283 SaveContext ;Save context
\r
284 ORCCR #0x10 ;Re-enable Interrupts
\r
288 AND R1,@R0 ;Clear RLT0 interrupt flag
\r
290 CALL32 _xTaskIncrementTick,R12 ;Increment Tick
\r
291 CALL32 _vTaskSwitchContext,R12 ;Switch context if required
\r
293 ANDCCR #0xEF ;Disable Interrupts
\r
294 RestoreContext ;Restore context
\r
295 ORCCR #0x10 ;Re-enable Interrupts
\r
304 * Tick ISR for the cooperative scheduler. All this does is increment the
\r
305 * tick count. We don't need to switch context, this can only be done by
\r
306 * manual calls to taskYIELD();
\r
308 __interrupt void ReloadTimer0_IRQHandler( void )
\r
310 /* Clear RLT0 interrupt flag */
\r
312 xTaskIncrementTick();
\r
318 * Manual context switch. We can use a __nosavereg attribute as the context
\r
319 * would be saved by PortSAVE_CONTEXT(). The context is switched and then
\r
320 * the context of the new task is restored saved.
\r
324 .global _vPortYieldDelayed
\r
325 _vPortYieldDelayed:
\r
327 ANDCCR #0xEF ;Disable Interrupts
\r
328 SaveContext ;Save context
\r
329 ORCCR #0x10 ;Re-enable Interrupts
\r
332 BANDL #0x0E, @R0 ;Clear Delayed interrupt flag
\r
334 CALL32 _vTaskSwitchContext,R12 ;Switch context if required
\r
336 ANDCCR #0xEF ;Disable Interrupts
\r
337 RestoreContext ;Restore context
\r
338 ORCCR #0x10 ;Re-enable Interrupts
\r
343 /*-----------------------------------------------------------*/
\r
346 * Manual context switch. We can use a __nosavereg attribute as the context
\r
347 * would be saved by PortSAVE_CONTEXT(). The context is switched and then
\r
348 * the context of the new task is restored saved.
\r
352 .global _vPortYield
\r
355 SaveContext ;Save context
\r
356 CALL32 _vTaskSwitchContext,R12 ;Switch context if required
\r
357 RestoreContext ;Restore context
\r
362 /*-----------------------------------------------------------*/
\r