📄 os_task.lst
字号:
340 #endif
341 /*$PAGE*/
342 /*
343 *********************************************************************************************************
344 * DELETE A TASK
345 *
346 * Description: This function allows you to delete a task. The calling task can delete itself by
347 * its own priority number. The deleted task is returned to the dormant state and can be
348 * re-activated by creating the deleted task again.
349 *
350 * Arguments : prio is the priority of the task to delete. Note that you can explicitely delete
351 * the current task without knowing its priority level by setting 'prio' to
352 * OS_PRIO_SELF.
353 *
354 * Returns : OS_NO_ERR if the call is successful
355 * OS_TASK_DEL_IDLE if you attempted to delete uC/OS-II's idle task
356 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
357 * (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
358 * OS_TASK_DEL_ERR if the task you want to delete does not exist.
359 * OS_TASK_NOT_EXIST if the task is assigned to a Mutex PIP.
360 * OS_TASK_DEL_ISR if you tried to delete a task from an ISR
361 *
362 * Notes : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
363 * a) by making it not ready
364 * b) by removing it from any wait lists
365 * c) by preventing OSTimeTick() from making the task ready to run.
366 * The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
367 * 2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors,
368 * the next instruction following the enable interrupt instruction is ignored.
369 * 3) An ISR cannot delete a task.
C51 COMPILER V8.08 OS_TASK 08/04/2008 21:49:52 PAGE 8
370 * 4) The lock nesting counter is incremented because, for a brief instant, if the current
371 * task is being deleted, the current task would not be able to be rescheduled because it
372 * is removed from the ready list. Incrementing the nesting counter prevents another task
373 * from being schedule. This means that an ISR would return to the current task which is
374 * being deleted. The rest of the deletion would thus be able to be completed.
375 *********************************************************************************************************
376 */
377 /*$PAGE*/
378 #if OS_TASK_DEL_EN > 0
379 INT8U OSTaskDel (INT8U prio)
380 {
381 #if OS_EVENT_EN
382 OS_EVENT *pevent;
383 #endif
384 #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
385 OS_FLAG_NODE *pnode;
386 #endif
387 OS_TCB *ptcb;
388 INT8U y;
389 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
392
393
394
395 if (OSIntNesting > 0) { /* See if trying to delete from ISR */
396 return (OS_TASK_DEL_ISR);
397 }
398 #if OS_ARG_CHK_EN > 0
399 if (prio == OS_IDLE_PRIO) { /* Not allowed to delete idle task */
400 return (OS_TASK_DEL_IDLE);
401 }
402 if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
403 if (prio != OS_PRIO_SELF) {
404 return (OS_PRIO_INVALID);
405 }
406 }
407 #endif
408 OS_ENTER_CRITICAL();
409 if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */
410 prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */
411 }
412 ptcb = OSTCBPrioTbl[prio];
413 if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */
414 OS_EXIT_CRITICAL();
415 return (OS_TASK_DEL_ERR);
416 }
417 if (ptcb == (OS_TCB *)1) { /* Must not be assigned to Mutex */
418 OS_EXIT_CRITICAL();
419 return (OS_TASK_NOT_EXIST);
420 }
421 y = ptcb->OSTCBY;
422 OSRdyTbl[y] &= ~ptcb->OSTCBBitX;
423 if (OSRdyTbl[y] == 0) { /* Make task not ready */
424 OSRdyGrp &= ~ptcb->OSTCBBitY;
425 }
426 #if OS_EVENT_EN
427 pevent = ptcb->OSTCBEventPtr;
428 if (pevent != (OS_EVENT *)0) { /* If task is waiting on event */
429 pevent->OSEventTbl[y] &= ~ptcb->OSTCBBitX;
430 if (pevent->OSEventTbl[y] == 0) { /* ... remove task from ... */
431 pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... event ctrl block */
C51 COMPILER V8.08 OS_TASK 08/04/2008 21:49:52 PAGE 9
432 }
433 }
434 #endif
435 #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
436 pnode = ptcb->OSTCBFlagNode;
437 if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */
438 OS_FlagUnlink(pnode); /* Remove from wait list */
439 }
440 #endif
441 ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */
442 ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */
443 ptcb->OSTCBPendTO = FALSE;
444 if (OSLockNesting < 255u) { /* Make sure we don't context switch */
445 OSLockNesting++;
446 }
447 OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */
448 OS_Dummy(); /* ... Dummy ensures that INTs will be */
449 OS_ENTER_CRITICAL(); /* ... disabled HERE! */
450 if (OSLockNesting > 0) { /* Remove context switch lock */
451 OSLockNesting--;
452 }
453 OSTaskDelHook(ptcb); /* Call user defined hook */
454 OSTaskCtr--; /* One less task being managed */
455 OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */
456 if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */
457 ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
458 OSTCBList = ptcb->OSTCBNext;
459 } else {
460 ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
461 ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
462 }
463 ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */
464 OSTCBFreeList = ptcb;
465 #if OS_TASK_NAME_SIZE > 1
466 ptcb->OSTCBTaskName[0] = '?'; /* Unknown name */
467 ptcb->OSTCBTaskName[1] = OS_ASCII_NUL;
468 #endif
469 OS_EXIT_CRITICAL();
470 OS_Sched(); /* Find new highest priority task */
471 return (OS_NO_ERR);
472 }
473 #endif
474 /*$PAGE*/
475 /*
476 *********************************************************************************************************
477 * REQUEST THAT A TASK DELETE ITSELF
478 *
479 * Description: This function is used to:
480 * a) notify a task to delete itself.
481 * b) to see if a task requested that the current task delete itself.
482 * This function is a little tricky to understand. Basically, you have a task that needs
483 * to be deleted however, this task has resources that it has allocated (memory buffers,
484 * semaphores, mailboxes, queues etc.). The task cannot be deleted otherwise these
485 * resources would not be freed. The requesting task calls OSTaskDelReq() to indicate that
486 * the task needs to be deleted. Deleting of the task is however, deferred to the task to
487 * be deleted. For example, suppose that task #10 needs to be deleted. The requesting task
488 * example, task #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls
489 * this function by specifying OS_PRIO_SELF and monitors the returned value. If the return
490 * value is OS_TASK_DEL_REQ, another task requested a task delete. Task #10 would look like
491 * this:
492 *
493 * void Task(void *p_arg)
C51 COMPILER V8.08 OS_TASK 08/04/2008 21:49:52 PAGE 10
494 * {
495 * .
496 * .
497 * while (1) {
498 * OSTimeDly(1);
499 * if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
500 * Release any owned resources;
501 * De-allocate any dynamic memory;
502 * OSTaskDel(OS_PRIO_SELF);
503 * }
504 * }
505 * }
506 *
507 * Arguments : prio is the priority of the task to request the delete from
508 *
509 * Returns : OS_NO_ERR if the task exist and the request has been registered
510 * OS_TASK_NOT_EXIST if the task has been deleted. This allows the caller to know whether
511 * the request has been executed.
512 * OS_TASK_DEL_ERR if the task is assigned to a Mutex.
513 * OS_TASK_DEL_IDLE if you requested to delete uC/OS-II's idle task
514 * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
515 * (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
516 * OS_TASK_DEL_REQ if a task (possibly another task) requested that the running task be
517 * deleted.
518 *********************************************************************************************************
519 */
520 /*$PAGE*/
521 #if OS_TASK_DEL_EN > 0
522 INT8U OSTaskDelReq (INT8U prio)
523 {
524 INT8U stat;
525 OS_TCB *ptcb;
526 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
529
530
531
532 #if OS_ARG_CHK_EN > 0
533 if (prio == OS_IDLE_PRIO) { /* Not allowed to delete idle task */
534 return (OS_TASK_DEL_IDLE);
535 }
536 if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
537 if (prio != OS_PRIO_SELF) {
538 return (OS_PRIO_INVALID);
539 }
540 }
541 #endif
542 if (prio == OS_PRIO_SELF) { /* See if a task is requesting to ... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -