OS_TASK.lst
上传用户:tzjinxin1
上传日期:2022-08-08
资源大小:272k
文件大小:48k
开发平台:

Visual C++

  1. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 1   
  2. C51 COMPILER V8.02, COMPILATION OF MODULE OS_TASK
  3. OBJECT MODULE PLACED IN .objOS_TASK.obj
  4. COMPILER INVOKED BY: C:KeilC51BINC51.EXE uCosiiOS_TASK.C LARGE BROWSE DEBUG OBJECTEXTEND PRINT(.lstOS_TASK.lst) O
  5.                     -BJECT(.objOS_TASK.obj)
  6. line level    source
  7.    1          /*
  8.    2          *********************************************************************************************************
  9.    3          *                                                uC/OS-II
  10.    4          *                                          The Real-Time Kernel
  11.    5          *                                            TASK MANAGEMENT
  12.    6          *
  13.    7          *                          (c) Copyright 1992-2001, Jean J. Labrosse, Weston, FL
  14.    8          *                                           All Rights Reserved
  15.    9          *
  16.   10          * File : OS_TASK.C
  17.   11          * By   : Jean J. Labrosse
  18.   12          *********************************************************************************************************
  19.   13          */
  20.   14          
  21.   15          #ifndef  OS_MASTER_FILE
  22.   16          #include "sourceincludes.h"
  23.   17          #endif
  24.   18          
  25.   19          /*
  26.   20          *********************************************************************************************************
  27.   21          *                                        CHANGE PRIORITY OF A TASK
  28.   22          *
  29.   23          * Description: This function allows you to change the priority of a task dynamically.  Note that the new
  30.   24          *              priority MUST be available.
  31.   25          *
  32.   26          * Arguments  : oldp     is the old priority
  33.   27          *
  34.   28          *              newp     is the new priority
  35.   29          *
  36.   30          * Returns    : OS_NO_ERR        is the call was successful
  37.   31          *              OS_PRIO_INVALID  if the priority you specify is higher that the maximum allowed
  38.   32          *                               (i.e. >= OS_LOWEST_PRIO)
  39.   33          *              OS_PRIO_EXIST    if the new priority already exist.
  40.   34          *              OS_PRIO_ERR      there is no task with the specified OLD priority (i.e. the OLD task does
  41.   35          *                               not exist.
  42.   36          *********************************************************************************************************
  43.   37          */
  44.   38          
  45.   39          #if OS_TASK_CHANGE_PRIO_EN > 0
  46.               INT8U  OSTaskChangePrio (INT8U oldprio, INT8U newprio) reentrant
  47.               {
  48.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  49.                   OS_CPU_SR    cpu_sr;
  50.               #endif
  51.               
  52.               #if OS_EVENT_EN > 0
  53.                   OS_EVENT    *pevent;
  54.               #endif
  55.               
  56.                   OS_TCB      *ptcb;
  57.                   INT8U        x;
  58.                   INT8U        y;
  59.                   INT8U        bitx;
  60.                   INT8U        bity;
  61. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 2   
  62.               
  63.               
  64.               
  65.               #if OS_ARG_CHK_EN > 0
  66.                   if ((oldprio >= OS_LOWEST_PRIO && oldprio != OS_PRIO_SELF)  ||
  67.                        newprio >= OS_LOWEST_PRIO) {
  68.                       return (OS_PRIO_INVALID);
  69.                   }
  70.               #endif
  71.                   OS_ENTER_CRITICAL();
  72.                   if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) {                 /* New priority must not already exist */
  73.                       OS_EXIT_CRITICAL();
  74.                       return (OS_PRIO_EXIST);
  75.                   } else {
  76.                       OSTCBPrioTbl[newprio] = (OS_TCB *)1;                    /* Reserve the entry to prevent others */
  77.                       OS_EXIT_CRITICAL();
  78.                       y    = newprio >> 3;                                    /* Precompute to reduce INT. latency   */
  79.                       bity = OSMapTbl[y];
  80.                       x    = newprio & 0x07;
  81.                       bitx = OSMapTbl[x];
  82.                       OS_ENTER_CRITICAL();
  83.                       if (oldprio == OS_PRIO_SELF) {                          /* See if changing self                */
  84.                           oldprio = OSTCBCur->OSTCBPrio;                      /* Yes, get priority                   */
  85.                       }
  86.                       if ((ptcb = OSTCBPrioTbl[oldprio]) != (OS_TCB *)0) {    /* Task to change must exist           */
  87.                           OSTCBPrioTbl[oldprio] = (OS_TCB *)0;                /* Remove TCB from old priority        */
  88.                           if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) {  /* If task is ready make it not */
  89.                               if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
  90.                                   OSRdyGrp &= ~ptcb->OSTCBBitY;
  91.                               }
  92.                               OSRdyGrp    |= bity;                            /* Make new priority ready to run      */
  93.                               OSRdyTbl[y] |= bitx;
  94.               #if OS_EVENT_EN > 0
  95.                           } else {
  96.                               if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0) { /* Remove from event wait list  */
  97.                                   if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {
  98.                                       pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
  99.                                   }
  100.                                   pevent->OSEventGrp    |= bity;              /* Add new priority to wait list       */
  101.                                   pevent->OSEventTbl[y] |= bitx;
  102.                               }
  103.               #endif
  104.                           }
  105.                           OSTCBPrioTbl[newprio] = ptcb;                       /* Place pointer to TCB @ new priority */
  106.                           ptcb->OSTCBPrio       = newprio;                    /* Set new task priority               */
  107.                           ptcb->OSTCBY          = y;
  108.                           ptcb->OSTCBX          = x;
  109.                           ptcb->OSTCBBitY       = bity;
  110.                           ptcb->OSTCBBitX       = bitx;
  111.                           OS_EXIT_CRITICAL();
  112.                           OS_Sched();                                         /* Run highest priority task ready     */
  113.                           return (OS_NO_ERR);
  114.                       } else {
  115.                           OSTCBPrioTbl[newprio] = (OS_TCB *)0;                /* Release the reserved prio.          */
  116.                           OS_EXIT_CRITICAL();
  117.                           return (OS_PRIO_ERR);                               /* Task to change didn't exist         */
  118.                       }
  119.                   }
  120.               }
  121.               #endif
  122.  115          /*$PAGE*/
  123.  116          /*
  124. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 3   
  125.  117          *********************************************************************************************************
  126.  118          *                                            CREATE A TASK
  127.  119          *
  128.  120          * Description: This function is used to have uC/OS-II manage the execution of a task.  Tasks can either
  129.  121          *              be created prior to the start of multitasking or by a running task.  A task cannot be
  130.  122          *              created by an ISR.
  131.  123          *
  132.  124          * Arguments  : task     is a pointer to the task's code
  133.  125          *
  134.  126          *              ppdata   is a pointer to an optional data area which can be used to pass parameters to
  135.  127          *                       the task when the task first executes.  Where the task is concerned it thinks
  136.  128          *                       it was invoked and passed the argument 'ppdata' as follows:
  137.  129          *
  138.  130          *                           void Task (void *ppdata)
  139.  131          *                           {
  140.  132          *                               for (;;) {
  141.  133          *                                   Task code;
  142.  134          *                               }
  143.  135          *                           }
  144.  136          *
  145.  137          *              ptos     is a pointer to the task's top of stack.  If the configuration constant
  146.  138          *                       OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
  147.  139          *                       memory to low memory).  'pstk' will thus point to the highest (valid) memory
  148.  140          *                       location of the stack.  If OS_STK_GROWTH is set to 0, 'pstk' will point to the
  149.  141          *                       lowest memory location of the stack and the stack will grow with increasing
  150.  142          *                       memory locations.
  151.  143          *
  152.  144          *              prio     is the task's priority.  A unique priority MUST be assigned to each task and the
  153.  145          *                       lower the number, the higher the priority.
  154.  146          *
  155.  147          * Returns    : OS_NO_ERR        if the function was successful.
  156.  148          *              OS_PRIO_EXIT     if the task priority already exist
  157.  149          *                               (each task MUST have a unique priority).
  158.  150          *              OS_PRIO_INVALID  if the priority you specify is higher that the maximum allowed
  159.  151          *                               (i.e. >= OS_LOWEST_PRIO)
  160.  152          *********************************************************************************************************
  161.  153          */
  162.  154          
  163.  155          #if OS_TASK_CREATE_EN > 0
  164.  156          INT8U  OSTaskCreate (void (*task)(void *pd) reentrant, void *ppdata, OS_STK *ptos, INT8U prio) reentrant
  165.  157          {
  166.  158   1      #if OS_CRITICAL_METHOD == 3                  /* Allocate storage for CPU status register               */
  167.                   OS_CPU_SR  cpu_sr;
  168.               #endif
  169.  161   1          OS_STK    *psp;
  170.  162   1          INT8U      err;
  171.  163   1      
  172.  164   1      
  173.  165   1      #if OS_ARG_CHK_EN > 0
  174.  166   1          if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */
  175.  167   2              return (OS_PRIO_INVALID);
  176.  168   2          }
  177.  169   1      #endif
  178.  170   1          OS_ENTER_CRITICAL();
  179.  171   1          if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */
  180.  172   2              OSTCBPrioTbl[prio] = (OS_TCB *)1;    /* Reserve the priority to prevent others from doing ...  */
  181.  173   2                                                   /* ... the same thing until task is created.              */
  182.  174   2              OS_EXIT_CRITICAL();
  183.  175   2              psp = (OS_STK *)OSTaskStkInit(task, ppdata, ptos, 0);    /* Initialize the task's stack         */
  184.  176   2              err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
  185.  177   2              if (err == OS_NO_ERR) {
  186.  178   3                  OS_ENTER_CRITICAL();
  187. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 4   
  188.  179   3                  OSTaskCtr++;                                        /* Increment the #tasks counter        */
  189.  180   3                  OS_EXIT_CRITICAL();
  190.  181   3                  if (OSRunning == TRUE) {         /* Find highest priority task if multitasking has started */
  191.  182   4                      OS_Sched();
  192.  183   4                  }
  193.  184   3              } else {
  194.  185   3                  OS_ENTER_CRITICAL();
  195.  186   3                  OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others                 */
  196.  187   3                  OS_EXIT_CRITICAL();
  197.  188   3              }
  198.  189   2              return (err);
  199.  190   2          }
  200.  191   1          OS_EXIT_CRITICAL();
  201.  192   1          return (OS_PRIO_EXIST);
  202.  193   1      }
  203.  194          #endif
  204.  195          /*$PAGE*/
  205.  196          /*
  206.  197          *********************************************************************************************************
  207.  198          *                                     CREATE A TASK (Extended Version)
  208.  199          *
  209.  200          * Description: This function is used to have uC/OS-II manage the execution of a task.  Tasks can either
  210.  201          *              be created prior to the start of multitasking or by a running task.  A task cannot be
  211.  202          *              created by an ISR.  This function is similar to OSTaskCreate() except that it allows
  212.  203          *              additional information about a task to be specified.
  213.  204          *
  214.  205          * Arguments  : task     is a pointer to the task's code
  215.  206          *
  216.  207          *              ppdata   is a pointer to an optional data area which can be used to pass parameters to
  217.  208          *                       the task when the task first executes.  Where the task is concerned it thinks
  218.  209          *                       it was invoked and passed the argument 'pdata' as follows:
  219.  210          *
  220.  211          *                           void Task (void *ppdata)
  221.  212          *                           {
  222.  213          *                               for (;;) {
  223.  214          *                                   Task code;
  224.  215          *                               }
  225.  216          *                           }
  226.  217          *
  227.  218          *              ptos     is a pointer to the task's top of stack.  If the configuration constant
  228.  219          *                       OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
  229.  220          *                       memory to low memory).  'pstk' will thus point to the highest (valid) memory
  230.  221          *                       location of the stack.  If OS_STK_GROWTH is set to 0, 'pstk' will point to the
  231.  222          *                       lowest memory location of the stack and the stack will grow with increasing
  232.  223          *                       memory locations.  'pstk' MUST point to a valid 'free' data item.
  233.  224          *
  234.  225          *              prio     is the task's priority.  A unique priority MUST be assigned to each task and the
  235.  226          *                       lower the number, the higher the priority.
  236.  227          *
  237.  228          *              id       is the task's ID (0..65535)
  238.  229          *
  239.  230          *              pbos     is a pointer to the task's bottom of stack.  If the configuration constant
  240.  231          *                       OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
  241.  232          *                       memory to low memory).  'pbos' will thus point to the LOWEST (valid) memory
  242.  233          *                       location of the stack.  If OS_STK_GROWTH is set to 0, 'pbos' will point to the
  243.  234          *                       HIGHEST memory location of the stack and the stack will grow with increasing
  244.  235          *                       memory locations.  'pbos' MUST point to a valid 'free' data item.
  245.  236          *
  246.  237          *              stk_size is the size of the stack in number of elements.  If OS_STK is set to INT8U,
  247.  238          *                       'stk_size' corresponds to the number of bytes available.  If OS_STK is set to
  248.  239          *                       INT16U, 'stk_size' contains the number of 16-bit entries available.  Finally, if
  249.  240          *                       OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries
  250. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 5   
  251.  241          *                       available on the stack.
  252.  242          *
  253.  243          *              pext     is a pointer to a user supplied memory location which is used as a TCB extension.
  254.  244          *                       For example, this user memory can hold the contents of floating-point registers
  255.  245          *                       during a context switch, the time each task takes to execute, the number of times
  256.  246          *                       the task has been switched-in, etc.
  257.  247          *
  258.  248          *              opt      contains additional information (or options) about the behavior of the task.  The
  259.  249          *                       LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
  260.  250          *                       specific.  See OS_TASK_OPT_??? in uCOS-II.H.
  261.  251          *
  262.  252          * Returns    : OS_NO_ERR        if the function was successful.
  263.  253          *              OS_PRIO_EXIT     if the task priority already exist
  264.  254          *                               (each task MUST have a unique priority).
  265.  255          *              OS_PRIO_INVALID  if the priority you specify is higher that the maximum allowed
  266.  256          *                               (i.e. > OS_LOWEST_PRIO)
  267.  257          *********************************************************************************************************
  268.  258          */
  269.  259          /*$PAGE*/
  270.  260          #if OS_TASK_CREATE_EXT_EN > 0
  271.               INT8U  OSTaskCreateExt (void   (*task)(void *pd) reentrant,
  272.                                       void    *ppdata,
  273.                                       OS_STK  *ptos,
  274.                                       INT8U    prio,
  275.                                       INT16U   id,
  276.                                       OS_STK  *pbos,
  277.                                       INT32U   stk_size,
  278.                                       void    *pext,
  279.                                       INT16U   opt) reentrant
  280.               {
  281.               #if OS_CRITICAL_METHOD == 3                  /* Allocate storage for CPU status register               */
  282.                   OS_CPU_SR  cpu_sr;
  283.               #endif
  284.                   OS_STK    *psp;
  285.                   INT8U      err;
  286.               
  287.               
  288.               #if OS_ARG_CHK_EN > 0
  289.                   if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */
  290.                       return (OS_PRIO_INVALID);
  291.                   }
  292.               #endif
  293.                   OS_ENTER_CRITICAL();
  294.                   if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */
  295.                       OSTCBPrioTbl[prio] = (OS_TCB *)1;    /* Reserve the priority to prevent others from doing ...  */
  296.                                                            /* ... the same thing until task is created.              */
  297.                       OS_EXIT_CRITICAL();
  298.               
  299.                       if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) ||   /* See if stack checking has been enabled     */
  300.                           ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) {   /* See if stack needs to be cleared           */
  301.                           #if OS_STK_GROWTH == 1
  302.                           (void)memset(pbos, 0, stk_size * sizeof(OS_STK));
  303.                           #else
  304.                           (void)memset(ptos, 0, stk_size * sizeof(OS_STK));
  305.                           #endif
  306.                       }
  307.               
  308.                       psp = (OS_STK *)OSTaskStkInit(task, ppdata, ptos, opt); /* Initialize the task's stack          */
  309.                       err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
  310.                       if (err == OS_NO_ERR) {
  311.                           OS_ENTER_CRITICAL();
  312.                           OSTaskCtr++;                                       /* Increment the #tasks counter         */
  313. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 6   
  314.                           OS_EXIT_CRITICAL();
  315.                           if (OSRunning == TRUE) {                           /* Find HPT if multitasking has started */
  316.                               OS_Sched();
  317.                           }
  318.                       } else {
  319.                           OS_ENTER_CRITICAL();
  320.                           OSTCBPrioTbl[prio] = (OS_TCB *)0;                  /* Make this priority avail. to others  */
  321.                           OS_EXIT_CRITICAL();
  322.                       }
  323.                       return (err);
  324.                   }
  325.                   OS_EXIT_CRITICAL();
  326.                   return (OS_PRIO_EXIST);
  327.               }
  328.               #endif
  329.  318          /*$PAGE*/
  330.  319          /*
  331.  320          *********************************************************************************************************
  332.  321          *                                            DELETE A TASK
  333.  322          *
  334.  323          * Description: This function allows you to delete a task.  The calling task can delete itself by
  335.  324          *              its own priority number.  The deleted task is returned to the dormant state and can be
  336.  325          *              re-activated by creating the deleted task again.
  337.  326          *
  338.  327          * Arguments  : prio    is the priority of the task to delete.  Note that you can explicitely delete
  339.  328          *                      the current task without knowing its priority level by setting 'prio' to
  340.  329          *                      OS_PRIO_SELF.
  341.  330          *
  342.  331          * Returns    : OS_NO_ERR           if the call is successful
  343.  332          *              OS_TASK_DEL_IDLE    if you attempted to delete uC/OS-II's idle task
  344.  333          *              OS_PRIO_INVALID     if the priority you specify is higher that the maximum allowed
  345.  334          *                                  (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  346.  335          *              OS_TASK_DEL_ERR     if the task you want to delete does not exist
  347.  336          *              OS_TASK_DEL_ISR     if you tried to delete a task from an ISR
  348.  337          *
  349.  338          * Notes      : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
  350.  339          *                    a) by making it not ready
  351.  340          *                    b) by removing it from any wait lists
  352.  341          *                    c) by preventing OSTimeTick() from making the task ready to run.
  353.  342          *                 The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
  354.  343          *              2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors,
  355.  344          *                 the next instruction following the enable interrupt instruction is ignored.  
  356.  345          *              3) An ISR cannot delete a task.
  357.  346          *              4) The lock nesting counter is incremented because, for a brief instant, if the current
  358.  347          *                 task is being deleted, the current task would not be able to be rescheduled because it
  359.  348          *                 is removed from the ready list.  Incrementing the nesting counter prevents another task
  360.  349          *                 from being schedule.  This means that an ISR would return to the current task which is
  361.  350          *                 being deleted.  The rest of the deletion would thus be able to be completed.
  362.  351          *********************************************************************************************************
  363.  352          */
  364.  353          /*$PAGE*/
  365.  354          #if OS_TASK_DEL_EN > 0
  366.               INT8U  OSTaskDel (INT8U prio) reentrant
  367.               {
  368.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  369.                   OS_CPU_SR     cpu_sr;
  370.               #endif
  371.               
  372.               #if OS_EVENT_EN > 0
  373.                   OS_EVENT     *pevent;
  374.               #endif    
  375.               #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
  376. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 7   
  377.                   OS_FLAG_NODE *pnode;
  378.               #endif
  379.                   OS_TCB       *ptcb;
  380.               
  381.               
  382.               
  383.                   if (OSIntNesting > 0) {                                     /* See if trying to delete from ISR    */
  384.                       return (OS_TASK_DEL_ISR);
  385.                   }
  386.               #if OS_ARG_CHK_EN > 0
  387.                   if (prio == OS_IDLE_PRIO) {                                 /* Not allowed to delete idle task     */
  388.                       return (OS_TASK_DEL_IDLE);
  389.                   }
  390.                   if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {       /* Task priority valid ?               */
  391.                       return (OS_PRIO_INVALID);
  392.                   }
  393.               #endif
  394.                   OS_ENTER_CRITICAL();
  395.                   if (prio == OS_PRIO_SELF) {                                 /* See if requesting to delete self    */
  396.                       prio = OSTCBCur->OSTCBPrio;                             /* Set priority to delete to current   */
  397.                   }
  398.                   if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) {                /* Task to delete must exist      */
  399.                       if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {  /* Make task not ready            */
  400.                           OSRdyGrp &= ~ptcb->OSTCBBitY;
  401.                       }
  402.               #if OS_EVENT_EN > 0
  403.                       pevent = ptcb->OSTCBEventPtr;
  404.                       if (pevent != (OS_EVENT *)0) {                          /* If task is waiting on event         */
  405.                           if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 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.                               if (OSLockNesting < 255) {
  419.                           OSLockNesting++;
  420.                               }
  421.                       OS_EXIT_CRITICAL();                                     /* Enabling INT. ignores next instruc. */
  422.                       OS_Dummy();                                             /* ... Dummy ensures that INTs will be */
  423.                       OS_ENTER_CRITICAL();                                    /* ... disabled HERE!                  */
  424.                               if (OSLockNesting > 0) {
  425.                           OSLockNesting--;
  426.                               }
  427.                       OSTaskDelHook(ptcb);                                    /* Call user defined hook              */
  428.                       OSTaskCtr--;                                            /* One less task being managed         */
  429.                       OSTCBPrioTbl[prio] = (OS_TCB *)0;                       /* Clear old priority entry            */
  430.                       if (ptcb->OSTCBPrev == (OS_TCB *)0) {                   /* Remove from TCB chain               */
  431.                           ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
  432.                           OSTCBList                  = ptcb->OSTCBNext;
  433.                       } else {
  434.                           ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
  435.                           ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
  436.                       }
  437.                       ptcb->OSTCBNext = OSTCBFreeList;                        /* Return TCB to free TCB list         */
  438.                       OSTCBFreeList   = ptcb;
  439. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 8   
  440.                       OS_EXIT_CRITICAL();
  441.                       OS_Sched();                                             /* Find new highest priority task      */
  442.                       return (OS_NO_ERR);
  443.                   }
  444.                   OS_EXIT_CRITICAL();
  445.                   return (OS_TASK_DEL_ERR);
  446.               }
  447.               #endif
  448.  435          /*$PAGE*/
  449.  436          /*
  450.  437          *********************************************************************************************************
  451.  438          *                                    REQUEST THAT A TASK DELETE ITSELF
  452.  439          *
  453.  440          * Description: This function is used to:
  454.  441          *                   a) notify a task to delete itself.
  455.  442          *                   b) to see if a task requested that the current task delete itself.
  456.  443          *              This function is a little tricky to understand.  Basically, you have a task that needs
  457.  444          *              to be deleted however, this task has resources that it has allocated (memory buffers,
  458.  445          *              semaphores, mailboxes, queues etc.).  The task cannot be deleted otherwise these
  459.  446          *              resources would not be freed.  The requesting task calls OSTaskDelReq() to indicate that
  460.  447          *              the task needs to be deleted.  Deleting of the task is however, deferred to the task to
  461.  448          *              be deleted.  For example, suppose that task #10 needs to be deleted.  The requesting task
  462.  449          *              example, task #5, would call OSTaskDelReq(10).  When task #10 gets to execute, it calls
  463.  450          *              this function by specifying OS_PRIO_SELF and monitors the returned value.  If the return
  464.  451          *              value is OS_TASK_DEL_REQ, another task requested a task delete.  Task #10 would look like
  465.  452          *              this:
  466.  453          *
  467.  454          *                   void Task(void *data)
  468.  455          *                   {
  469.  456          *                       .
  470.  457          *                       .
  471.  458          *                       while (1) {
  472.  459          *                           OSTimeDly(1);
  473.  460          *                           if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
  474.  461          *                               Release any owned resources;
  475.  462          *                               De-allocate any dynamic memory;
  476.  463          *                               OSTaskDel(OS_PRIO_SELF);
  477.  464          *                           }
  478.  465          *                       }
  479.  466          *                   }
  480.  467          *
  481.  468          * Arguments  : prio    is the priority of the task to request the delete from
  482.  469          *
  483.  470          * Returns    : OS_NO_ERR          if the task exist and the request has been registered
  484.  471          *              OS_TASK_NOT_EXIST  if the task has been deleted.  This allows the caller to know whether
  485.  472          *                                 the request has been executed.
  486.  473          *              OS_TASK_DEL_IDLE   if you requested to delete uC/OS-II's idle task
  487.  474          *              OS_PRIO_INVALID    if the priority you specify is higher that the maximum allowed
  488.  475          *                                 (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  489.  476          *              OS_TASK_DEL_REQ    if a task (possibly another task) requested that the running task be
  490.  477          *                                 deleted.
  491.  478          *********************************************************************************************************
  492.  479          */
  493.  480          /*$PAGE*/
  494.  481          #if OS_TASK_DEL_EN > 0
  495.               INT8U  OSTaskDelReq (INT8U prio) reentrant
  496.               {
  497.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  498.                   OS_CPU_SR  cpu_sr;
  499.               #endif
  500.                   BOOLEAN    stat;
  501.                   INT8U      err;
  502. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 9   
  503.                   OS_TCB    *ptcb;
  504.               
  505.               
  506.               #if OS_ARG_CHK_EN > 0
  507.                   if (prio == OS_IDLE_PRIO) {                                 /* Not allowed to delete idle task     */
  508.                       return (OS_TASK_DEL_IDLE);
  509.                   }
  510.                   if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {       /* Task priority valid ?               */
  511.                       return (OS_PRIO_INVALID);
  512.                   }
  513.               #endif
  514.                   if (prio == OS_PRIO_SELF) {                                 /* See if a task is requesting to ...  */
  515.                       OS_ENTER_CRITICAL();                                    /* ... this task to delete itself      */
  516.                       stat = OSTCBCur->OSTCBDelReq;                           /* Return request status to caller     */
  517.                       OS_EXIT_CRITICAL();
  518.                       return (stat);
  519.                   }
  520.                   OS_ENTER_CRITICAL();
  521.                   if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) {           /* Task to delete must exist           */
  522.                       ptcb->OSTCBDelReq = OS_TASK_DEL_REQ;                    /* Set flag indicating task to be DEL. */
  523.                       err               = OS_NO_ERR;
  524.                   } else {
  525.                       err               = OS_TASK_NOT_EXIST;                  /* Task must be deleted                */
  526.                   }
  527.                   OS_EXIT_CRITICAL();
  528.                   return (err);
  529.               }
  530.               #endif
  531.  517          /*$PAGE*/
  532.  518          /*
  533.  519          *********************************************************************************************************
  534.  520          *                                        RESUME A SUSPENDED TASK
  535.  521          *
  536.  522          * Description: This function is called to resume a previously suspended task.  This is the only call that
  537.  523          *              will remove an explicit task suspension.
  538.  524          *
  539.  525          * Arguments  : prio     is the priority of the task to resume.
  540.  526          *
  541.  527          * Returns    : OS_NO_ERR                if the requested task is resumed
  542.  528          *              OS_PRIO_INVALID          if the priority you specify is higher that the maximum allowed
  543.  529          *                                       (i.e. >= OS_LOWEST_PRIO)
  544.  530          *              OS_TASK_RESUME_PRIO      if the task to resume does not exist
  545.  531          *              OS_TASK_NOT_SUSPENDED    if the task to resume has not been suspended
  546.  532          *********************************************************************************************************
  547.  533          */
  548.  534          
  549.  535          #if OS_TASK_SUSPEND_EN > 0
  550.               INT8U  OSTaskResume (INT8U prio) reentrant
  551.               {
  552.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  553.                   OS_CPU_SR  cpu_sr;
  554.               #endif
  555.                   OS_TCB    *ptcb;
  556.               
  557.               
  558.               #if OS_ARG_CHK_EN > 0
  559.                   if (prio >= OS_LOWEST_PRIO) {                               /* Make sure task priority is valid    */
  560.                       return (OS_PRIO_INVALID);
  561.                   }
  562.               #endif
  563.                   OS_ENTER_CRITICAL();
  564.                   if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) {           /* Task to suspend must exist          */
  565. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 10  
  566.                       OS_EXIT_CRITICAL();
  567.                       return (OS_TASK_RESUME_PRIO);
  568.                   }
  569.                   if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != 0x00) {                     /* Task must be suspended   */
  570.                       if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) &&      /* Remove suspension        */
  571.                            (ptcb->OSTCBDly  == 0)) {                                     /* Must not be delayed      */
  572.                           OSRdyGrp               |= ptcb->OSTCBBitY;                     /* Make task ready to run   */
  573.                           OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
  574.                           OS_EXIT_CRITICAL();
  575.                           OS_Sched();
  576.                       } else {
  577.                           OS_EXIT_CRITICAL();
  578.                       }
  579.                       return (OS_NO_ERR);
  580.                   }
  581.                   OS_EXIT_CRITICAL();
  582.                   return (OS_TASK_NOT_SUSPENDED);
  583.               }
  584.               #endif
  585.  570          /*$PAGE*/
  586.  571          /*
  587.  572          *********************************************************************************************************
  588.  573          *                                             STACK CHECKING
  589.  574          *
  590.  575          * Description: This function is called to check the amount of free memory left on the specified task's
  591.  576          *              stack.
  592.  577          *
  593.  578          * Arguments  : prio     is the task priority
  594.  579          *
  595.  580          *              ppdata    is a pointer to a data structure of type OS_STK_DATA.
  596.  581          *
  597.  582          * Returns    : OS_NO_ERR           upon success
  598.  583          *              OS_PRIO_INVALID     if the priority you specify is higher that the maximum allowed
  599.  584          *                                  (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  600.  585          *              OS_TASK_NOT_EXIST   if the desired task has not been created
  601.  586          *              OS_TASK_OPT_ERR     if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
  602.  587          *********************************************************************************************************
  603.  588          */
  604.  589          #if OS_TASK_CREATE_EXT_EN > 0
  605.               INT8U  OSTaskStkChk (INT8U prio, OS_STK_DATA *ppdata) reentrant
  606.               {
  607.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  608.                   OS_CPU_SR  cpu_sr;
  609.               #endif
  610.                   OS_TCB    *ptcb;
  611.                   OS_STK    *pchk;
  612.                   INT32U     free;
  613.                   INT32U     size;
  614.               
  615.               
  616.               #if OS_ARG_CHK_EN > 0
  617.                   if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {        /* Make sure task priority is valid    */
  618.                       return (OS_PRIO_INVALID);
  619.                   }
  620.               #endif
  621.                   ppdata->OSFree = 0;                                          /* Assume failure, set to 0 size       */
  622.                   ppdata->OSUsed = 0;
  623.                   OS_ENTER_CRITICAL();
  624.                   if (prio == OS_PRIO_SELF) {                        /* See if check for SELF                        */
  625.                       prio = OSTCBCur->OSTCBPrio;
  626.                   }
  627.                   ptcb = OSTCBPrioTbl[prio];
  628. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 11  
  629.                   if (ptcb == (OS_TCB *)0) {                         /* Make sure task exist                         */
  630.                       OS_EXIT_CRITICAL();
  631.                       return (OS_TASK_NOT_EXIST);
  632.                   }
  633.                   if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set       */
  634.                       OS_EXIT_CRITICAL();
  635.                       return (OS_TASK_OPT_ERR);
  636.                   }
  637.                   free = 0;
  638.                   size = ptcb->OSTCBStkSize;
  639.                   pchk = ptcb->OSTCBStkBottom;
  640.                   OS_EXIT_CRITICAL();
  641.               #if OS_STK_GROWTH == 1
  642.                   while (*pchk++ == (OS_STK)0) {                    /* Compute the number of zero entries on the stk */
  643.                       free++;
  644.                   }
  645.               #else
  646.                   while (*pchk-- == (OS_STK)0) {
  647.                       free++;
  648.                   }
  649.               #endif
  650.                   ppdata->OSFree = free * sizeof(OS_STK);            /* Compute number of free bytes on the stack     */
  651.                   ppdata->OSUsed = (size - free) * sizeof(OS_STK);   /* Compute number of bytes used on the stack     */
  652.                   return (OS_NO_ERR);
  653.               }
  654.               #endif
  655.  639          /*$PAGE*/
  656.  640          /*
  657.  641          *********************************************************************************************************
  658.  642          *                                            SUSPEND A TASK
  659.  643          *
  660.  644          * Description: This function is called to suspend a task.  The task can be the calling task if the
  661.  645          *              priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF.
  662.  646          *
  663.  647          * Arguments  : prio     is the priority of the task to suspend.  If you specify OS_PRIO_SELF, the
  664.  648          *                       calling task will suspend itself and rescheduling will occur.
  665.  649          *
  666.  650          * Returns    : OS_NO_ERR                if the requested task is suspended
  667.  651          *              OS_TASK_SUSPEND_IDLE     if you attempted to suspend the idle task which is not allowed.
  668.  652          *              OS_PRIO_INVALID          if the priority you specify is higher that the maximum allowed
  669.  653          *                                       (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  670.  654          *              OS_TASK_SUSPEND_PRIO     if the task to suspend does not exist
  671.  655          *
  672.  656          * Note       : You should use this function with great care.  If you suspend a task that is waiting for
  673.  657          *              an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from
  674.  658          *              running when the event arrives.
  675.  659          *********************************************************************************************************
  676.  660          */
  677.  661          
  678.  662          #if OS_TASK_SUSPEND_EN > 0
  679.               INT8U  OSTaskSuspend (INT8U prio) reentrant
  680.               {
  681.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  682.                   OS_CPU_SR  cpu_sr;
  683.               #endif
  684.                   BOOLEAN    self;
  685.                   OS_TCB    *ptcb;
  686.               
  687.               
  688.               #if OS_ARG_CHK_EN > 0
  689.                   if (prio == OS_IDLE_PRIO) {                                 /* Not allowed to suspend idle task    */
  690.                       return (OS_TASK_SUSPEND_IDLE);
  691. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 12  
  692.                   }
  693.                   if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {       /* Task priority valid ?               */
  694.                       return (OS_PRIO_INVALID);
  695.                   }
  696.               #endif
  697.                   OS_ENTER_CRITICAL();
  698.                   if (prio == OS_PRIO_SELF) {                                 /* See if suspend SELF                 */
  699.                       prio = OSTCBCur->OSTCBPrio;
  700.                       self = TRUE;
  701.                   } else if (prio == OSTCBCur->OSTCBPrio) {                   /* See if suspending self              */
  702.                       self = TRUE;
  703.                   } else {
  704.                       self = FALSE;                                           /* No suspending another task          */
  705.                   }
  706.                   if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) {           /* Task to suspend must exist          */
  707.                       OS_EXIT_CRITICAL();
  708.                       return (OS_TASK_SUSPEND_PRIO);
  709.                   }
  710.                   if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { /* Make task not ready                 */
  711.                       OSRdyGrp &= ~ptcb->OSTCBBitY;
  712.                   }
  713.                   ptcb->OSTCBStat |= OS_STAT_SUSPEND;                         /* Status of task is 'SUSPENDED'       */
  714.                   OS_EXIT_CRITICAL();
  715.                   if (self == TRUE) {                                         /* Context switch only if SELF         */
  716.                       OS_Sched();
  717.                   }
  718.                   return (OS_NO_ERR);
  719.               }
  720.               #endif
  721.  704          /*$PAGE*/
  722.  705          /*
  723.  706          *********************************************************************************************************
  724.  707          *                                            QUERY A TASK
  725.  708          *
  726.  709          * Description: This function is called to obtain a copy of the desired task's TCB.
  727.  710          *
  728.  711          * Arguments  : prio     is the priority of the task to obtain information from.
  729.  712          *
  730.  713          * Returns    : OS_NO_ERR       if the requested task is suspended
  731.  714          *              OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
  732.  715          *                              (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  733.  716          *              OS_PRIO_ERR     if the desired task has not been created
  734.  717          *********************************************************************************************************
  735.  718          */
  736.  719          
  737.  720          #if OS_TASK_QUERY_EN > 0
  738.               INT8U  OSTaskQuery (INT8U prio, OS_TCB *ppdata) reentrant
  739.               {
  740.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  741.                   OS_CPU_SR  cpu_sr;
  742.               #endif
  743.                   OS_TCB    *ptcb;
  744.               
  745.               
  746.               #if OS_ARG_CHK_EN > 0
  747.                   if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {   /* Task priority valid ?                    */
  748.                       return (OS_PRIO_INVALID);
  749.                   }
  750.               #endif
  751.                   OS_ENTER_CRITICAL();
  752.                   if (prio == OS_PRIO_SELF) {                            /* See if suspend SELF                      */
  753.                       prio = OSTCBCur->OSTCBPrio;
  754. C51 COMPILER V8.02   OS_TASK                                                               06/22/2006 11:44:40 PAGE 13  
  755.                   }
  756.                   if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) {      /* Task to query must exist                 */
  757.                       OS_EXIT_CRITICAL();
  758.                       return (OS_PRIO_ERR);
  759.                   }
  760.                   memcpy(ppdata, ptcb, sizeof(OS_TCB));                  /* Copy TCB into user storage area          */
  761.                   OS_EXIT_CRITICAL();
  762.                   return (OS_NO_ERR);
  763.               }
  764.               #endif
  765. MODULE INFORMATION:   STATIC OVERLAYABLE
  766.    CODE SIZE        =    384    ----
  767.    CONSTANT SIZE    =   ----    ----
  768.    XDATA SIZE       =   ----    ----
  769.    PDATA SIZE       =   ----    ----
  770.    DATA SIZE        =   ----    ----
  771.    IDATA SIZE       =   ----    ----
  772.    BIT SIZE         =   ----    ----
  773. END OF MODULE INFORMATION.
  774. C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)