| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
os_cpu_c.c
Go to the documentation of this file.
1 /*
2 *********************************************************************************************************
3 * uC/OS-III
4 * The Real-Time Kernel
5 *
6 *
7 * (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
8 * All rights reserved. Protected by international copyright laws.
9 *
10 * ARM Cortex-M4 Port
11 *
12 * File : OS_CPU_C.C
13 * Version : V3.01.2
14 * By : JJL
15 * BAN
16 *
17 * LICENSING TERMS:
18 * ---------------
19 * uC/OS-III is provided in source form to registered licensees ONLY. It is
20 * illegal to distribute this source code to any third party unless you receive
21 * written permission by an authorized Micrium representative. Knowledge of
22 * the source code may NOT be used to develop a similar product.
23 *
24 * Please help us continue to provide the Embedded community with the finest
25 * software available. Your honesty is greatly appreciated.
26 *
27 * You can contact us at www.micrium.com.
28 *
29 * For : ARMv7M Cortex-M4
30 * Mode : Thumb2
31 * Toolchain : RealView
32 *********************************************************************************************************
33 */
34
35 #define OS_CPU_GLOBALS
36
37 #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
38 const CPU_CHAR *os_cpu_c__c = "$Id: $";
39 #endif
40
41 /*$PAGE*/
42 /*
43 *********************************************************************************************************
44 * INCLUDE FILES
45 *********************************************************************************************************
46 */
47
48 #include <os.h>
49
50 /*
51 *********************************************************************************************************
52 * IDLE TASK HOOK
53 *
54 * Description: This function is called by the idle task. This hook has been added to allow you to do
55 * such things as STOP the CPU to conserve power.
56 *
57 * Arguments : None.
58 *
59 * Note(s) : None.
60 *********************************************************************************************************
61 */
62
63 void OSIdleTaskHook (void)
64 {
65 #if OS_CFG_APP_HOOKS_EN > 0u
66 if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
67 (*OS_AppIdleTaskHookPtr)();
68 }
69 #endif
70 }
71
72
73 /*$PAGE*/
74 /*
75 *********************************************************************************************************
76 * OS INITIALIZATION HOOK
77 *
78 * Description: This function is called by OSInit() at the beginning of OSInit().
79 *
80 * Arguments : None.
81 *
82 * Note(s) : None.
83 *********************************************************************************************************
84 */
85
86 void OSInitHook (void)
87 {
88 CPU_STK_SIZE i;
89 CPU_STK *p_stk;
90
91
92 p_stk = OSCfg_ISRStkBasePtr; /* Clear the ISR stack */
93 for (i = 0u; i < OSCfg_ISRStkSize; i++) {
94 *p_stk++ = (CPU_STK)0u;
95 }
96 OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u);
97 }
98
99
100 /*$PAGE*/
101 /*
102 *********************************************************************************************************
103 * STATISTIC TASK HOOK
104 *
105 * Description: This function is called every second by uC/OS-III's statistics task. This allows your
106 * application to add functionality to the statistics task.
107 *
108 * Arguments : None.
109 *
110 * Note(s) : None.
111 *********************************************************************************************************
112 */
113
114 void OSStatTaskHook (void)
115 {
116 #if OS_CFG_APP_HOOKS_EN > 0u
117 if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
118 (*OS_AppStatTaskHookPtr)();
119 }
120 #endif
121 }
122
123
124 /*$PAGE*/
125 /*
126 *********************************************************************************************************
127 * TASK CREATION HOOK
128 *
129 * Description: This function is called when a task is created.
130 *
131 * Arguments : p_tcb Pointer to the task control block of the task being created.
132 *
133 * Note(s) : None.
134 *********************************************************************************************************
135 */
136
137 void OSTaskCreateHook (OS_TCB *p_tcb)
138 {
139 #if OS_CFG_APP_HOOKS_EN > 0u
140 if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
141 (*OS_AppTaskCreateHookPtr)(p_tcb);
142 }
143 #else
144 (void)p_tcb; /* Prevent compiler warning */
145 #endif
146 }
147
148
149 /*$PAGE*/
150 /*
151 *********************************************************************************************************
152 * TASK DELETION HOOK
153 *
154 * Description: This function is called when a task is deleted.
155 *
156 * Arguments : p_tcb Pointer to the task control block of the task being deleted.
157 *
158 * Note(s) : None.
159 *********************************************************************************************************
160 */
161
162 void OSTaskDelHook (OS_TCB *p_tcb)
163 {
164 #if OS_CFG_APP_HOOKS_EN > 0u
165 if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
166 (*OS_AppTaskDelHookPtr)(p_tcb);
167 }
168 #else
169 (void)p_tcb; /* Prevent compiler warning */
170 #endif
171 }
172
173
174 /*$PAGE*/
175 /*
176 *********************************************************************************************************
177 * TASK RETURN HOOK
178 *
179 * Description: This function is called if a task accidentally returns. In other words, a task should
180 * either be an infinite loop or delete itself when done.
181 *
182 * Arguments : p_tcb Pointer to the task control block of the task that is returning.
183 *
184 * Note(s) : None.
185 *********************************************************************************************************
186 */
187
188 void OSTaskReturnHook (OS_TCB *p_tcb)
189 {
190 #if OS_CFG_APP_HOOKS_EN > 0u
191 if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
192 (*OS_AppTaskReturnHookPtr)(p_tcb);
193 }
194 #else
195 (void)p_tcb; /* Prevent compiler warning */
196 #endif
197 }
198
199
200 /*$PAGE*/
201 /*
202 **********************************************************************************************************
203 * INITIALIZE A TASK'S STACK
204 *
205 * Description: This function is called by OS_Task_Create() or OSTaskCreateExt() to initialize the stack
206 * frame of the task being created. This function is highly processor specific.
207 *
208 * Arguments : p_task Pointer to the task entry point address.
209 *
210 * p_arg Pointer to a user supplied data area that will be passed to the task
211 * when the task first executes.
212 *
213 * p_stk_base Pointer to the base address of the stack.
214 *
215 * stk_size Size of the stack, in number of CPU_STK elements.
216 *
217 * opt Options used to alter the behavior of OS_Task_StkInit().
218 * (see OS.H for OS_TASK_OPT_xxx).
219 *
220 * Returns : Always returns the location of the new top-of-stack' once the processor registers have
221 * been placed on the stack in the proper order.
222 *
223 * Note(s) : 1) Interrupts are enabled when task starts executing.
224 *
225 * 2) All tasks run in Thread mode, using process stack.
226 **********************************************************************************************************
227 */
228
229 CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
230 void *p_arg,
231 CPU_STK *p_stk_base,
232 CPU_STK *p_stk_limit,
233 CPU_STK_SIZE stk_size,
234 OS_OPT opt)
235 {
236 CPU_STK *p_stk;
237
238
239 (void)opt; /* Prevent compiler warning */
240
241 p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
242 /* Registers stacked as if auto-saved on exception */
243 *--p_stk = (CPU_STK)0xDEADBEAF;
244 *--p_stk = (CPU_STK)0xDEADBEAF;
245 *--p_stk = (CPU_STK)0xDEADBEAF;
246 *--p_stk = (CPU_STK)0xDEADBEAF;
247 *--p_stk = (CPU_STK)0xDEADBEAF;
248 *--p_stk = (CPU_STK)0xDEADBEAF;
249 *--p_stk = (CPU_STK)0xDEADBEAF;
250 *--p_stk = (CPU_STK)0xDEADBEAF;
251 *--p_stk = (CPU_STK)0xDEADBEAF;
252 *--p_stk = (CPU_STK)0xDEADBEAF;
253 *--p_stk = (CPU_STK)0xDEADBEAF;
254 *--p_stk = (CPU_STK)0xDEADBEAF;
255 *--p_stk = (CPU_STK)0xDEADBEAF;
256 *--p_stk = (CPU_STK)0xDEADBEAF;
257 *--p_stk = (CPU_STK)0xDEADBEAF;
258 *--p_stk = (CPU_STK)0xDEADBEAF;
259 *--p_stk = (CPU_STK)0xDEADBEAF;
260 *--p_stk = (CPU_STK)0xDEADBEAF;
261 *--p_stk = (CPU_STK)0x01000000u; /* xPSR */
262 *--p_stk = (CPU_STK)p_task; /* Entry Point */
263 *--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
264 *--p_stk = (CPU_STK)0x12121212u; /* R12 */
265 *--p_stk = (CPU_STK)0x03030303u; /* R3 */
266 *--p_stk = (CPU_STK)0x02020202u; /* R2 */
267 *--p_stk = (CPU_STK)p_stk_limit; /* R1 */
268 *--p_stk = (CPU_STK)p_arg; /* R0 : argument */
269 /* Remaining registers saved on process stack */
270 *--p_stk = (CPU_STK)0x11111111u; /* R11 */
271 *--p_stk = (CPU_STK)0x10101010u; /* R10 */
272 *--p_stk = (CPU_STK)0x09090909u; /* R9 */
273 *--p_stk = (CPU_STK)0x08080808u; /* R8 */
274 *--p_stk = (CPU_STK)0x07070707u; /* R7 */
275 *--p_stk = (CPU_STK)0x06060606u; /* R6 */
276 *--p_stk = (CPU_STK)0x05050505u; /* R5 */
277 *--p_stk = (CPU_STK)0x04040404u; /* R4 */
278
279 *--p_stk = (CPU_STK)0xDEADBEAF;
280 *--p_stk = (CPU_STK)0xDEADBEAF;
281 *--p_stk = (CPU_STK)0xDEADBEAF;
282 *--p_stk = (CPU_STK)0xDEADBEAF;
283 *--p_stk = (CPU_STK)0xDEADBEAF;
284 *--p_stk = (CPU_STK)0xDEADBEAF;
285 *--p_stk = (CPU_STK)0xDEADBEAF;
286 *--p_stk = (CPU_STK)0xDEADBEAF;
287 *--p_stk = (CPU_STK)0xDEADBEAF;
288 *--p_stk = (CPU_STK)0xDEADBEAF;
289 *--p_stk = (CPU_STK)0xDEADBEAF;
290 *--p_stk = (CPU_STK)0xDEADBEAF;
291 *--p_stk = (CPU_STK)0xDEADBEAF;
292 *--p_stk = (CPU_STK)0xDEADBEAF;
293 *--p_stk = (CPU_STK)0xDEADBEAF;
294 *--p_stk = (CPU_STK)0xDEADBEAF;
295 *--p_stk = (CPU_STK)0xFFFFFFED; /* R14 (LR) */
296
297 return (p_stk);
298 }
299
300
301 /*$PAGE*/
302 /*
303 *********************************************************************************************************
304 * TASK SWITCH HOOK
305 *
306 * Description: This function is called when a task switch is performed. This allows you to perform other
307 * operations during a context switch.
308 *
309 * Arguments : None.
310 *
311 * Note(s) : 1) Interrupts are disabled during this call.
312 * 2) It is assumed that the global pointer 'OSTCBHighRdyPtr' points to the TCB of the task
313 * that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
314 * to the task being switched out (i.e. the preempted task).
315 *********************************************************************************************************
316 */
317
318 void OSTaskSwHook (void)
319 {
320 #if OS_CFG_TASK_PROFILE_EN > 0u
321 CPU_TS ts;
322 #endif
323 #ifdef CPU_CFG_INT_DIS_MEAS_EN
324 CPU_TS int_dis_time;
325 #endif
326
327
328
329 #if OS_CFG_APP_HOOKS_EN > 0u
330 if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
331 (*OS_AppTaskSwHookPtr)();
332 }
333 #endif
334
335 #if OS_CFG_TASK_PROFILE_EN > 0u
336 ts = OS_TS_GET();
337 if (OSTCBCurPtr != OSTCBHighRdyPtr) {
338 OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
339 OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
340 }
341
342 OSTCBHighRdyPtr->CyclesStart = ts;
343 #endif
344
345 #ifdef CPU_CFG_INT_DIS_MEAS_EN
346 int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
347 if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
348 OSTCBCurPtr->IntDisTimeMax = int_dis_time;
349 }
350 #endif
351
352 #if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
353 /* Keep track of per-task scheduler lock time */
354 if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
355 OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
356 }
357 OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
358 #endif
359 }
360
361
362 /*$PAGE*/
363 /*
364 *********************************************************************************************************
365 * TICK HOOK
366 *
367 * Description: This function is called every tick.
368 *
369 * Arguments : None.
370 *
371 * Note(s) : 1) This function is assumed to be called from the Tick ISR.
372 *********************************************************************************************************
373 */
374
375 void OSTimeTickHook (void)
376 {
377 #if OS_CFG_APP_HOOKS_EN > 0u
378 if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
379 (*OS_AppTimeTickHookPtr)();
380 }
381 #endif
382 }
383
384
385 /*$PAGE*/
386 /*
387 *********************************************************************************************************
388 * SYS TICK HANDLER
389 *
390 * Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
391 * interrupt.
392 *
393 * Arguments : None.
394 *
395 * Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
396 *********************************************************************************************************
397 */
398
399 void OS_CPU_SysTickHandler (void)
400 {
401 CPU_SR_ALLOC();
402
403
404 CPU_CRITICAL_ENTER();
405 OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
406 CPU_CRITICAL_EXIT();
407
408 OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
409
410 OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
411 }
412
413
414 /*$PAGE*/
415 /*
416 *********************************************************************************************************
417 * INITIALIZE SYS TICK
418 *
419 * Description: Initialize the SysTick.
420 *
421 * Arguments : cnts Number of SysTick counts between two OS tick interrupts.
422 *
423 * Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
424 *********************************************************************************************************
425 */
426
427 void OS_CPU_SysTickInit (CPU_INT32U cnts)
428 {
429 CPU_INT32U prio;
430
431
432 CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
433
434 /* Set SysTick handler prio. */
435 prio = CPU_REG_NVIC_SHPRI3;
436 prio &= DEF_BIT_FIELD(24, 0);
437 prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
438
439 CPU_REG_NVIC_SHPRI3 = prio;
440
441 /* Enable timer. */
442 CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
443 CPU_REG_NVIC_ST_CTRL_ENABLE;
444 /* Enable timer interrupt. */
445 CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
446 }
447