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