Project

General

Profile

Download (7.87 KB) Statistics
| Branch: | Tag: | Revision:
1
/*
2
	FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
3

    
4
	This file is part of the FreeRTOS.org distribution.
5

    
6
	FreeRTOS.org is free software; you can redistribute it and/or modify
7
	it under the terms of the GNU General Public License as published by
8
	the Free Software Foundation; either version 2 of the License, or
9
	(at your option) any later version.
10

    
11
	FreeRTOS.org is distributed in the hope that it will be useful,
12
	but WITHOUT ANY WARRANTY; without even the implied warranty of
13
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
	GNU General Public License for more details.
15

    
16
	You should have received a copy of the GNU General Public License
17
	along with FreeRTOS.org; if not, write to the Free Software
18
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19

    
20
	A special exception to the GPL can be applied should you wish to distribute
21
	a combined work that includes FreeRTOS.org, without being obliged to provide
22
	the source code for any proprietary components.  See the licensing section 
23
	of http://www.FreeRTOS.org for full details of how and when the exception
24
	can be applied.
25

    
26
	***************************************************************************
27
	See http://www.FreeRTOS.org for documentation, latest information, license 
28
	and contact details.  Please ensure to read the configuration and relevant 
29
	port sections of the online documentation.
30

    
31
	Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
32
	with commercial development and support options.
33
	***************************************************************************
34
*/
35

    
36

    
37
/*-----------------------------------------------------------
38
 * Implementation of functions defined in portable.h for the ARM7 port.
39
 *
40
 * Components that can be compiled to either ARM or THUMB mode are
41
 * contained in this file.  The ISR routines, which can only be compiled
42
 * to ARM mode are contained in portISR.c.
43
 *----------------------------------------------------------*/
44

    
45
/*
46
	Changes from V2.5.2
47
		
48
	+ ulCriticalNesting is now saved as part of the task context, as is 
49
	  therefore added to the initial task stack during pxPortInitialiseStack.
50
*/
51

    
52

    
53
/* Standard includes. */
54
#include <stdlib.h>
55

    
56
/* Scheduler includes. */
57
#include "FreeRTOS.h"
58
#include "task.h"
59

    
60
/* Processor constants. */
61
#include "AT91SAM7.h"
62
#include "lib_AT91SAM7.h"
63

    
64
/* Constants required to setup the task context. */
65
#define portINITIAL_SPSR				( ( portSTACK_TYPE ) 0x1f )	/* System mode, ARM mode, interrupts enabled. */
66
#define portTHUMB_MODE_BIT				( ( portSTACK_TYPE ) 0x20 )
67
#define portINSTRUCTION_SIZE			( ( portSTACK_TYPE ) 4 )
68
#define portNO_CRITICAL_SECTION_NESTING	( ( portSTACK_TYPE ) 0 )
69

    
70
/* Constants required to setup the tick ISR. */
71
#define portENABLE_TIMER			( ( unsigned portCHAR ) 0x01 )
72
#define portPRESCALE_VALUE			0x00
73
#define portINTERRUPT_ON_MATCH		( ( unsigned portLONG ) 0x01 )
74
#define portRESET_COUNT_ON_MATCH	( ( unsigned portLONG ) 0x02 )
75

    
76
/* Constants required to setup the PIT. */
77
#define portPIT_CLOCK_DIVISOR			( ( unsigned portLONG ) 16 )
78
#define portPIT_COUNTER_VALUE			( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_RATE_MS )
79

    
80
#define portINT_LEVEL_SENSITIVE  0
81
#define portPIT_ENABLE      	( ( unsigned portSHORT ) 0x1 << 24 )
82
#define portPIT_INT_ENABLE     	( ( unsigned portSHORT ) 0x1 << 25 )
83
/*-----------------------------------------------------------*/
84

    
85
/* Setup the timer to generate the tick interrupts. */
86
static void prvSetupTimerInterrupt (void);
87

    
88
/* 
89
 * The scheduler can only be started from ARM mode, so 
90
 * vPortISRStartFirstSTask() is defined in portISR.c. 
91
 */
92
extern void vPortISRStartFirstTask (void);
93

    
94
/*-----------------------------------------------------------*/
95

    
96
/* 
97
 * Initialise the stack of a task to look exactly as if a call to 
98
 * portSAVE_CONTEXT had been called.
99
 *
100
 * See header file for description. 
101
 */
102
portSTACK_TYPE *
103
pxPortInitialiseStack (portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode,
104
		       void *pvParameters)
105
{
106
  portSTACK_TYPE *pxOriginalTOS;
107

    
108
  pxOriginalTOS = pxTopOfStack;
109

    
110
  /* Setup the initial stack of the task.  The stack is set exactly as 
111
     expected by the portRESTORE_CONTEXT() macro. */
112

    
113
  /* First on the stack is the return address - which in this case is the
114
     start of the task.  The offset is added to make the return address appear
115
     as it would within an IRQ ISR. */
116
  *pxTopOfStack = (portSTACK_TYPE) pxCode + portINSTRUCTION_SIZE;
117
  pxTopOfStack--;
118

    
119
  *pxTopOfStack = (portSTACK_TYPE) 0xaaaaaaaa;	/* R14 */
120
  pxTopOfStack--;
121
  *pxTopOfStack = (portSTACK_TYPE) pxOriginalTOS;	/* Stack used when task starts goes in R13. */
122
  pxTopOfStack--;
123
  *pxTopOfStack = (portSTACK_TYPE) 0x12121212;	/* R12 */
124
  pxTopOfStack--;
125
  *pxTopOfStack = (portSTACK_TYPE) 0x11111111;	/* R11 */
126
  pxTopOfStack--;
127
  *pxTopOfStack = (portSTACK_TYPE) 0x10101010;	/* R10 */
128
  pxTopOfStack--;
129
  *pxTopOfStack = (portSTACK_TYPE) 0x09090909;	/* R9 */
130
  pxTopOfStack--;
131
  *pxTopOfStack = (portSTACK_TYPE) 0x08080808;	/* R8 */
132
  pxTopOfStack--;
133
  *pxTopOfStack = (portSTACK_TYPE) 0x07070707;	/* R7 */
134
  pxTopOfStack--;
135
  *pxTopOfStack = (portSTACK_TYPE) 0x06060606;	/* R6 */
136
  pxTopOfStack--;
137
  *pxTopOfStack = (portSTACK_TYPE) 0x05050505;	/* R5 */
138
  pxTopOfStack--;
139
  *pxTopOfStack = (portSTACK_TYPE) 0x04040404;	/* R4 */
140
  pxTopOfStack--;
141
  *pxTopOfStack = (portSTACK_TYPE) 0x03030303;	/* R3 */
142
  pxTopOfStack--;
143
  *pxTopOfStack = (portSTACK_TYPE) 0x02020202;	/* R2 */
144
  pxTopOfStack--;
145
  *pxTopOfStack = (portSTACK_TYPE) 0x01010101;	/* R1 */
146
  pxTopOfStack--;
147

    
148
  /* When the task starts is will expect to find the function parameter in
149
     R0. */
150
  *pxTopOfStack = (portSTACK_TYPE) pvParameters;	/* R0 */
151
  pxTopOfStack--;
152

    
153
  /* The last thing onto the stack is the status register, which is set for
154
     system mode, with interrupts enabled. */
155
  *pxTopOfStack = (portSTACK_TYPE) portINITIAL_SPSR;
156

    
157
#ifdef THUMB_INTERWORK
158
  {
159
    /* We want the task to start in thumb mode. */
160
    *pxTopOfStack |= portTHUMB_MODE_BIT;
161
  }
162
#endif
163

    
164
  pxTopOfStack--;
165

    
166
  /* Some optimisation levels use the stack differently to others.  This 
167
     means the interrupt flags cannot always be stored on the stack and will
168
     instead be stored in a variable, which is then saved as part of the
169
     tasks context. */
170
  *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
171

    
172
  return pxTopOfStack;
173
}
174

    
175
/*-----------------------------------------------------------*/
176

    
177
portBASE_TYPE
178
xPortStartScheduler (void)
179
{
180
  /* Start the timer that generates the tick ISR.  Interrupts are disabled
181
     here already. */
182
  prvSetupTimerInterrupt ();
183

    
184
  /* Start the first task. */
185
  vPortISRStartFirstTask ();
186

    
187
  /* Should not get here! */
188
  return 0;
189
}
190

    
191
/*-----------------------------------------------------------*/
192

    
193
void
194
vPortEndScheduler (void)
195
{
196
  /* It is unlikely that the ARM port will require this function as there
197
     is nothing to return to.  */
198
}
199

    
200
/*-----------------------------------------------------------*/
201

    
202
/*
203
 * Setup the timer 0 to generate the tick interrupts at the required frequency.
204
 */
205
static void
206
prvSetupTimerInterrupt (void)
207
{
208
  AT91PS_PITC pxPIT = AT91C_BASE_PITC;
209

    
210
  /* Setup the AIC for PIT interrupts.  The interrupt routine chosen depends
211
     on whether the preemptive or cooperative scheduler is being used. */
212
#if configUSE_PREEMPTION == 0
213

    
214
  extern void (vNonPreemptiveTick) (void);
215
  AT91F_AIC_ConfigureIt (AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST,
216
			 portINT_LEVEL_SENSITIVE,
217
			 (void (*)(void)) vNonPreemptiveTick);
218

    
219
#else
220

    
221
  extern void (vPreemptiveTick) (void);
222
  AT91F_AIC_ConfigureIt (AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST,
223
			 portINT_LEVEL_SENSITIVE,
224
			 (void (*)(void)) vPreemptiveTick);
225

    
226
#endif
227

    
228
  /* Configure the PIT period. */
229
  pxPIT->PITC_PIMR =
230
    portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
231

    
232
  /* Enable the interrupt.  Global interrupts are disables at this point so 
233
     this is safe. */
234
  AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
235
}
236

    
237
/*-----------------------------------------------------------*/
(4-4/6)
Add picture from clipboard (Maximum size: 48.8 MB)