LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 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 
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 
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 
372 {
373  CPU_SR_ALLOC();
374 
375 
377  OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
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 
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);
410 
411  CPU_REG_NVIC_SHPRI3 = prio;
412 
413  /* Enable timer. */
416  /* Enable timer interrupt. */
418 }
419 
420 #endif