| 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_m0.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-M0 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 : ARMv6M Cortex-M0
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)0x01000000u; /* xPSR */
244 *--p_stk = (CPU_STK)p_task; /* Entry Point */
245 *--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
246 *--p_stk = (CPU_STK)0x12121212u; /* R12 */
247 *--p_stk = (CPU_STK)0x03030303u; /* R3 */
248 *--p_stk = (CPU_STK)0x02020202u; /* R2 */
249 *--p_stk = (CPU_STK)0x01010101u; /* R1 */
250 *--p_stk = (CPU_STK)p_arg; /* R0 : argument */
251 /* Remaining registers saved on process stack */
252 *--p_stk = (CPU_STK)0x07070707u; /* R7 */
253 *--p_stk = (CPU_STK)0x06060606u; /* R6 */
254 *--p_stk = (CPU_STK)0x05050505u; /* R5 */
255 *--p_stk = (CPU_STK)0x04040404u; /* R4 */
256 *--p_stk = (CPU_STK)0x11111111u; /* R11 */
257 *--p_stk = (CPU_STK)0x10101010u; /* R10 */
258 *--p_stk = (CPU_STK)0x09090909u; /* R9 */
259 *--p_stk = (CPU_STK)0x08080808u; /* R8 */
260
261
262 return (p_stk);
263 }
264
265
266 /*$PAGE*/
267 /*
268 *********************************************************************************************************
269 * TASK SWITCH HOOK
270 *
271 * Description: This function is called when a task switch is performed. This allows you to perform other
272 * operations during a context switch.
273 *
274 * Arguments : None.
275 *
276 * Note(s) : 1) Interrupts are disabled during this call.
277 * 2) It is assumed that the global pointer 'OSTCBHighRdyPtr' points to the TCB of the task
278 * that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
279 * to the task being switched out (i.e. the preempted task).
280 *********************************************************************************************************
281 */
282
283 void OSTaskSwHook (void)
284 {
285 #if OS_CFG_TASK_PROFILE_EN > 0u
286 CPU_TS ts;
287 #endif
288 #ifdef CPU_CFG_INT_DIS_MEAS_EN
289 CPU_TS int_dis_time;
290 #endif
291
292
293
294 #if OS_CFG_APP_HOOKS_EN > 0u
295 if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
296 (*OS_AppTaskSwHookPtr)();
297 }
298 #endif
299
300 #if OS_CFG_TASK_PROFILE_EN > 0u
301 ts = OS_TS_GET();
302 if (OSTCBCurPtr != OSTCBHighRdyPtr) {
303 OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
304 OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
305 }
306
307 OSTCBHighRdyPtr->CyclesStart = ts;
308 #endif
309
310 #ifdef CPU_CFG_INT_DIS_MEAS_EN
311 int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
312 if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
313 OSTCBCurPtr->IntDisTimeMax = int_dis_time;
314 }
315 #endif
316
317 #if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
318 /* Keep track of per-task scheduler lock time */
319 if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
320 OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
321 }
322 OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
323 #endif
324 }
325
326
327 /*$PAGE*/
328 /*
329 *********************************************************************************************************
330 * TICK HOOK
331 *
332 * Description: This function is called every tick.
333 *
334 * Arguments : None.
335 *
336 * Note(s) : 1) This function is assumed to be called from the Tick ISR.
337 *********************************************************************************************************
338 */
339
340 void OSTimeTickHook (void)
341 {
342 #if OS_CFG_APP_HOOKS_EN > 0u
343 if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
344 (*OS_AppTimeTickHookPtr)();
345 }
346 #endif
347 }
348
349 CPU_DATA CPU_CntLeadZeros(CPU_DATA val)
350 {
351 return __clz(val);
352 }
353
354
355 #if configUSE_CUSTOM_TICK == 0
356
357 /*$PAGE*/
358 /*
359 *********************************************************************************************************
360 * SYS TICK HANDLER
361 *
362 * Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
363 * interrupt.
364 *
365 * Arguments : None.
366 *
367 * Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
368 *********************************************************************************************************
369 */
370
371 void OS_CPU_SysTickHandler (void)
372 {
373 CPU_SR_ALLOC();
374
375
376 CPU_CRITICAL_ENTER();
377 OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
378 CPU_CRITICAL_EXIT();
379
380 OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
381
382 OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
383 }
384
385
386 /*$PAGE*/
387 /*
388 *********************************************************************************************************
389 * INITIALIZE SYS TICK
390 *
391 * Description: Initialize the SysTick.
392 *
393 * Arguments : cnts Number of SysTick counts between two OS tick interrupts.
394 *
395 * Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
396 *********************************************************************************************************
397 */
398
399 void OS_CPU_SysTickInit (CPU_INT32U cnts)
400 {
401 CPU_INT32U prio;
402
403
404 CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
405
406 /* Set SysTick handler prio. */
407 prio = CPU_REG_NVIC_SHPRI3;
408 prio &= DEF_BIT_FIELD(24, 0);
409 prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
410
411 CPU_REG_NVIC_SHPRI3 = prio;
412
413 /* Enable timer. */
414 CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
415 CPU_REG_NVIC_ST_CTRL_ENABLE;
416 /* Enable timer interrupt. */
417 CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
418 }
419
420 #endif