os_task.c
上传用户:yyyd609
上传日期:2022-07-18
资源大小:183k
文件大小:49k
源码类别:

微处理器开发

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/OS-II
  4. *                                          The Real-Time Kernel
  5. *                                            TASK MANAGEMENT
  6. *
  7. *                          (c) Copyright 1992-2003, Jean J. Labrosse, Weston, FL
  8. *                                           All Rights Reserved
  9. *
  10. * File    : OS_TASK.C
  11. * By      : Jean J. Labrosse
  12. * Version : V2.76
  13. *********************************************************************************************************
  14. */
  15. #ifndef  OS_MASTER_FILE
  16. #include <ucos_ii.h>
  17. #endif
  18. /*
  19. *********************************************************************************************************
  20. *                                        CHANGE PRIORITY OF A TASK
  21. *
  22. * Description: This function allows you to change the priority of a task dynamically.  Note that the new
  23. *              priority MUST be available.
  24. *
  25. * Arguments  : oldp     is the old priority
  26. *
  27. *              newp     is the new priority
  28. *
  29. * Returns    : OS_NO_ERR          is the call was successful
  30. *              OS_PRIO_INVALID    if the priority you specify is higher that the maximum allowed
  31. *                                 (i.e. >= OS_LOWEST_PRIO)
  32. *              OS_PRIO_EXIST      if the new priority already exist.
  33. *              OS_PRIO_ERR        there is no task with the specified OLD priority (i.e. the OLD task does
  34. *                                 not exist.
  35. *              OS_TASK_NOT_EXIST  if the task is assigned to a Mutex PIP.
  36. *********************************************************************************************************
  37. */
  38. #if OS_TASK_CHANGE_PRIO_EN > 0
  39. INT8U  OSTaskChangePrio (INT8U oldprio, INT8U newprio)
  40. {
  41. #if OS_EVENT_EN
  42.     OS_EVENT    *pevent;
  43. #endif
  44.     OS_TCB      *ptcb;
  45.     INT8U        x;
  46.     INT8U        y;
  47.     INT8U        bitx;
  48.     INT8U        bity;
  49.     INT8U        y_old;
  50. #if OS_CRITICAL_METHOD == 3                                     
  51.     OS_CPU_SR    cpu_sr;                                        /* Storage for CPU status register     */
  52.     cpu_sr = 0;                                                 /* Prevent compiler warning            */
  53. #endif    
  54. #if OS_ARG_CHK_EN > 0
  55.     if (oldprio >= OS_LOWEST_PRIO) {
  56.     if (oldprio != OS_PRIO_SELF) {
  57.             return (OS_PRIO_INVALID);
  58. }
  59. }
  60.     if (newprio >= OS_LOWEST_PRIO) {
  61.         return (OS_PRIO_INVALID);
  62.     }
  63. #endif
  64.     OS_ENTER_CRITICAL();
  65.     if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) {                 /* New priority must not already exist */
  66.         OS_EXIT_CRITICAL();
  67.         return (OS_PRIO_EXIST);
  68.     } 
  69.     if (oldprio == OS_PRIO_SELF) {                              /* See if changing self                */
  70.         oldprio = OSTCBCur->OSTCBPrio;                          /* Yes, get priority                   */
  71.     }
  72.     ptcb = OSTCBPrioTbl[oldprio];
  73.     if (ptcb == (OS_TCB *)0) {                                  /* Does task to change exist?          */
  74.         OS_EXIT_CRITICAL();                                     /* No, can't change its priority!      */
  75.         return (OS_PRIO_ERR);
  76.     }                                       
  77.     if (ptcb == (OS_TCB *)1) {                                  /* Is task assigned to Mutex           */
  78.         OS_EXIT_CRITICAL();                                     /* No, can't change its priority!      */
  79.         return (OS_TASK_NOT_EXIST);
  80.     }                                       
  81.     y                     = newprio >> 3;                       /* Yes, compute new TCB fields         */
  82.     bity                  = OSMapTbl[y];
  83.     x                     = newprio & 0x07;
  84.     bitx                  = OSMapTbl[x];
  85.     OSTCBPrioTbl[oldprio] = (OS_TCB *)0;                        /* Remove TCB from old priority        */
  86.     OSTCBPrioTbl[newprio] = ptcb;                               /* Place pointer to TCB @ new priority */
  87.     y_old                 = ptcb->OSTCBY;
  88.     if ((OSRdyTbl[y_old] & ptcb->OSTCBBitX) != 0x00) {          /* If task is ready make it not        */
  89.         OSRdyTbl[y_old] &= ~ptcb->OSTCBBitX;
  90.         if (OSRdyTbl[y_old] == 0x00) {
  91.             OSRdyGrp &= ~ptcb->OSTCBBitY;
  92.         }
  93.         OSRdyGrp    |= bity;                                    /* Make new priority ready to run      */
  94.         OSRdyTbl[y] |= bitx;
  95. #if OS_EVENT_EN
  96.     } else {                                                    /* Task was not ready ...              */
  97.         pevent = ptcb->OSTCBEventPtr;
  98.         if (pevent != (OS_EVENT *)0) {                          /* ... remove from event wait list     */
  99.             pevent->OSEventTbl[y_old] &= ~ptcb->OSTCBBitX;
  100.             if (pevent->OSEventTbl[y_old] == 0) {
  101.                 pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
  102.             }
  103.             pevent->OSEventGrp    |= bity;                      /* Add new priority to wait list       */
  104.             pevent->OSEventTbl[y] |= bitx;
  105.         }
  106. #endif
  107.     }
  108.     ptcb->OSTCBPrio = newprio;                                  /* Set new task priority               */
  109.     ptcb->OSTCBY    = y;
  110.     ptcb->OSTCBX    = x;
  111.     ptcb->OSTCBBitY = bity;
  112.     ptcb->OSTCBBitX = bitx;
  113.     OS_EXIT_CRITICAL();
  114.     OS_Sched();                                                 /* Run highest priority task ready     */
  115.     return (OS_NO_ERR);
  116. }
  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. *              p_arg    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 'p_arg' as follows:
  132. *
  133. *                           void Task (void *p_arg)
  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. *              OS_ERR_TASK_CREATE_ISR  if you tried to create a task from an ISR.
  156. *********************************************************************************************************
  157. */
  158. #if OS_TASK_CREATE_EN > 0
  159. INT8U  OSTaskCreate (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT8U prio)
  160. {
  161.     OS_STK    *psp;
  162.     INT8U      err;
  163. #if OS_CRITICAL_METHOD == 3                  /* Allocate storage for CPU status register               */
  164.     OS_CPU_SR  cpu_sr;
  165.     cpu_sr = 0;                              /* Prevent compiler warning                               */
  166. #endif    
  167. #if OS_ARG_CHK_EN > 0
  168.     if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */
  169.         return (OS_PRIO_INVALID);
  170.     }
  171. #endif
  172.     OS_ENTER_CRITICAL();
  173.     if (OSIntNesting > 0) {                  /* Make sure we don't create the task from within an ISR  */
  174.         OS_EXIT_CRITICAL();
  175.         return (OS_ERR_TASK_CREATE_ISR);
  176.     }
  177.     if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */
  178.         OSTCBPrioTbl[prio] = (OS_TCB *)1;    /* Reserve the priority to prevent others from doing ...  */
  179.                                              /* ... the same thing until task is created.              */
  180.        OS_EXIT_CRITICAL();
  181.         psp = (OS_STK *)OSTaskStkInit(task, p_arg, ptos, 0);    /* Initialize the task's stack         */
  182.         err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
  183.         if (err == OS_NO_ERR) {
  184.             if (OSRunning == TRUE) {         /* Find highest priority task if multitasking has started */
  185.                 OS_Sched();
  186.             }
  187.         } else {
  188.             OS_ENTER_CRITICAL();
  189.             OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others                 */
  190.             OS_EXIT_CRITICAL();
  191.         }
  192.         return (err);
  193.     }
  194.     OS_EXIT_CRITICAL();
  195.     return (OS_PRIO_EXIST);
  196. }
  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. *              p_arg     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 'p_arg' as follows:
  213. *
  214. *                            void Task (void *p_arg)
  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,
  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.  Current choices are:
  254. *
  255. *                        OS_TASK_OPT_STK_CHK      Stack checking to be allowed for the task
  256. *                        OS_TASK_OPT_STK_CLR      Clear the stack when the task is created
  257. *                        OS_TASK_OPT_SAVE_FP      If the CPU has floating-point registers, save them
  258. *                                                 during a context switch.
  259. *
  260. * Returns    : OS_NO_ERR               if the function was successful.
  261. *              OS_PRIO_EXIT            if the task priority already exist
  262. *                                      (each task MUST have a unique priority).
  263. *              OS_PRIO_INVALID         if the priority you specify is higher that the maximum allowed
  264. *                                      (i.e. > OS_LOWEST_PRIO)
  265. *              OS_ERR_TASK_CREATE_ISR  if you tried to create a task from an ISR.
  266. *********************************************************************************************************
  267. */
  268. /*$PAGE*/
  269. #if OS_TASK_CREATE_EXT_EN > 0
  270. INT8U  OSTaskCreateExt (void   (*task)(void *pd),
  271.                         void    *p_arg,
  272.                         OS_STK  *ptos,
  273.                         INT8U    prio,
  274.                         INT16U   id,
  275.                         OS_STK  *pbos,
  276.                         INT32U   stk_size,
  277.                         void    *pext,
  278.                         INT16U   opt)
  279. {
  280.     OS_STK    *psp;
  281.     INT8U      err;
  282. #if OS_CRITICAL_METHOD == 3                  /* Allocate storage for CPU status register               */
  283.     OS_CPU_SR  cpu_sr;
  284.     cpu_sr = 0;                              /* Prevent compiler warning                               */
  285. #endif    
  286. #if OS_ARG_CHK_EN > 0
  287.     if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */
  288.         return (OS_PRIO_INVALID);
  289.     }
  290. #endif
  291.     OS_ENTER_CRITICAL();
  292.     if (OSIntNesting > 0) {                  /* Make sure we don't create the task from within an ISR  */
  293.         OS_EXIT_CRITICAL();
  294.         return (OS_ERR_TASK_CREATE_ISR);
  295.     }
  296.     if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */
  297.         OSTCBPrioTbl[prio] = (OS_TCB *)1;    /* Reserve the priority to prevent others from doing ...  */
  298.                                              /* ... the same thing until task is created.              */
  299.         OS_EXIT_CRITICAL();
  300.         OS_TaskStkClr(pbos, stk_size, opt);                    /* Clear the task stack (if needed)     */
  301.         psp = (OS_STK *)OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the task's stack          */
  302.         err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
  303.         if (err == OS_NO_ERR) {
  304.             if (OSRunning == TRUE) {                           /* Find HPT if multitasking has started */
  305.                 OS_Sched();
  306.             }
  307.         } else {
  308.             OS_ENTER_CRITICAL();
  309.             OSTCBPrioTbl[prio] = (OS_TCB *)0;                  /* Make this priority avail. to others  */
  310.             OS_EXIT_CRITICAL();
  311.         }
  312.         return (err);
  313.     }
  314.     OS_EXIT_CRITICAL();
  315.     return (OS_PRIO_EXIST);
  316. }
  317. #endif
  318. /*$PAGE*/
  319. /*
  320. *********************************************************************************************************
  321. *                                            DELETE A TASK
  322. *
  323. * Description: This function allows you to delete a task.  The calling task can delete itself by
  324. *              its own priority number.  The deleted task is returned to the dormant state and can be
  325. *              re-activated by creating the deleted task again.
  326. *
  327. * Arguments  : prio    is the priority of the task to delete.  Note that you can explicitely delete
  328. *                      the current task without knowing its priority level by setting 'prio' to
  329. *                      OS_PRIO_SELF.
  330. *
  331. * Returns    : OS_NO_ERR           if the call is successful
  332. *              OS_TASK_DEL_IDLE    if you attempted to delete uC/OS-II's idle task
  333. *              OS_PRIO_INVALID     if the priority you specify is higher that the maximum allowed
  334. *                                  (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  335. *              OS_TASK_DEL_ERR     if the task you want to delete does not exist.
  336. *              OS_TASK_NOT_EXIST   if the task is assigned to a Mutex PIP.
  337. *              OS_TASK_DEL_ISR     if you tried to delete a task from an ISR
  338. *
  339. * Notes      : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
  340. *                    a) by making it not ready
  341. *                    b) by removing it from any wait lists
  342. *                    c) by preventing OSTimeTick() from making the task ready to run.
  343. *                 The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
  344. *              2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors,
  345. *                 the next instruction following the enable interrupt instruction is ignored.  
  346. *              3) An ISR cannot delete a task.
  347. *              4) The lock nesting counter is incremented because, for a brief instant, if the current
  348. *                 task is being deleted, the current task would not be able to be rescheduled because it
  349. *                 is removed from the ready list.  Incrementing the nesting counter prevents another task
  350. *                 from being schedule.  This means that an ISR would return to the current task which is
  351. *                 being deleted.  The rest of the deletion would thus be able to be completed.
  352. *********************************************************************************************************
  353. */
  354. /*$PAGE*/
  355. #if OS_TASK_DEL_EN > 0
  356. INT8U  OSTaskDel (INT8U prio)
  357. {
  358. #if OS_EVENT_EN
  359.     OS_EVENT     *pevent;
  360. #endif    
  361. #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
  362.     OS_FLAG_NODE *pnode;
  363. #endif
  364.     OS_TCB       *ptcb;
  365. INT8U         y;
  366. #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  367.     OS_CPU_SR     cpu_sr;
  368.     cpu_sr = 0;                                                 /* Prevent compiler warning            */
  369. #endif    
  370.     if (OSIntNesting > 0) {                                     /* See if trying to delete from ISR    */
  371.         return (OS_TASK_DEL_ISR);
  372.     }
  373. #if OS_ARG_CHK_EN > 0
  374.     if (prio == OS_IDLE_PRIO) {                                 /* Not allowed to delete idle task     */
  375.         return (OS_TASK_DEL_IDLE);
  376.     }
  377.     if (prio >= OS_LOWEST_PRIO) {                               /* Task priority valid ?               */
  378.         if (prio != OS_PRIO_SELF) {       
  379.             return (OS_PRIO_INVALID);
  380.         }
  381.     }
  382. #endif
  383.     OS_ENTER_CRITICAL();
  384.     if (prio == OS_PRIO_SELF) {                                 /* See if requesting to delete self    */
  385.         prio = OSTCBCur->OSTCBPrio;                             /* Set priority to delete to current   */
  386.     }
  387.     ptcb = OSTCBPrioTbl[prio];
  388.     if (ptcb == (OS_TCB *)0) {                                  /* Task to delete must exist           */
  389.         OS_EXIT_CRITICAL();
  390.         return (OS_TASK_DEL_ERR);
  391.     }
  392.     if (ptcb == (OS_TCB *)1) {                                  /* Must not be assigned to Mutex       */
  393.         OS_EXIT_CRITICAL();
  394.         return (OS_TASK_NOT_EXIST);
  395.     }
  396. y            =  ptcb->OSTCBY;
  397. OSRdyTbl[y] &= ~ptcb->OSTCBBitX;
  398.     if (OSRdyTbl[y] == 0x00) {                                  /* Make task not ready                 */
  399.         OSRdyGrp &= ~ptcb->OSTCBBitY;
  400.     }
  401. #if OS_EVENT_EN
  402.     pevent = ptcb->OSTCBEventPtr;
  403.     if (pevent != (OS_EVENT *)0) {                              /* If task is waiting on event         */
  404.     pevent->OSEventTbl[y] &= ~ptcb->OSTCBBitX;
  405.         if (pevent->OSEventTbl[y] == 0) {                       /* ... remove task from ...            */
  406.             pevent->OSEventGrp &= ~ptcb->OSTCBBitY;             /* ... event ctrl block                */
  407.         }
  408.     }
  409. #endif
  410. #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
  411.     pnode = ptcb->OSTCBFlagNode;
  412.     if (pnode != (OS_FLAG_NODE *)0) {                           /* If task is waiting on event flag    */
  413.         OS_FlagUnlink(pnode);                                   /* Remove from wait list               */
  414.     }
  415. #endif
  416.     ptcb->OSTCBDly    = 0;                                      /* Prevent OSTimeTick() from updating  */
  417.     ptcb->OSTCBStat   = OS_STAT_RDY;                            /* Prevent task from being resumed     */
  418.     ptcb->OSTCBPendTO = FALSE;
  419. if (OSLockNesting < 255u) {                                 /* Make sure we don't context switch   */
  420.         OSLockNesting++;
  421. }
  422.     OS_EXIT_CRITICAL();                                         /* Enabling INT. ignores next instruc. */
  423.     OS_Dummy();                                                 /* ... Dummy ensures that INTs will be */
  424.     OS_ENTER_CRITICAL();                                        /* ... disabled HERE!                  */
  425. if (OSLockNesting > 0) {                                    /* Remove context switch lock          */
  426.         OSLockNesting--;
  427. }
  428.     OSTaskDelHook(ptcb);                                        /* Call user defined hook              */
  429.     OSTaskCtr--;                                                /* One less task being managed         */
  430.     OSTCBPrioTbl[prio] = (OS_TCB *)0;                           /* Clear old priority entry            */
  431.     if (ptcb->OSTCBPrev == (OS_TCB *)0) {                       /* Remove from TCB chain               */
  432.         ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
  433.         OSTCBList                  = ptcb->OSTCBNext;
  434.     } else {
  435.         ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
  436.         ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
  437.     }
  438.     ptcb->OSTCBNext   = OSTCBFreeList;                          /* Return TCB to free TCB list         */
  439.     OSTCBFreeList     = ptcb;
  440. #if OS_TASK_NAME_SIZE > 1
  441.     ptcb->OSTCBTaskName[0] = '?';                               /* Unknown name                        */
  442.     ptcb->OSTCBTaskName[1] = OS_ASCII_NUL;
  443. #endif
  444.     OS_EXIT_CRITICAL();
  445.     OS_Sched();                                                 /* Find new highest priority task      */
  446.     return (OS_NO_ERR);
  447. }
  448. #endif
  449. /*$PAGE*/
  450. /*
  451. *********************************************************************************************************
  452. *                                    REQUEST THAT A TASK DELETE ITSELF
  453. *
  454. * Description: This function is used to:
  455. *                   a) notify a task to delete itself.
  456. *                   b) to see if a task requested that the current task delete itself.
  457. *              This function is a little tricky to understand.  Basically, you have a task that needs
  458. *              to be deleted however, this task has resources that it has allocated (memory buffers,
  459. *              semaphores, mailboxes, queues etc.).  The task cannot be deleted otherwise these
  460. *              resources would not be freed.  The requesting task calls OSTaskDelReq() to indicate that
  461. *              the task needs to be deleted.  Deleting of the task is however, deferred to the task to
  462. *              be deleted.  For example, suppose that task #10 needs to be deleted.  The requesting task
  463. *              example, task #5, would call OSTaskDelReq(10).  When task #10 gets to execute, it calls
  464. *              this function by specifying OS_PRIO_SELF and monitors the returned value.  If the return
  465. *              value is OS_TASK_DEL_REQ, another task requested a task delete.  Task #10 would look like
  466. *              this:
  467. *
  468. *                   void Task(void *p_arg)
  469. *                   {
  470. *                       .
  471. *                       .
  472. *                       while (1) {
  473. *                           OSTimeDly(1);
  474. *                           if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
  475. *                               Release any owned resources;
  476. *                               De-allocate any dynamic memory;
  477. *                               OSTaskDel(OS_PRIO_SELF);
  478. *                           }
  479. *                       }
  480. *                   }
  481. *
  482. * Arguments  : prio    is the priority of the task to request the delete from
  483. *
  484. * Returns    : OS_NO_ERR          if the task exist and the request has been registered
  485. *              OS_TASK_NOT_EXIST  if the task has been deleted.  This allows the caller to know whether
  486. *                                 the request has been executed.
  487. *              OS_TASK_DEL_ERR    if the task is assigned to a Mutex.
  488. *              OS_TASK_DEL_IDLE   if you requested to delete uC/OS-II's idle task
  489. *              OS_PRIO_INVALID    if the priority you specify is higher that the maximum allowed
  490. *                                 (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  491. *              OS_TASK_DEL_REQ    if a task (possibly another task) requested that the running task be
  492. *                                 deleted.
  493. *********************************************************************************************************
  494. */
  495. /*$PAGE*/
  496. #if OS_TASK_DEL_EN > 0
  497. INT8U  OSTaskDelReq (INT8U prio)
  498. {
  499.     INT8U      stat;
  500.     OS_TCB    *ptcb;
  501. #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  502.     OS_CPU_SR  cpu_sr;
  503.     cpu_sr = 0;                                                 /* Prevent compiler warning            */
  504. #endif    
  505. #if OS_ARG_CHK_EN > 0
  506.     if (prio == OS_IDLE_PRIO) {                                 /* Not allowed to delete idle task     */
  507.         return (OS_TASK_DEL_IDLE);
  508.     }
  509.     if (prio >= OS_LOWEST_PRIO) {         /* Task priority valid ?               */
  510.         if (prio != OS_PRIO_SELF) {                       
  511.             return (OS_PRIO_INVALID);
  512. }
  513.     }
  514. #endif
  515.     if (prio == OS_PRIO_SELF) {                                 /* See if a task is requesting to ...  */
  516.         OS_ENTER_CRITICAL();                                    /* ... this task to delete itself      */
  517.         stat = OSTCBCur->OSTCBDelReq;                           /* Return request status to caller     */
  518.         OS_EXIT_CRITICAL();
  519.         return (stat);
  520.     }
  521.     OS_ENTER_CRITICAL();
  522.     ptcb = OSTCBPrioTbl[prio];
  523.     if (ptcb == (OS_TCB *)0) {                                  /* Task to delete must exist           */
  524.         OS_EXIT_CRITICAL();
  525.         return (OS_TASK_NOT_EXIST);                             /* Task must already be deleted        */
  526.     }
  527.     if (ptcb == (OS_TCB *)1) {                                  /* Must NOT be assigned to a Mutex     */
  528.         OS_EXIT_CRITICAL();
  529.         return (OS_TASK_DEL_ERR);
  530.     }
  531.     ptcb->OSTCBDelReq = OS_TASK_DEL_REQ;                        /* Set flag indicating task to be DEL. */
  532.     OS_EXIT_CRITICAL();
  533.     return (OS_NO_ERR);
  534. }
  535. #endif
  536. /*$PAGE*/
  537. /*
  538. *********************************************************************************************************
  539. *                                        GET THE NAME OF A TASK
  540. *
  541. * Description: This function is called to obtain the name of a task.
  542. *
  543. * Arguments  : prio      is the priority of the task that you want to obtain the name from.
  544. *
  545. *              pname     is a pointer to an ASCII string that will receive the name of the task.  The 
  546. *                        string must be able to hold at least OS_TASK_NAME_SIZE characters.
  547. *
  548. *              err       is a pointer to an error code that can contain one of the following values:
  549. *
  550. *                        OS_NO_ERR                  if the requested task is resumed
  551. *                        OS_TASK_NOT_EXIST          if the task has not been created or is assigned to a Mutex
  552. *                        OS_PRIO_INVALID            if you specified an invalid priority:
  553. *                                                   A higher value than the idle task or not OS_PRIO_SELF.
  554. *                        OS_ERR_PNAME_NULL          You passed a NULL pointer for 'pname'
  555. *
  556. * Returns    : The length of the string or 0 if the task does not exist.
  557. *********************************************************************************************************
  558. */
  559. #if OS_TASK_NAME_SIZE > 1
  560. INT8U  OSTaskNameGet (INT8U prio, char *pname, INT8U *err)
  561. {
  562.     OS_TCB    *ptcb;
  563.     INT8U      len;
  564. #if OS_CRITICAL_METHOD == 3                              /* Allocate storage for CPU status register   */
  565.     OS_CPU_SR  cpu_sr;
  566.     cpu_sr = 0;                                          /* Prevent compiler warning                   */
  567. #endif    
  568. #if OS_ARG_CHK_EN > 0
  569.     if (prio > OS_LOWEST_PRIO) {                         /* Task priority valid ?                      */
  570.         if (prio != OS_PRIO_SELF) { 
  571.             *err = OS_PRIO_INVALID;                      /* No                                         */
  572.             return (0);
  573.         }
  574.     }
  575.     if (pname == (char *)0) {                             /* Is 'pname' a NULL pointer?                */
  576.         *err = OS_ERR_PNAME_NULL;   /* Yes                                       */
  577.         return (0);
  578.     }
  579. #endif
  580.     OS_ENTER_CRITICAL();
  581.     if (prio == OS_PRIO_SELF) {                           /* See if caller desires it's own name       */
  582.         prio = OSTCBCur->OSTCBPrio;
  583.     }
  584.     ptcb = OSTCBPrioTbl[prio];
  585.     if (ptcb == (OS_TCB *)0) {                            /* Does task exist?                          */
  586.         OS_EXIT_CRITICAL();                               /* No                                        */
  587.         *err = OS_TASK_NOT_EXIST;
  588.         return (0);
  589.     }
  590.     if (ptcb == (OS_TCB *)1) {                            /* Task assigned to a Mutex?                 */
  591.         OS_EXIT_CRITICAL();                               /* Yes                                       */
  592.         *err = OS_TASK_NOT_EXIST;
  593.         return (0);
  594.     }
  595.     len  = OS_StrCopy(pname, ptcb->OSTCBTaskName);        /* Yes, copy name from TCB                   */
  596.     OS_EXIT_CRITICAL();
  597.     *err = OS_NO_ERR;
  598.     return (len);
  599. }
  600. #endif
  601. /*$PAGE*/
  602. /*
  603. *********************************************************************************************************
  604. *                                        ASSIGN A NAME TO A TASK
  605. *
  606. * Description: This function is used to set the name of a task.
  607. *
  608. * Arguments  : prio      is the priority of the task that you want the assign a name to.
  609. *
  610. *              pname     is a pointer to an ASCII string that contains the name of the task.  The ASCII
  611. *                        string must be NUL terminated.
  612. *
  613. *              err       is a pointer to an error code that can contain one of the following values:
  614. *
  615. *                        OS_NO_ERR                  if the requested task is resumed
  616. *                        OS_TASK_NOT_EXIST          if the task has not been created or is assigned to a Mutex
  617. *                        OS_ERR_TASK_NAME_TOO_LONG  if the name you are giving to the task exceeds the 
  618. *                                                   storage capacity of a task name as specified by 
  619. *                                                   OS_TASK_NAME_SIZE.
  620. *                        OS_ERR_PNAME_NULL          You passed a NULL pointer for 'pname'
  621. *                        OS_PRIO_INVALID            if you specified an invalid priority:
  622. *                                                   A higher value than the idle task or not OS_PRIO_SELF.
  623. *
  624. * Returns    : None
  625. *********************************************************************************************************
  626. */
  627. #if OS_TASK_NAME_SIZE > 1
  628. void  OSTaskNameSet (INT8U prio, char *pname, INT8U *err)
  629. {
  630.     INT8U      len;
  631.     OS_TCB    *ptcb;
  632. #if OS_CRITICAL_METHOD == 3                          /* Allocate storage for CPU status register       */
  633.     OS_CPU_SR  cpu_sr;
  634.     cpu_sr = 0;                                      /* Prevent compiler warning                       */
  635. #endif    
  636. #if OS_ARG_CHK_EN > 0
  637.     if (prio > OS_LOWEST_PRIO) {                     /* Task priority valid ?                          */
  638.         if (prio != OS_PRIO_SELF) {              
  639.             *err = OS_PRIO_INVALID;                  /* No                                             */
  640.             return;
  641.         }
  642.     }
  643.     if (pname == (char *)0) {                        /* Is 'pname' a NULL pointer?                     */
  644.         *err = OS_ERR_PNAME_NULL;  /* Yes                                            */
  645.         return;
  646.     }
  647. #endif
  648.     OS_ENTER_CRITICAL();
  649.     if (prio == OS_PRIO_SELF) {                      /* See if caller desires to set it's own name     */
  650.         prio = OSTCBCur->OSTCBPrio;
  651.     }
  652.     ptcb = OSTCBPrioTbl[prio];
  653.     if (ptcb == (OS_TCB *)0) {                       /* Does task exist?                               */
  654.         OS_EXIT_CRITICAL();                          /* No                                             */
  655.         *err = OS_TASK_NOT_EXIST;
  656.         return;
  657.     }
  658.     if (ptcb == (OS_TCB *)1) {                       /* Task assigned to a Mutex?                      */
  659.         OS_EXIT_CRITICAL();                          /* Yes                                            */
  660.         *err = OS_TASK_NOT_EXIST;
  661.         return;
  662.     }
  663.     len = OS_StrLen(pname);                          /* Yes, Can we fit the string in the TCB?         */
  664.     if (len > (OS_TASK_NAME_SIZE - 1)) {             /*      No                                        */
  665.         OS_EXIT_CRITICAL();
  666.         *err = OS_ERR_TASK_NAME_TOO_LONG;
  667.         return;
  668.     } 
  669.     (void)OS_StrCopy(ptcb->OSTCBTaskName, pname);    /*      Yes, copy to TCB                          */
  670.     OS_EXIT_CRITICAL();
  671.     *err = OS_NO_ERR;
  672. }
  673. #endif
  674. /*$PAGE*/
  675. /*
  676. *********************************************************************************************************
  677. *                                        RESUME A SUSPENDED TASK
  678. *
  679. * Description: This function is called to resume a previously suspended task.  This is the only call that
  680. *              will remove an explicit task suspension.
  681. *
  682. * Arguments  : prio     is the priority of the task to resume.
  683. *
  684. * Returns    : OS_NO_ERR                if the requested task is resumed
  685. *              OS_PRIO_INVALID          if the priority you specify is higher that the maximum allowed
  686. *                                       (i.e. >= OS_LOWEST_PRIO)
  687. *              OS_TASK_RESUME_PRIO      if the task to resume does not exist
  688. *              OS_TASK_NOT_EXIST        if the task is assigned to a Mutex PIP
  689. *              OS_TASK_NOT_SUSPENDED    if the task to resume has not been suspended
  690. *********************************************************************************************************
  691. */
  692. #if OS_TASK_SUSPEND_EN > 0
  693. INT8U  OSTaskResume (INT8U prio)
  694. {
  695.     OS_TCB    *ptcb;
  696. #if OS_CRITICAL_METHOD == 3                                   /* Storage for CPU status register       */
  697.     OS_CPU_SR  cpu_sr;
  698.     cpu_sr = 0;                                               /* Prevent compiler warning              */
  699. #endif    
  700. #if OS_ARG_CHK_EN > 0
  701.     if (prio >= OS_LOWEST_PRIO) {                             /* Make sure task priority is valid      */
  702.         return (OS_PRIO_INVALID);
  703.     }
  704. #endif
  705.     OS_ENTER_CRITICAL();
  706.     ptcb = OSTCBPrioTbl[prio];
  707.     if (ptcb == (OS_TCB *)0) {                                /* Task to suspend must exist            */
  708.         OS_EXIT_CRITICAL();
  709.         return (OS_TASK_RESUME_PRIO);
  710.     }
  711.     if (ptcb == (OS_TCB *)1) {                                /* See if assigned to Mutex              */
  712.         OS_EXIT_CRITICAL();
  713.         return (OS_TASK_NOT_EXIST);
  714.     }
  715.     if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended                */
  716.         ptcb->OSTCBStat &= ~OS_STAT_SUSPEND;   /* Remove suspension                     */
  717.         if (ptcb->OSTCBStat == OS_STAT_RDY) {                 /* See if task is now ready              */
  718.             if (ptcb->OSTCBDly == 0) {
  719.                 OSRdyGrp               |= ptcb->OSTCBBitY;    /* Yes, Make task ready to run           */
  720.                 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
  721.                 OS_EXIT_CRITICAL();
  722.                 OS_Sched();
  723.             } else {
  724.                 OS_EXIT_CRITICAL();
  725.             }
  726.         } else {                                              /* Must be pending on event              */
  727.     OS_EXIT_CRITICAL();
  728.         }
  729.         return (OS_NO_ERR);
  730.     }
  731.     OS_EXIT_CRITICAL();
  732.     return (OS_TASK_NOT_SUSPENDED);
  733. }
  734. #endif
  735. /*$PAGE*/
  736. /*
  737. *********************************************************************************************************
  738. *                                             STACK CHECKING
  739. *
  740. * Description: This function is called to check the amount of free memory left on the specified task's
  741. *              stack.
  742. *
  743. * Arguments  : prio          is the task priority
  744. *
  745. *              p_stk_data    is a pointer to a data structure of type OS_STK_DATA.
  746. *
  747. * Returns    : OS_NO_ERR           upon success
  748. *              OS_PRIO_INVALID     if the priority you specify is higher that the maximum allowed
  749. *                                  (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  750. *              OS_TASK_NOT_EXIST   if the desired task has not been created or is assigned to a Mutex PIP
  751. *              OS_TASK_OPT_ERR     if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
  752. *********************************************************************************************************
  753. */
  754. #if OS_TASK_CREATE_EXT_EN > 0
  755. INT8U  OSTaskStkChk (INT8U prio, OS_STK_DATA *p_stk_data)
  756. {
  757.     OS_TCB    *ptcb;
  758.     OS_STK    *pchk;
  759.     INT32U     free;
  760.     INT32U     size;
  761. #if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
  762.     OS_CPU_SR  cpu_sr;
  763.     cpu_sr = 0;                                        /* Prevent compiler warning                     */
  764. #endif    
  765. #if OS_ARG_CHK_EN > 0
  766.     if (prio > OS_LOWEST_PRIO) {    /* Make sure task priority is valid             */
  767.         if (prio != OS_PRIO_SELF) {        
  768.             return (OS_PRIO_INVALID);
  769.         }
  770.     }
  771. #endif
  772.     p_stk_data->OSFree = 0;                            /* Assume failure, set to 0 size                */
  773.     p_stk_data->OSUsed = 0;
  774.     OS_ENTER_CRITICAL();
  775.     if (prio == OS_PRIO_SELF) {                        /* See if check for SELF                        */
  776.         prio = OSTCBCur->OSTCBPrio;
  777.     }
  778.     ptcb = OSTCBPrioTbl[prio];
  779.     if (ptcb == (OS_TCB *)0) {                         /* Make sure task exist                         */
  780.         OS_EXIT_CRITICAL();
  781.         return (OS_TASK_NOT_EXIST);
  782.     }
  783.     if (ptcb == (OS_TCB *)1) {
  784.         OS_EXIT_CRITICAL();
  785.         return (OS_TASK_NOT_EXIST);
  786.     }  
  787.     if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set       */
  788.         OS_EXIT_CRITICAL();
  789.         return (OS_TASK_OPT_ERR);
  790.     }
  791.     free = 0;
  792.     size = ptcb->OSTCBStkSize;
  793.     pchk = ptcb->OSTCBStkBottom;
  794.     OS_EXIT_CRITICAL();
  795. #if OS_STK_GROWTH == 1
  796.     while (*pchk++ == (OS_STK)0) {                    /* Compute the number of zero entries on the stk */
  797.         free++;
  798.     }
  799. #else
  800.     while (*pchk-- == (OS_STK)0) {
  801.         free++;
  802.     }
  803. #endif
  804.     p_stk_data->OSFree = free * sizeof(OS_STK);           /* Compute number of free bytes on the stack */
  805.     p_stk_data->OSUsed = (size - free) * sizeof(OS_STK);  /* Compute number of bytes used on the stack */
  806.     return (OS_NO_ERR);
  807. }
  808. #endif
  809. /*$PAGE*/
  810. /*
  811. *********************************************************************************************************
  812. *                                            SUSPEND A TASK
  813. *
  814. * Description: This function is called to suspend a task.  The task can be the calling task if the
  815. *              priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF.
  816. *
  817. * Arguments  : prio     is the priority of the task to suspend.  If you specify OS_PRIO_SELF, the
  818. *                       calling task will suspend itself and rescheduling will occur.
  819. *
  820. * Returns    : OS_NO_ERR                if the requested task is suspended
  821. *              OS_TASK_SUSPEND_IDLE     if you attempted to suspend the idle task which is not allowed.
  822. *              OS_PRIO_INVALID          if the priority you specify is higher that the maximum allowed
  823. *                                       (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  824. *              OS_TASK_SUSPEND_PRIO     if the task to suspend does not exist
  825. *              OS_TASK_NOT_EXITS        if the task is assigned to a Mutex PIP
  826. *
  827. * Note       : You should use this function with great care.  If you suspend a task that is waiting for
  828. *              an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from
  829. *              running when the event arrives.
  830. *********************************************************************************************************
  831. */
  832. #if OS_TASK_SUSPEND_EN > 0
  833. INT8U  OSTaskSuspend (INT8U prio)
  834. {
  835.     BOOLEAN    self;
  836.     OS_TCB    *ptcb;
  837. INT8U      y;
  838. #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  839.     OS_CPU_SR  cpu_sr;
  840.     cpu_sr = 0;                                                 /* Prevent compiler warning            */
  841. #endif    
  842. #if OS_ARG_CHK_EN > 0
  843.     if (prio == OS_IDLE_PRIO) {                                 /* Not allowed to suspend idle task    */
  844.         return (OS_TASK_SUSPEND_IDLE);
  845.     }
  846.     if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ?               */
  847.         if (prio != OS_PRIO_SELF) {
  848.             return (OS_PRIO_INVALID);
  849.         }
  850.     }
  851. #endif
  852.     OS_ENTER_CRITICAL();
  853.     if (prio == OS_PRIO_SELF) {                                 /* See if suspend SELF                 */
  854.         prio = OSTCBCur->OSTCBPrio;
  855.         self = TRUE;
  856.     } else if (prio == OSTCBCur->OSTCBPrio) {                   /* See if suspending self              */
  857.         self = TRUE;
  858.     } else {
  859.         self = FALSE;                                           /* No suspending another task          */
  860.     }
  861.     ptcb = OSTCBPrioTbl[prio];
  862.     if (ptcb == (OS_TCB *)0) {                                  /* Task to suspend must exist          */
  863.         OS_EXIT_CRITICAL();
  864.         return (OS_TASK_SUSPEND_PRIO);
  865.     }
  866.     if (ptcb == (OS_TCB *)1) {                                  /* See if assigned to Mutex            */
  867.         OS_EXIT_CRITICAL();
  868.         return (OS_TASK_NOT_EXIST);
  869.     }
  870. y            = ptcb->OSTCBY;
  871. OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Make task not ready                 */
  872.     if (OSRdyTbl[y] == 0x00) { 
  873.         OSRdyGrp &= ~ptcb->OSTCBBitY;
  874.     }
  875.     ptcb->OSTCBStat |= OS_STAT_SUSPEND;                         /* Status of task is 'SUSPENDED'       */
  876.     OS_EXIT_CRITICAL();
  877.     if (self == TRUE) {                                         /* Context switch only if SELF         */
  878.         OS_Sched();
  879.     }
  880.     return (OS_NO_ERR);
  881. }
  882. #endif
  883. /*$PAGE*/
  884. /*
  885. *********************************************************************************************************
  886. *                                            QUERY A TASK
  887. *
  888. * Description: This function is called to obtain a copy of the desired task's TCB.
  889. *
  890. * Arguments  : prio         is the priority of the task to obtain information from.
  891. *
  892. *              p_task_data  is a pointer to where the desired task's OS_TCB will be stored.
  893. *
  894. * Returns    : OS_NO_ERR          if the requested task is suspended
  895. *              OS_PRIO_INVALID    if the priority you specify is higher that the maximum allowed
  896. *                                 (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  897. *              OS_PRIO_ERR        if the desired task has not been created
  898. *              OS_TASK_NOT_EXIST  if the task is assigned to a Mutex PIP
  899. *********************************************************************************************************
  900. */
  901. #if OS_TASK_QUERY_EN > 0
  902. INT8U  OSTaskQuery (INT8U prio, OS_TCB *p_task_data)
  903. {
  904.     OS_TCB    *ptcb;
  905. #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  906.     OS_CPU_SR  cpu_sr;
  907.     cpu_sr = 0;                                  /* Prevent compiler warning                           */
  908. #endif    
  909. #if OS_ARG_CHK_EN > 0
  910.     if (prio > OS_LOWEST_PRIO) {  /* Task priority valid ?                            */
  911.         if (prio != OS_PRIO_SELF) {   
  912.             return (OS_PRIO_INVALID);
  913.         }
  914.     }
  915. #endif
  916.     OS_ENTER_CRITICAL();
  917.     if (prio == OS_PRIO_SELF) {                  /* See if suspend SELF                                */
  918.         prio = OSTCBCur->OSTCBPrio;
  919.     }
  920.     ptcb = OSTCBPrioTbl[prio];
  921.     if (ptcb == (OS_TCB *)0) {                   /* Task to query must exist                           */
  922.         OS_EXIT_CRITICAL();
  923.         return (OS_PRIO_ERR);
  924.     }
  925.     if (ptcb == (OS_TCB *)1) {                   /* Task to query must not be assigned to a Mutex      */
  926.         OS_EXIT_CRITICAL();
  927.         return (OS_TASK_NOT_EXIST);
  928.     }
  929.                                                  /* Copy TCB into user storage area                    */
  930.     OS_MemCopy((INT8U *)p_task_data, (INT8U *)ptcb, sizeof(OS_TCB));  
  931.     OS_EXIT_CRITICAL();
  932.     return (OS_NO_ERR);
  933. }
  934. #endif
  935. /*$PAGE*/
  936. /*
  937. *********************************************************************************************************
  938. *                                        CLEAR TASK STACK
  939. *
  940. * Description: This function is used to clear the stack of a task (i.e. write all zeros)
  941. *
  942. * Arguments  : pbos     is a pointer to the task's bottom of stack.  If the configuration constant
  943. *                       OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
  944. *                       memory to low memory).  'pbos' will thus point to the lowest (valid) memory
  945. *                       location of the stack.  If OS_STK_GROWTH is set to 0, 'pbos' will point to the
  946. *                       highest memory location of the stack and the stack will grow with increasing
  947. *                       memory locations.  'pbos' MUST point to a valid 'free' data item.
  948. *
  949. *              size     is the number of 'stack elements' to clear.
  950. *
  951. *              opt      contains additional information (or options) about the behavior of the task.  The
  952. *                       LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
  953. *                       specific.  See OS_TASK_OPT_??? in uCOS-II.H.
  954. *
  955. * Returns    : none
  956. *********************************************************************************************************
  957. */
  958. #if OS_TASK_CREATE_EXT_EN > 0
  959. void  OS_TaskStkClr (OS_STK *pbos, INT32U size, INT16U opt)
  960. {
  961.     if ((opt & OS_TASK_OPT_STK_CHK) != 0x0000) {       /* See if stack checking has been enabled       */
  962.         if ((opt & OS_TASK_OPT_STK_CLR) != 0x0000) {   /* See if stack needs to be cleared             */
  963. #if OS_STK_GROWTH == 1                     
  964.             while (size > 0) {                         /* Stack grows from HIGH to LOW memory          */
  965.                 size--;
  966.                 *pbos++ = (OS_STK)0;                   /* Clear from bottom of stack and up!           */
  967.             }
  968. #else
  969.             while (size > 0) {                         /* Stack grows from LOW to HIGH memory          */
  970.                 size--;
  971.                 *pbos-- = (OS_STK)0;                   /* Clear from bottom of stack and down          */
  972.             }
  973. #endif
  974.         }
  975.     }
  976. }
  977. #endif