www.pudn.com > uCOSV262.rar > os_task.lst


C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 1


C51 COMPILER V8.05a, COMPILATION OF MODULE OS_TASK
OBJECT MODULE PLACED IN ..\Output\os_task.obj
COMPILER INVOKED BY: D:\Program Files\keil\C51\BIN\C51.EXE ..\SOURCE\os_task.c LARGE BROWSE INCDIR(..\app;..\Main;..\Por
-t;..\SOURCE) DEBUG OBJECTEXTEND PRINT(..\Output\os_task.lst) OBJECT(..\Output\os_task.obj)

line level source

1 /*
2 *********************************************************************************************************
3 * uC/OS-II
4 * The Real-Time Kernel
5 * TASK MANAGEMENT
6 *
7 * (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
8 * All Rights Reserved
9 *
10 * File : OS_TASK.C
11 * By : Jean J. Labrosse
12 *********************************************************************************************************
13 */
14
15 #ifndef OS_MASTER_FILE
16 #include "includes.h"
17 #endif
18
19 /*
20 *********************************************************************************************************
21 * CHANGE PRIORITY OF A TASK
22 *
23 * Description: This function allows you to change the priority of a task dynamically. Note that the new
24 * priority MUST be available.
25 *
26 * Arguments : oldp is the old priority
27 *
28 * newp is the new priority
29 *
30 * Returns : OS_NO_ERR is the call was successful
31 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
32 * (i.e. >= OS_LOWEST_PRIO)
33 * OS_PRIO_EXIST if the new priority already exist.
34 * OS_PRIO_ERR there is no task with the specified OLD priority (i.e. the OLD task does
35 * not exist.
36 *********************************************************************************************************
37 */
38
39 #if OS_TASK_CHANGE_PRIO_EN > 0
40 INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio) KCREENTRANT
41 {
42 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
45 1
46 1 #if OS_EVENT_EN > 0
OS_EVENT *pevent;
#endif
49 1
50 1 OS_TCB *ptcb;
51 1 INT8U x;
52 1 INT8U y;
53 1 INT8U bitx;
54 1 INT8U bity;
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 2

55 1 INT8U y_old;
56 1
57 1
58 1 #if OS_ARG_CHK_EN > 0
59 1 if (oldprio >= OS_LOWEST_PRIO) {
60 2 if (oldprio != OS_PRIO_SELF) {
61 3 return (OS_PRIO_INVALID);
62 3 }
63 2 }
64 1 if (newprio >= OS_LOWEST_PRIO) {
65 2 return (OS_PRIO_INVALID);
66 2 }
67 1 #endif
68 1 OS_ENTER_CRITICAL();
69 1 if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */
70 2 OS_EXIT_CRITICAL();
71 2 return (OS_PRIO_EXIST);
72 2 }
73 1 if (oldprio == OS_PRIO_SELF) { /* See if changing self */
74 2 oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */
75 2 }
76 1 ptcb = OSTCBPrioTbl[oldprio];
77 1 if (ptcb == (OS_TCB *)0) { /* Does task to change exist? */
78 2 OS_EXIT_CRITICAL(); /* No, can't change its priority! */
79 2 return (OS_PRIO_ERR);
80 2 }
81 1 y = newprio >> 3; /* Yes, compute new TCB fields */
82 1 bity = OSMapTbl[y];
83 1 x = newprio &amt; 0x07;
84 1 bitx = OSMapTbl[x];
85 1 OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */
86 1 OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */
87 1 y_old = ptcb->OSTCBY;
88 1 if ((OSRdyTbl[y_old] &amt; ptcb->OSTCBBitX) != 0x00) { /* If task is ready make it not */
89 2 OSRdyTbl[y_old] &amt;= ~ptcb->OSTCBBitX;
90 2 if (OSRdyTbl[y_old] == 0x00) {
91 3 OSRdyGrp &amt;= ~ptcb->OSTCBBitY;
92 3 }
93 2 OSRdyGrp |= bity; /* Make new priority ready to run */
94 2 OSRdyTbl[y] |= bitx;
95 2 #if OS_EVENT_EN > 0
} else { /* Task was not ready ... */
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0) { /* ... remove from event wait list */
pevent->OSEventTbl[y_old] &amt;= ~ptcb->OSTCBBitX;
if (pevent->OSEventTbl[y_old] == 0) {
pevent->OSEventGrp &amt;= ~ptcb->OSTCBBitY;
}
pevent->OSEventGrp |= bity; /* Add new priority to wait list */
pevent->OSEventTbl[y] |= bitx;
}
#endif
107 2 }
108 1 ptcb->OSTCBPrio = newprio; /* Set new task priority */
109 1 ptcb->OSTCBY = y;
110 1 ptcb->OSTCBX = x;
111 1 ptcb->OSTCBBitY = bity;
112 1 ptcb->OSTCBBitX = bitx;
113 1 OS_EXIT_CRITICAL();
114 1 OS_Sched(); /* Run highest priority task ready */
115 1 return (OS_NO_ERR);
116 1 }
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 3

117 #endif
118 /*$PAGE*/
119 /*
120 *********************************************************************************************************
121 * CREATE A TASK
122 *
123 * Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either
124 * be created prior to the start of multitasking or by a running task. A task cannot be
125 * created by an ISR.
126 *
127 * Arguments : task is a pointer to the task's code
128 *
129 * pdata is a pointer to an optional data area which can be used to pass parameters to
130 * the task when the task first executes. Where the task is concerned it thinks
131 * it was invoked and passed the argument 'pdata' as follows:
132 *
133 * void Task (void *pdata)
134 * {
135 * for (;;) {
136 * Task code;
137 * }
138 * }
139 *
140 * ptos is a pointer to the task's top of stack. If the configuration constant
141 * OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
142 * memory to low memory). 'pstk' will thus point to the highest (valid) memory
143 * location of the stack. If OS_STK_GROWTH is set to 0, 'pstk' will point to the
144 * lowest memory location of the stack and the stack will grow with increasing
145 * memory locations.
146 *
147 * prio is the task's priority. A unique priority MUST be assigned to each task and the
148 * lower the number, the higher the priority.
149 *
150 * Returns : OS_NO_ERR if the function was successful.
151 * OS_PRIO_EXIT if the task priority already exist
152 * (each task MUST have a unique priority).
153 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
154 * (i.e. >= OS_LOWEST_PRIO)
155 *********************************************************************************************************
156 */
157
158 #if OS_TASK_CREATE_EN > 0
159 INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio) KCREENTRANT
160 {
161 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
164 1 OS_STK *psp;
165 1 INT8U err;
166 1
167 1
168 1 #if OS_ARG_CHK_EN > 0
169 1 if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
170 2 return (OS_PRIO_INVALID);
171 2 }
172 1 #endif
173 1 OS_ENTER_CRITICAL();
174 1 if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
175 2 OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */
176 2 /* ... the same thing until task is created. */
177 2 OS_EXIT_CRITICAL();
178 2 psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* Initialize the task's stack */
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 4

179 2 err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
180 2 if (err == OS_NO_ERR) {
181 3 OS_ENTER_CRITICAL();
182 3 OSTaskCtr++; /* Increment the #tasks counter */
183 3 OS_EXIT_CRITICAL();
184 3 if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */
185 4 OS_Sched();
186 4 }
187 3 } else {
188 3 OS_ENTER_CRITICAL();
189 3 OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
190 3 OS_EXIT_CRITICAL();
191 3 }
192 2 return (err);
193 2 }
194 1 OS_EXIT_CRITICAL();
195 1 return (OS_PRIO_EXIST);
196 1 }
197 #endif
198 /*$PAGE*/
199 /*
200 *********************************************************************************************************
201 * CREATE A TASK (Extended Version)
202 *
203 * Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either
204 * be created prior to the start of multitasking or by a running task. A task cannot be
205 * created by an ISR. This function is similar to OSTaskCreate() except that it allows
206 * additional information about a task to be specified.
207 *
208 * Arguments : task is a pointer to the task's code
209 *
210 * pdata is a pointer to an optional data area which can be used to pass parameters to
211 * the task when the task first executes. Where the task is concerned it thinks
212 * it was invoked and passed the argument 'pdata' as follows:
213 *
214 * void Task (void *pdata)
215 * {
216 * for (;;) {
217 * Task code;
218 * }
219 * }
220 *
221 * ptos is a pointer to the task's top of stack. If the configuration constant
222 * OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
223 * memory to low memory). 'ptos' will thus point to the highest (valid) memory
224 * location of the stack. If OS_STK_GROWTH is set to 0, 'ptos' will point to the
225 * lowest memory location of the stack and the stack will grow with increasing
226 * memory locations. 'ptos' MUST point to a valid 'free' data item.
227 *
228 * prio is the task's priority. A unique priority MUST be assigned to each task and the
229 * lower the number, the higher the priority.
230 *
231 * id is the task's ID (0..65535)
232 *
233 * pbos is a pointer to the task's bottom of stack. If the configuration constant
234 * OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
235 * memory to low memory). 'pbos' will thus point to the LOWEST (valid) memory
236 * location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the
237 * HIGHEST memory location of the stack and the stack will grow with increasing
238 * memory locations. 'pbos' MUST point to a valid 'free' data item.
239 *
240 * stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U,
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 5

241 * 'stk_size' corresponds to the number of bytes available. If OS_STK is set to
242 * INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if
243 * OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries
244 * available on the stack.
245 *
246 * pext is a pointer to a user supplied memory location which is used as a TCB extension.
247 * For example, this user memory can hold the contents of floating-point registers
248 * during a context switch, the time each task takes to execute, the number of times
249 * the task has been switched-in, etc.
250 *
251 * opt contains additional information (or options) about the behavior of the task. The
252 * LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
253 * specific. See OS_TASK_OPT_??? in uCOS-II.H.
254 *
255 * Returns : OS_NO_ERR if the function was successful.
256 * OS_PRIO_EXIT if the task priority already exist
257 * (each task MUST have a unique priority).
258 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
259 * (i.e. > OS_LOWEST_PRIO)
260 *********************************************************************************************************
261 */
262 /*$PAGE*/
263 #if OS_TASK_CREATE_EXT_EN > 0
264 INT8U OSTaskCreateExt (void (*task)(void *pd),
265 void *pdata,
266 OS_STK *ptos,
267 INT8U prio,
268 INT16U id,
269 OS_STK *pbos,
270 INT32U stk_size,
271 void *pext,
272 INT16U opt) KCREENTRANT
273 {
274 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
277 1 OS_STK *psp;
278 1 INT8U err;
279 1
280 1
281 1 #if OS_ARG_CHK_EN > 0
282 1 if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
283 2 return (OS_PRIO_INVALID);
284 2 }
285 1 #endif
286 1 OS_ENTER_CRITICAL();
287 1 if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
288 2 OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */
289 2 /* ... the same thing until task is created. */
290 2 OS_EXIT_CRITICAL();
291 2
292 2 OS_TaskStkClr(pbos, stk_size, opt); /* Clear the task stack (if needed) */
293 2
294 2 psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); /* Initialize the task's stack */
295 2 err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
296 2 if (err == OS_NO_ERR) {
297 3 OS_ENTER_CRITICAL();
298 3 OSTaskCtr++; /* Increment the #tasks counter */
299 3 OS_EXIT_CRITICAL();
300 3 if (OSRunning == TRUE) { /* Find HPT if multitasking has started */
301 4 OS_Sched();
302 4 }
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 6

303 3 } else {
304 3 OS_ENTER_CRITICAL();
305 3 OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */
306 3 OS_EXIT_CRITICAL();
307 3 }
308 2 return (err);
309 2 }
310 1 OS_EXIT_CRITICAL();
311 1 return (OS_PRIO_EXIST);
312 1 }
313 #endif
314 /*$PAGE*/
315 /*
316 *********************************************************************************************************
317 * DELETE A TASK
318 *
319 * Description: This function allows you to delete a task. The calling task can delete itself by
320 * its own priority number. The deleted task is returned to the dormant state and can be
321 * re-activated by creating the deleted task again.
322 *
323 * Arguments : prio is the priority of the task to delete. Note that you can explicitely delete
324 * the current task without knowing its priority level by setting 'prio' to
325 * OS_PRIO_SELF.
326 *
327 * Returns : OS_NO_ERR if the call is successful
328 * OS_TASK_DEL_IDLE if you attempted to delete uC/OS-II's idle task
329 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
330 * (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
331 * OS_TASK_DEL_ERR if the task you want to delete does not exist
332 * OS_TASK_DEL_ISR if you tried to delete a task from an ISR
333 *
334 * Notes : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
335 * a) by making it not ready
336 * b) by removing it from any wait lists
337 * c) by preventing OSTimeTick() from making the task ready to run.
338 * The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
339 * 2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors,
340 * the next instruction following the enable interrupt instruction is ignored.
341 * 3) An ISR cannot delete a task.
342 * 4) The lock nesting counter is incremented because, for a brief instant, if the current
343 * task is being deleted, the current task would not be able to be rescheduled because it
344 * is removed from the ready list. Incrementing the nesting counter prevents another task
345 * from being schedule. This means that an ISR would return to the current task which is
346 * being deleted. The rest of the deletion would thus be able to be completed.
347 *********************************************************************************************************
348 */
349 /*$PAGE*/
350 #if OS_TASK_DEL_EN > 0
351 INT8U OSTaskDel (INT8U prio) KCREENTRANT
352 {
353 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
356 1
357 1 #if OS_EVENT_EN > 0
OS_EVENT *pevent;
#endif
360 1 #if (OS_VERSION >= 251) &amt;&amt; (OS_FLAG_EN > 0) &amt;&amt; (OS_MAX_FLAGS > 0)
OS_FLAG_NODE *pnode;
#endif
363 1 OS_TCB *ptcb;
364 1 INT8U y;
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 7

365 1
366 1
367 1
368 1 if (OSIntNesting > 0) { /* See if trying to delete from ISR */
369 2 return (OS_TASK_DEL_ISR);
370 2 }
371 1 #if OS_ARG_CHK_EN > 0
372 1 if (prio == OS_IDLE_PRIO) { /* Not allowed to delete idle task */
373 2 return (OS_TASK_DEL_IDLE);
374 2 }
375 1 if (prio >= OS_LOWEST_PRIO &amt;&amt; prio != OS_PRIO_SELF) { /* Task priority valid ? */
376 2 return (OS_PRIO_INVALID);
377 2 }
378 1 #endif
379 1 OS_ENTER_CRITICAL();
380 1 if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */
381 2 prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */
382 2 }
383 1 ptcb = OSTCBPrioTbl[prio];
384 1 if (ptcb != (OS_TCB *)0) { /* Task to delete must exist */
385 2 y = ptcb->OSTCBY;
386 2 OSRdyTbl[y] &amt;= ~ptcb->OSTCBBitX;
387 2 if (OSRdyTbl[y] == 0x00) { /* Make task not ready */
388 3 OSRdyGrp &amt;= ~ptcb->OSTCBBitY;
389 3 }
390 2 #if OS_EVENT_EN > 0
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0) { /* If task is waiting on event */
pevent->OSEventTbl[y] &amt;= ~ptcb->OSTCBBitX;
if (pevent->OSEventTbl[y] == 0) { /* ... remove task from ... */
pevent->OSEventGrp &amt;= ~ptcb->OSTCBBitY; /* ... event ctrl block */
}
}
#endif
399 2 #if (OS_VERSION >= 251) &amt;&amt; (OS_FLAG_EN > 0) &amt;&amt; (OS_MAX_FLAGS > 0)
pnode = ptcb->OSTCBFlagNode;
if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */
OS_FlagUnlink(pnode); /* Remove from wait list */
}
#endif
405 2 ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */
406 2 ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */
407 2 if (OSLockNesting < 255u) {
408 3 OSLockNesting++;
409 3 }
410 2 OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */
411 2 OS_Dummy(); /* ... Dummy ensures that INTs will be */
412 2 OS_ENTER_CRITICAL(); /* ... disabled HERE! */
413 2 if (OSLockNesting > 0) {
414 3 OSLockNesting--;
415 3 }
416 2 OSTaskDelHook(ptcb); /* Call user defined hook */
417 2 OSTaskCtr--; /* One less task being managed */
418 2 OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */
419 2 if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */
420 3 ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
421 3 OSTCBList = ptcb->OSTCBNext;
422 3 } else {
423 3 ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
424 3 ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
425 3 }
426 2 ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 8

427 2 OSTCBFreeList = ptcb;
428 2 ptcb->OSTCBStkPtr = (OS_STK *)0; /* Show that TCB is 'unused' */
429 2 #if OS_TASK_NAME_SIZE > 0
(void)strcpy(ptcb->OSTCBTaskName, "?"); /* Unknown name */
#endif
432 2 OS_EXIT_CRITICAL();
433 2 OS_Sched(); /* Find new highest priority task */
434 2 return (OS_NO_ERR);
435 2 }
436 1 OS_EXIT_CRITICAL();
437 1 return (OS_TASK_DEL_ERR);
438 1 }
439 #endif
440 /*$PAGE*/
441 /*
442 *********************************************************************************************************
443 * REQUEST THAT A TASK DELETE ITSELF
444 *
445 * Description: This function is used to:
446 * a) notify a task to delete itself.
447 * b) to see if a task requested that the current task delete itself.
448 * This function is a little tricky to understand. Basically, you have a task that needs
449 * to be deleted however, this task has resources that it has allocated (memory buffers,
450 * semaphores, mailboxes, queues etc.). The task cannot be deleted otherwise these
451 * resources would not be freed. The requesting task calls OSTaskDelReq() to indicate that
452 * the task needs to be deleted. Deleting of the task is however, deferred to the task to
453 * be deleted. For example, suppose that task #10 needs to be deleted. The requesting task
454 * example, task #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls
455 * this function by specifying OS_PRIO_SELF and monitors the returned value. If the return
456 * value is OS_TASK_DEL_REQ, another task requested a task delete. Task #10 would look like
457 * this:
458 *
459 * void Task(void *data)
460 * {
461 * .
462 * .
463 * while (1) {
464 * OSTimeDly(1);
465 * if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
466 * Release any owned resources;
467 * De-allocate any dynamic memory;
468 * OSTaskDel(OS_PRIO_SELF);
469 * }
470 * }
471 * }
472 *
473 * Arguments : prio is the priority of the task to request the delete from
474 *
475 * Returns : OS_NO_ERR if the task exist and the request has been registered
476 * OS_TASK_NOT_EXIST if the task has been deleted. This allows the caller to know whether
477 * the request has been executed.
478 * OS_TASK_DEL_IDLE if you requested to delete uC/OS-II's idle task
479 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
480 * (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
481 * OS_TASK_DEL_REQ if a task (possibly another task) requested that the running task be
482 * deleted.
483 *********************************************************************************************************
484 */
485 /*$PAGE*/
486 #if OS_TASK_DEL_EN > 0
487 INT8U OSTaskDelReq (INT8U prio) KCREENTRANT
488 {
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 9

489 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
492 1 BOOLEAN stat;
493 1 INT8U err;
494 1 OS_TCB *ptcb;
495 1
496 1
497 1 #if OS_ARG_CHK_EN > 0
498 1 if (prio == OS_IDLE_PRIO) { /* Not allowed to delete idle task */
499 2 return (OS_TASK_DEL_IDLE);
500 2 }
501 1 if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
502 2 if (prio != OS_PRIO_SELF) {
503 3 return (OS_PRIO_INVALID);
504 3 }
505 2 }
506 1 #endif
507 1 if (prio == OS_PRIO_SELF) { /* See if a task is requesting to ... */
508 2 OS_ENTER_CRITICAL(); /* ... this task to delete itself */
509 2 stat = OSTCBCur->OSTCBDelReq; /* Return request status to caller */
510 2 OS_EXIT_CRITICAL();
511 2 return (stat);
512 2 }
513 1 OS_ENTER_CRITICAL();
514 1 ptcb = OSTCBPrioTbl[prio];
515 1 if (ptcb != (OS_TCB *)0) { /* Task to delete must exist */
516 2 ptcb->OSTCBDelReq = OS_TASK_DEL_REQ; /* Set flag indicating task to be DEL. */
517 2 err = OS_NO_ERR;
518 2 } else {
519 2 err = OS_TASK_NOT_EXIST; /* Task must be deleted */
520 2 }
521 1 OS_EXIT_CRITICAL();
522 1 return (err);
523 1 }
524 #endif
525 /*$PAGE*/
526 /*
527 *********************************************************************************************************
528 * GET THE NAME OF A TASK
529 *
530 * Description: This function is called to obtain the name of a task.
531 *
532 * Arguments : prio is the priority of the task that you want to obtain the name from.
533 *
534 * pname is a pointer to an ASCII string that will receive the name of the task. The
535 * string must be able to hold at least OS_TASK_NAME_SIZE characters.
536 *
537 * err is a pointer to an error code that can contain one of the following values:
538 *
539 * OS_NO_ERR if the requested task is resumed
540 * OS_TASK_NOT_EXIST if the task has not been created
541 * OS_PRIO_INVALID if you specified an invalid priority:
542 * A higher value than the idle task or not OS_PRIO_SELF.
543 * OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
544 *
545 * Returns : The length of the string or 0 if the task does not exist.
546 *********************************************************************************************************
547 */
548
549 #if OS_TASK_NAME_SIZE > 0
INT8U OSTaskNameGet (INT8U prio, char *pname, INT8U *err) KCREENTRANT
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 10

{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
INT8U len;


OS_ENTER_CRITICAL();
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO &amt;&amt; prio != OS_PRIO_SELF) { /* Task priority valid ? */
*err = OS_PRIO_INVALID; /* No */
return (0);
}
if (pname == (char *)0) { /* Is 'pname' a NULL pointer? */
OS_EXIT_CRITICAL(); /* Yes */
*err = OS_ERR_PNAME_NULL;
return (0);
}
#endif
if (prio == OS_PRIO_SELF) { /* See if caller desires it's own name */
prio = OSTCBCur->OSTCBPrio;
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Does task exist? */
OS_EXIT_CRITICAL(); /* No */
*err = OS_TASK_NOT_EXIST;
return (0);
}
(void)strcpy(pname, ptcb->OSTCBTaskName); /* Yes, copy name from TCB */
len = strlen(pname);
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (len);
}
#endif
587
588 /*$PAGE*/
589 /*
590 *********************************************************************************************************
591 * ASSIGN A NAME TO A TASK
592 *
593 * Description: This function is used to set the name of a task.
594 *
595 * Arguments : prio is the priority of the task that you want the assign a name to.
596 *
597 * pname is a pointer to an ASCII string that contains the name of the task. The ASCII
598 * string must be NUL terminated.
599 *
600 * err is a pointer to an error code that can contain one of the following values:
601 *
602 * OS_NO_ERR if the requested task is resumed
603 * OS_TASK_NOT_EXIST if the task has not been created
604 * OS_ERR_TASK_NAME_TOO_LONG if the name you are giving to the task exceeds the
605 * storage capacity of a task name as specified by
606 * OS_TASK_NAME_SIZE.
607 * OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
608 * OS_PRIO_INVALID if you specified an invalid priority:
609 * A higher value than the idle task or not OS_PRIO_SELF.
610 *
611 * Returns : None
612 *********************************************************************************************************
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 11

613 */
614 #if OS_TASK_NAME_SIZE > 0
void OSTaskNameSet (INT8U prio, char *pname, INT8U *err) KCREENTRANT
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U len;
OS_TCB *ptcb;


OS_ENTER_CRITICAL();
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */
if (prio != OS_PRIO_SELF) {
*err = OS_PRIO_INVALID; /* No */
return;
}
}
if (pname == (char *)0) { /* Is 'pname' a NULL pointer? */
OS_EXIT_CRITICAL(); /* Yes */
*err = OS_ERR_PNAME_NULL;
return;
}
#endif
if (prio == OS_PRIO_SELF) { /* See if caller desires to set it's own name */
prio = OSTCBCur->OSTCBPrio;
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Does task exist? */
OS_EXIT_CRITICAL(); /* No */
*err = OS_TASK_NOT_EXIST;
return;
}
len = strlen(pname); /* Yes, Can we fit the string in the TCB? */
if (len > (OS_TASK_NAME_SIZE - 1)) { /* No */
OS_EXIT_CRITICAL();
*err = OS_ERR_TASK_NAME_TOO_LONG;
return;
}
(void)strcpy(ptcb->OSTCBTaskName, pname); /* Yes, copy to TCB */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
}
#endif
658
659 /*$PAGE*/
660 /*
661 *********************************************************************************************************
662 * RESUME A SUSPENDED TASK
663 *
664 * Description: This function is called to resume a previously suspended task. This is the only call that
665 * will remove an explicit task suspension.
666 *
667 * Arguments : prio is the priority of the task to resume.
668 *
669 * Returns : OS_NO_ERR if the requested task is resumed
670 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
671 * (i.e. >= OS_LOWEST_PRIO)
672 * OS_TASK_RESUME_PRIO if the task to resume does not exist
673 * OS_TASK_NOT_SUSPENDED if the task to resume has not been suspended
674 *********************************************************************************************************
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 12

675 */
676
677 #if OS_TASK_SUSPEND_EN > 0
678 INT8U OSTaskResume (INT8U prio) KCREENTRANT
679 {
680 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
683 1 OS_TCB *ptcb;
684 1
685 1
686 1 #if OS_ARG_CHK_EN > 0
687 1 if (prio >= OS_LOWEST_PRIO) { /* Make sure task priority is valid */
688 2 return (OS_PRIO_INVALID);
689 2 }
690 1 #endif
691 1 OS_ENTER_CRITICAL();
692 1 ptcb = OSTCBPrioTbl[prio];
693 1 if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */
694 2 OS_EXIT_CRITICAL();
695 2 return (OS_TASK_RESUME_PRIO);
696 2 }
697 1 if ((ptcb->OSTCBStat &amt; OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended */
698 2 ptcb->OSTCBStat &amt;= ~OS_STAT_SUSPEND; /* Remove suspension */
699 2 if (ptcb->OSTCBStat == OS_STAT_RDY) {
700 3 if (ptcb->OSTCBDly == 0) { /* Must not be delayed */
701 4 OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
702 4 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
703 4 OS_EXIT_CRITICAL();
704 4 OS_Sched();
705 4 } else {
706 4 OS_EXIT_CRITICAL();
707 4 }
708 3 } else {
709 3 OS_EXIT_CRITICAL();
710 3 }
711 2 return (OS_NO_ERR);
712 2 }
713 1 OS_EXIT_CRITICAL();
714 1 return (OS_TASK_NOT_SUSPENDED);
715 1 }
716 #endif
717 /*$PAGE*/
718 /*
719 *********************************************************************************************************
720 * STACK CHECKING
721 *
722 * Description: This function is called to check the amount of free memory left on the specified task's
723 * stack.
724 *
725 * Arguments : prio is the task priority
726 *
727 * pdata is a pointer to a data structure of type OS_STK_DATA.
728 *
729 * Returns : OS_NO_ERR upon success
730 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
731 * (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
732 * OS_TASK_NOT_EXIST if the desired task has not been created
733 * OS_TASK_OPT_ERR if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
734 *********************************************************************************************************
735 */
736 #if OS_TASK_CREATE_EXT_EN > 0
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 13

737 INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *pdata) KCREENTRANT
738 {
739 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
742 1 OS_TCB *ptcb;
743 1 OS_STK *pchk;
744 1 INT32U free;
745 1 INT32U size;
746 1
747 1
748 1 #if OS_ARG_CHK_EN > 0
749 1 if (prio > OS_LOWEST_PRIO) { /* Make sure task priority is valid */
750 2 if (prio != OS_PRIO_SELF) {
751 3 return (OS_PRIO_INVALID);
752 3 }
753 2 }
754 1 #endif
755 1 pdata->OSFree = 0; /* Assume failure, set to 0 size */
756 1 pdata->OSUsed = 0;
757 1 OS_ENTER_CRITICAL();
758 1 if (prio == OS_PRIO_SELF) { /* See if check for SELF */
759 2 prio = OSTCBCur->OSTCBPrio;
760 2 }
761 1 ptcb = OSTCBPrioTbl[prio];
762 1 if (ptcb == (OS_TCB *)0) { /* Make sure task exist */
763 2 OS_EXIT_CRITICAL();
764 2 return (OS_TASK_NOT_EXIST);
765 2 }
766 1 if (ptcb == (OS_TCB *)1) {
767 2 OS_EXIT_CRITICAL();
768 2 return (OS_TASK_NOT_EXIST);
769 2 }
770 1 if ((ptcb->OSTCBOpt &amt; OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set */
771 2 OS_EXIT_CRITICAL();
772 2 return (OS_TASK_OPT_ERR);
773 2 }
774 1 free = 0;
775 1 size = ptcb->OSTCBStkSize;
776 1 pchk = ptcb->OSTCBStkBottom;
777 1 OS_EXIT_CRITICAL();
778 1 #if OS_STK_GROWTH == 1
while (*pchk++ == (OS_STK)0) { /* Compute the number of zero entries on the stk */
free++;
}
#else
783 1 while (*pchk-- == (OS_STK)0) {
784 2 free++;
785 2 }
786 1 #endif
787 1 pdata->OSFree = free * sizeof(OS_STK); /* Compute number of free bytes on the stack */
788 1 pdata->OSUsed = (size - free) * sizeof(OS_STK); /* Compute number of bytes used on the stack */
789 1 return (OS_NO_ERR);
790 1 }
791 #endif
792 /*$PAGE*/
793 /*
794 *********************************************************************************************************
795 * SUSPEND A TASK
796 *
797 * Description: This function is called to suspend a task. The task can be the calling task if the
798 * priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF.
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 14

799 *
800 * Arguments : prio is the priority of the task to suspend. If you specify OS_PRIO_SELF, the
801 * calling task will suspend itself and rescheduling will occur.
802 *
803 * Returns : OS_NO_ERR if the requested task is suspended
804 * OS_TASK_SUSPEND_IDLE if you attempted to suspend the idle task which is not allowed.
805 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
806 * (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
807 * OS_TASK_SUSPEND_PRIO if the task to suspend does not exist
808 *
809 * Note : You should use this function with great care. If you suspend a task that is waiting for
810 * an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from
811 * running when the event arrives.
812 *********************************************************************************************************
813 */
814
815 #if OS_TASK_SUSPEND_EN > 0
816 INT8U OSTaskSuspend (INT8U prio) KCREENTRANT
817 {
818 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
821 1 BOOLEAN self;
822 1 OS_TCB *ptcb;
823 1 INT8U y;
824 1
825 1
826 1 #if OS_ARG_CHK_EN > 0
827 1 if (prio == OS_IDLE_PRIO) { /* Not allowed to suspend idle task */
828 2 return (OS_TASK_SUSPEND_IDLE);
829 2 }
830 1 if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
831 2 if (prio != OS_PRIO_SELF) {
832 3 return (OS_PRIO_INVALID);
833 3 }
834 2 }
835 1 #endif
836 1 OS_ENTER_CRITICAL();
837 1 if (prio == OS_PRIO_SELF) { /* See if suspend SELF */
838 2 prio = OSTCBCur->OSTCBPrio;
839 2 self = TRUE;
840 2 } else if (prio == OSTCBCur->OSTCBPrio) { /* See if suspending self */
841 2 self = TRUE;
842 2 } else {
843 2 self = FALSE; /* No suspending another task */
844 2 }
845 1 ptcb = OSTCBPrioTbl[prio];
846 1 if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */
847 2 OS_EXIT_CRITICAL();
848 2 return (OS_TASK_SUSPEND_PRIO);
849 2 }
850 1 y = ptcb->OSTCBY;
851 1 OSRdyTbl[y] &amt;= ~ptcb->OSTCBBitX; /* Make task not ready */
852 1 if (OSRdyTbl[y] == 0x00) {
853 2 OSRdyGrp &amt;= ~ptcb->OSTCBBitY;
854 2 }
855 1 ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */
856 1 OS_EXIT_CRITICAL();
857 1 if (self == TRUE) { /* Context switch only if SELF */
858 2 OS_Sched();
859 2 }
860 1 return (OS_NO_ERR);
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 15

861 1 }
862 #endif
863 /*$PAGE*/
864 /*
865 *********************************************************************************************************
866 * QUERY A TASK
867 *
868 * Description: This function is called to obtain a copy of the desired task's TCB.
869 *
870 * Arguments : prio is the priority of the task to obtain information from.
871 *
872 * Returns : OS_NO_ERR if the requested task is suspended
873 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
874 * (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
875 * OS_PRIO_ERR if the desired task has not been created
876 *********************************************************************************************************
877 */
878
879 #if OS_TASK_QUERY_EN > 0
880 INT8U OSTaskQuery (INT8U prio, OS_TCB *pdata) KCREENTRANT
881 {
882 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
885 1 OS_TCB *ptcb;
886 1
887 1
888 1 #if OS_ARG_CHK_EN > 0
889 1 if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */
890 2 if (prio != OS_PRIO_SELF) {
891 3 return (OS_PRIO_INVALID);
892 3 }
893 2 }
894 1 #endif
895 1 OS_ENTER_CRITICAL();
896 1 if (prio == OS_PRIO_SELF) { /* See if suspend SELF */
897 2 prio = OSTCBCur->OSTCBPrio;
898 2 }
899 1 ptcb = OSTCBPrioTbl[prio];
900 1 if (ptcb == (OS_TCB *)0) { /* Task to query must exist */
901 2 OS_EXIT_CRITICAL();
902 2 return (OS_PRIO_ERR);
903 2 }
904 1 memcpy(pdata, ptcb, sizeof(OS_TCB)); /* Copy TCB into user storage area */
905 1 OS_EXIT_CRITICAL();
906 1 return (OS_NO_ERR);
907 1 }
908 #endif
909 /*$PAGE*/
910 /*
911 *********************************************************************************************************
912 * CLEAR TASK STACK
913 *
914 * Description: This function is used to clear the stack of a task (i.e. write all zeros)
915 *
916 * Arguments : pbos is a pointer to the task's bottom of stack. If the configuration constant
917 * OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
918 * memory to low memory). 'pbos' will thus point to the lowest (valid) memory
919 * location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the
920 * highest memory location of the stack and the stack will grow with increasing
921 * memory locations. 'pbos' MUST point to a valid 'free' data item.
922 *
C51 COMPILER V8.05a OS_TASK 04/11/2007 16:19:49 PAGE 16

923 * size is the number of 'stack elements' to clear.
924 *
925 * opt contains additional information (or options) about the behavior of the task. The
926 * LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
927 * specific. See OS_TASK_OPT_??? in uCOS-II.H.
928 *
929 * Returns : none
930 *********************************************************************************************************
931 */
932 #if OS_TASK_CREATE_EXT_EN > 0
933 void OS_TaskStkClr (OS_STK *pbos, INT32U size, INT16U opt) KCREENTRANT
934 {
935 1 if ((opt &amt; OS_TASK_OPT_STK_CHK) != 0x0000) { /* See if stack checking has been enabled */
936 2 if ((opt &amt; OS_TASK_OPT_STK_CLR) != 0x0000) { /* See if stack needs to be cleared */
937 3 #if OS_STK_GROWTH == 1
while (size > 0) { /* Stack grows from HIGH to LOW memory */
size--;
*pbos++ = (OS_STK)0; /* Clear from bottom of stack and up! */
}
#else
943 3 while (size > 0) { /* Stack grows from LOW to HIGH memory */
944 4 size--;
945 4 *pbos-- = (OS_STK)0; /* Clear from bottom of stack and down */
946 4 }
947 3 #endif
948 3 }
949 2 }
950 1 }
951
952 #endif


MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 3830 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)