uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
port.c
Go to the documentation of this file.
1 /*
2  FreeRTOS V7.5.3 - Copyright (C) 2013 Real Time Engineers Ltd.
3  All rights reserved
4 
5  VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
6 
7  ***************************************************************************
8  * *
9  * FreeRTOS provides completely free yet professionally developed, *
10  * robust, strictly quality controlled, supported, and cross *
11  * platform software that has become a de facto standard. *
12  * *
13  * Help yourself get started quickly and support the FreeRTOS *
14  * project by purchasing a FreeRTOS tutorial book, reference *
15  * manual, or both from: http://www.FreeRTOS.org/Documentation *
16  * *
17  * Thank you! *
18  * *
19  ***************************************************************************
20 
21  This file is part of the FreeRTOS distribution.
22 
23  FreeRTOS is free software; you can redistribute it and/or modify it under
24  the terms of the GNU General Public License (version 2) as published by the
25  Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
26 
27  >>! NOTE: The modification to the GPL is included to allow you to distribute
28  >>! a combined work that includes FreeRTOS without being obliged to provide
29  >>! the source code for proprietary components outside of the FreeRTOS
30  >>! kernel.
31 
32  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
33  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34  FOR A PARTICULAR PURPOSE. Full license text is available from the following
35  link: http://www.freertos.org/a00114.html
36 
37  1 tab == 4 spaces!
38 
39  ***************************************************************************
40  * *
41  * Having a problem? Start by reading the FAQ "My application does *
42  * not run, what could be wrong?" *
43  * *
44  * http://www.FreeRTOS.org/FAQHelp.html *
45  * *
46  ***************************************************************************
47 
48  http://www.FreeRTOS.org - Documentation, books, training, latest versions,
49  license and Real Time Engineers Ltd. contact details.
50 
51  http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
52  including FreeRTOS+Trace - an indispensable productivity tool, a DOS
53  compatible FAT file system, and our tiny thread aware UDP/IP stack.
54 
55  http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
56  Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
57  licenses offer ticketed support, indemnification and middleware.
58 
59  http://www.SafeRTOS.com - High Integrity Systems also provide a safety
60  engineered and independently SIL3 certified version for use in safety and
61  mission critical applications that require provable dependability.
62 
63  1 tab == 4 spaces!
64 */
65 
66 /*-----------------------------------------------------------
67  * Implementation of functions defined in portable.h for the PIC32MX port.
68  *----------------------------------------------------------*/
69 
70 #ifndef __XC
71  #error This port is designed to work with XC32. Please update your C compiler version.
72 #endif
73 
74 /* Scheduler include files. */
75 #include "FreeRTOS.h"
76 #include "task.h"
77 
78 /* Hardware specifics. */
79 #define portTIMER_PRESCALE 8
80 #define portPRESCALE_BITS 1
81 
82 /* Bits within various registers. */
83 #define portIE_BIT ( 0x00000001 )
84 #define portEXL_BIT ( 0x00000002 )
85 
86 /* Bits within the CAUSE register. */
87 #define portCORE_SW_0 ( 0x00000100 )
88 #define portCORE_SW_1 ( 0x00000200 )
89 
90 /* The EXL bit is set to ensure interrupts do not occur while the context of
91 the first task is being restored. */
92 #define portINITIAL_SR ( portIE_BIT | portEXL_BIT )
93 
94 #ifndef configTICK_INTERRUPT_VECTOR
95  #define configTICK_INTERRUPT_VECTOR _TIMER_1_VECTOR
96 #endif
97 
98 /* Records the interrupt nesting depth. This starts at one as it will be
99 decremented to 0 when the first task starts. */
100 volatile unsigned portBASE_TYPE uxInterruptNesting = 0x01;
101 
102 /* Stores the task stack pointer when a switch is made to use the system stack. */
104 
105 /* The stack used by interrupt service routines that cause a context switch. */
106 portSTACK_TYPE xISRStack[ configISR_STACK_SIZE ] = { 0 };
107 
108 /* The top of stack value ensures there is enough space to store 6 registers on
109 the callers stack, as some functions seem to want to do this. */
110 const portSTACK_TYPE * const xISRStackTop = &( xISRStack[ configISR_STACK_SIZE - 7 ] );
111 
112 /*
113  * Place the prototype here to ensure the interrupt vector is correctly installed.
114  * Note that because the interrupt is written in assembly, the IPL setting in the
115  * following line of code has no effect. The interrupt priority is set by the
116  * call to ConfigIntTimer1() in vApplicationSetupTickTimerInterrupt().
117  */
118 extern void __attribute__( (interrupt(ipl1), vector( configTICK_INTERRUPT_VECTOR ))) vPortTickInterruptHandler( void );
119 
120 /*
121  * The software interrupt handler that performs the yield. Note that, because
122  * the interrupt is written in assembly, the IPL setting in the following line of
123  * code has no effect. The interrupt priority is set by the call to
124  * mConfigIntCoreSW0() in xPortStartScheduler().
125  */
126 void __attribute__( (interrupt(ipl1), vector(_CORE_SOFTWARE_0_VECTOR))) vPortYieldISR( void );
127 
128 /*-----------------------------------------------------------*/
129 
130 /*
131  * See header file for description.
132  */
133 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
134 {
135  /* Ensure byte alignment is maintained when leaving this function. */
136  pxTopOfStack--;
137 
138  *pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
139  pxTopOfStack--;
140 
141  *pxTopOfStack = (portSTACK_TYPE) 0x12345678; /* Word to which the stack pointer will be left pointing after context restore. */
142  pxTopOfStack--;
143 
144  *pxTopOfStack = (portSTACK_TYPE) _CP0_GET_CAUSE();
145  pxTopOfStack--;
146 
147  *pxTopOfStack = (portSTACK_TYPE) portINITIAL_SR; /* CP0_STATUS */
148  pxTopOfStack--;
149 
150  *pxTopOfStack = (portSTACK_TYPE) pxCode; /* CP0_EPC */
151  pxTopOfStack--;
152 
153  *pxTopOfStack = (portSTACK_TYPE) NULL; /* ra */
154  pxTopOfStack -= 15;
155 
156  *pxTopOfStack = (portSTACK_TYPE) pvParameters; /* Parameters to pass in */
157  pxTopOfStack -= 14;
158 
159  *pxTopOfStack = (portSTACK_TYPE) 0x00000000; /* critical nesting level - no longer used. */
160  pxTopOfStack--;
161 
162  return pxTopOfStack;
163 }
164 /*-----------------------------------------------------------*/
165 
166 /*
167  * Setup a timer for a regular tick. This function uses peripheral timer 1.
168  * The function is declared weak so an application writer can use a different
169  * timer by redefining this implementation. If a different timer is used then
170  * configTICK_INTERRUPT_VECTOR must also be defined in FreeRTOSConfig.h to
171  * ensure the RTOS provided tick interrupt handler is installed on the correct
172  * vector number. When Timer 1 is used the vector number is defined as
173  * _TIMER_1_VECTOR.
174  */
175 __attribute__(( weak )) void vApplicationSetupTickTimerInterrupt( void )
176 {
177 const unsigned long ulCompareMatch = ( (configPERIPHERAL_CLOCK_HZ / portTIMER_PRESCALE) / configTICK_RATE_HZ ) - 1;
178 
179  T1CON = 0x0000;
180  T1CONbits.TCKPS = portPRESCALE_BITS;
181  PR1 = ulCompareMatch;
182  IPC1bits.T1IP = configKERNEL_INTERRUPT_PRIORITY;
183 
184  /* Clear the interrupt as a starting condition. */
185  IFS0bits.T1IF = 0;
186 
187  /* Enable the interrupt. */
188  IEC0bits.T1IE = 1;
189 
190  /* Start the timer. */
191  T1CONbits.TON = 1;
192 }
193 /*-----------------------------------------------------------*/
194 
196 {
197  /* It is unlikely that the scheduler for the PIC port will get stopped
198  once running. If required disable the tick interrupt here, then return
199  to xPortStartScheduler(). */
200  for( ;; );
201 }
202 /*-----------------------------------------------------------*/
203 
205 {
206 extern void vPortStartFirstTask( void );
207 extern void *pxCurrentTCB;
208 
209  /* Clear the software interrupt flag. */
210  IFS0CLR = _IFS0_CS0IF_MASK;
211 
212  /* Set software timer priority. */
213  IPC0CLR = _IPC0_CS0IP_MASK;
214  IPC0SET = ( configKERNEL_INTERRUPT_PRIORITY << _IPC0_CS0IP_POSITION );
215 
216  /* Enable software interrupt. */
217  IEC0CLR = _IEC0_CS0IE_MASK;
218  IEC0SET = 1 << _IEC0_CS0IE_POSITION;
219 
220  /* Setup the timer to generate the tick. Interrupts will have been
221  disabled by the time we get here. */
222  vApplicationSetupTickTimerInterrupt();
223 
224  /* Kick off the highest priority task that has been created so far.
225  Its stack location is loaded into uxSavedTaskStackPointer. */
226  uxSavedTaskStackPointer = *( unsigned portBASE_TYPE * ) pxCurrentTCB;
227  vPortStartFirstTask();
228 
229  /* Should never get here as the tasks will now be executing. */
230  return pdFALSE;
231 }
232 /*-----------------------------------------------------------*/
233 
234 void vPortIncrementTick( void )
235 {
236 unsigned portBASE_TYPE uxSavedStatus;
237 
238  uxSavedStatus = uxPortSetInterruptMaskFromISR();
239  {
240  if( xTaskIncrementTick() != pdFALSE )
241  {
242  /* Pend a context switch. */
243  _CP0_BIS_CAUSE( portCORE_SW_0 );
244  }
245  }
246  vPortClearInterruptMaskFromISR( uxSavedStatus );
247 
248  /* Clear timer 1 interrupt. */
249  IFS0CLR = _IFS0_T1IF_MASK;
250 }
251 /*-----------------------------------------------------------*/
252 
254 {
255 unsigned portBASE_TYPE uxSavedStatusRegister;
256 
257  asm volatile ( "di" );
258  uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01;
259  /* This clears the IPL bits, then sets them to
260  configMAX_SYSCALL_INTERRUPT_PRIORITY. This function should not be called
261  from an interrupt that has a priority above
262  configMAX_SYSCALL_INTERRUPT_PRIORITY so, when used correctly, the action
263  can only result in the IPL being unchanged or raised, and therefore never
264  lowered. */
265  _CP0_SET_STATUS( ( ( uxSavedStatusRegister & ( ~portALL_IPL_BITS ) ) ) | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) );
266 
267  return uxSavedStatusRegister;
268 }
269 /*-----------------------------------------------------------*/
270 
271 void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatusRegister )
272 {
273  _CP0_SET_STATUS( uxSavedStatusRegister );
274 }
275 /*-----------------------------------------------------------*/
276 
277 
278 
279 
280