2 FreeRTOS.org V5.0.4 - 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
53 + Introduced the configKERNEL_INTERRUPT_PRIORITY definition.
\r
56 /*-----------------------------------------------------------
\r
57 * Implementation of functions defined in portable.h for the PIC24 port.
\r
58 *----------------------------------------------------------*/
\r
60 /* Scheduler include files. */
\r
61 #include "FreeRTOS.h"
\r
64 /* Hardware specifics. */
\r
65 #define portBIT_SET 1
\r
66 #define portTIMER_PRESCALE 8
\r
67 #define portINITIAL_SR 0
\r
69 /* Defined for backward compatability with project created prior to
\r
70 FreeRTOS.org V4.3.0. */
\r
71 #ifndef configKERNEL_INTERRUPT_PRIORITY
\r
72 #define configKERNEL_INTERRUPT_PRIORITY 1
\r
75 /* The program counter is only 23 bits. */
\r
76 #define portUNUSED_PR_BITS 0x7f
\r
78 /* Records the nesting depth of calls to portENTER_CRITICAL(). */
\r
79 unsigned portBASE_TYPE uxCriticalNesting = 0xef;
\r
81 #if configKERNEL_INTERRUPT_PRIORITY != 1
\r
82 #error If configKERNEL_INTERRUPT_PRIORITY is not 1 then the #32 in the following macros needs changing to equal the portINTERRUPT_BITS value, which is ( configKERNEL_INTERRUPT_PRIORITY << 5 )
\r
85 #ifdef MPLAB_PIC24_PORT
\r
87 #define portRESTORE_CONTEXT() \
\r
88 asm volatile( "MOV _pxCurrentTCB, W0 \n" /* Restore the stack pointer for the task. */ \
\r
89 "MOV [W0], W15 \n" \
\r
90 "POP W0 \n" /* Restore the critical nesting counter for the task. */ \
\r
91 "MOV W0, _uxCriticalNesting \n" \
\r
95 "POP RCOUNT \n" /* Restore the registers from the stack. */ \
\r
106 #endif /* MPLAB_PIC24_PORT */
\r
108 #ifdef MPLAB_DSPIC_PORT
\r
110 #define portRESTORE_CONTEXT() \
\r
111 asm volatile( "MOV _pxCurrentTCB, W0 \n" /* Restore the stack pointer for the task. */ \
\r
112 "MOV [W0], W15 \n" \
\r
113 "POP W0 \n" /* Restore the critical nesting counter for the task. */ \
\r
114 "MOV W0, _uxCriticalNesting \n" \
\r
119 "POP DOSTARTH \n" \
\r
120 "POP DOSTARTL \n" \
\r
129 "POP RCOUNT \n" /* Restore the registers from the stack. */ \
\r
140 #endif /* MPLAB_DSPIC_PORT */
\r
143 * Setup the timer used to generate the tick interrupt.
\r
145 static void prvSetupTimerInterrupt( void );
\r
148 * See header file for description.
\r
150 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
\r
152 unsigned portSHORT usCode;
\r
155 const portSTACK_TYPE xInitialStack[] =
\r
171 0xcdce, /* RCOUNT */
\r
172 0xabac, /* TBLPAG */
\r
174 /* dsPIC specific registers. */
\r
175 #ifdef MPLAB_DSPIC_PORT
\r
176 0x0202, /* ACCAL */
\r
177 0x0303, /* ACCAH */
\r
178 0x0404, /* ACCAU */
\r
179 0x0505, /* ACCBL */
\r
180 0x0606, /* ACCBH */
\r
181 0x0707, /* ACCBU */
\r
182 0x0808, /* DCOUNT */
\r
183 0x090a, /* DOSTARTL */
\r
184 0x1010, /* DOSTARTH */
\r
185 0x1110, /* DOENDL */
\r
186 0x1212, /* DOENDH */
\r
190 /* Setup the stack as if a yield had occurred.
\r
192 Save the low bytes of the program counter. */
\r
193 usCode = ( unsigned portSHORT ) pxCode;
\r
194 *pxTopOfStack = ( portSTACK_TYPE ) usCode;
\r
197 /* Save the high byte of the program counter. This will always be zero
\r
198 here as it is passed in a 16bit pointer. If the address is greater than
\r
199 16 bits then the pointer will point to a jump table. */
\r
200 *pxTopOfStack = ( portSTACK_TYPE ) 0;
\r
203 /* Status register with interrupts enabled. */
\r
204 *pxTopOfStack = portINITIAL_SR;
\r
207 /* Parameters are passed in W0. */
\r
208 *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
\r
211 for( i = 0; i < ( sizeof( xInitialStack ) / sizeof( portSTACK_TYPE ) ); i++ )
\r
213 *pxTopOfStack = xInitialStack[ i ];
\r
217 *pxTopOfStack = CORCON;
\r
219 *pxTopOfStack = PSVPAG;
\r
222 /* Finally the critical nesting depth. */
\r
223 *pxTopOfStack = 0x00;
\r
226 return pxTopOfStack;
\r
228 /*-----------------------------------------------------------*/
\r
230 portBASE_TYPE xPortStartScheduler( void )
\r
232 /* Setup a timer for the tick ISR. */
\r
233 prvSetupTimerInterrupt();
\r
235 /* Restore the context of the first task to run. */
\r
236 portRESTORE_CONTEXT();
\r
238 /* Simulate the end of the yield function. */
\r
239 asm volatile ( "return" );
\r
241 /* Should not reach here. */
\r
244 /*-----------------------------------------------------------*/
\r
246 void vPortEndScheduler( void )
\r
248 /* It is unlikely that the scheduler for the PIC port will get stopped
\r
249 once running. If required disable the tick interrupt here, then return
\r
250 to xPortStartScheduler(). */
\r
252 /*-----------------------------------------------------------*/
\r
255 * Setup a timer for a regular tick.
\r
257 static void prvSetupTimerInterrupt( void )
\r
259 const unsigned portLONG ulCompareMatch = ( configCPU_CLOCK_HZ / portTIMER_PRESCALE ) / configTICK_RATE_HZ;
\r
261 /* Prescale of 8. */
\r
265 PR1 = ( unsigned portSHORT ) ulCompareMatch;
\r
267 /* Setup timer 1 interrupt priority. */
\r
268 IPC0bits.T1IP = configKERNEL_INTERRUPT_PRIORITY;
\r
270 /* Clear the interrupt as a starting condition. */
\r
273 /* Enable the interrupt. */
\r
276 /* Setup the prescale value. */
\r
277 T1CONbits.TCKPS0 = 1;
\r
278 T1CONbits.TCKPS1 = 0;
\r
280 /* Start the timer. */
\r
283 /*-----------------------------------------------------------*/
\r
285 void vPortEnterCritical( void )
\r
287 portDISABLE_INTERRUPTS();
\r
288 uxCriticalNesting++;
\r
290 /*-----------------------------------------------------------*/
\r
292 void vPortExitCritical( void )
\r
294 uxCriticalNesting--;
\r
295 if( uxCriticalNesting == 0 )
\r
297 portENABLE_INTERRUPTS();
\r
300 /*-----------------------------------------------------------*/
\r
302 void __attribute__((__interrupt__, auto_psv)) _T1Interrupt( void )
\r
304 /* Clear the timer interrupt. */
\r
307 vTaskIncrementTick();
\r
309 #if configUSE_PREEMPTION == 1
\r