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

Visual C++

  1. C51 COMPILER V8.02   OS_SEM                                                                06/22/2006 11:44:39 PAGE 1   
  2. C51 COMPILER V8.02, COMPILATION OF MODULE OS_SEM
  3. OBJECT MODULE PLACED IN .objOS_SEM.obj
  4. COMPILER INVOKED BY: C:KeilC51BINC51.EXE uCosiiOS_SEM.C LARGE BROWSE DEBUG OBJECTEXTEND PRINT(.lstOS_SEM.lst) OBJ
  5.                     -ECT(.objOS_SEM.obj)
  6. line level    source
  7.    1          /*
  8.    2          *********************************************************************************************************
  9.    3          *                                                uC/OS-II
  10.    4          *                                          The Real-Time Kernel
  11.    5          *                                          SEMAPHORE 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_SEM.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          #if OS_SEM_EN > 0
  26.               /*
  27.               *********************************************************************************************************
  28.               *                                           ACCEPT SEMAPHORE
  29.               *
  30.               * Description: This function checks the semaphore to see if a resource is available or, if an event
  31.               *              occurred.  Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the
  32.               *              resource is not available or the event did not occur.
  33.               *
  34.               * Arguments  : pevent     is a pointer to the event control block
  35.               *
  36.               * Returns    : >  0       if the resource is available or the event did not occur the semaphore is
  37.               *                         decremented to obtain the resource.
  38.               *              == 0       if the resource is not available or the event did not occur or,
  39.               *                         if 'pevent' is a NULL pointer or,
  40.               *                         if you didn't pass a pointer to a semaphore
  41.               *********************************************************************************************************
  42.               */
  43.               
  44.               #if OS_SEM_ACCEPT_EN > 0
  45.               INT16U  OSSemAccept (OS_EVENT *pevent) reentrant
  46.               {
  47.               #if OS_CRITICAL_METHOD == 3                           /* Allocate storage for CPU status register      */
  48.                   OS_CPU_SR  cpu_sr;
  49.               #endif    
  50.                   INT16U     cnt;
  51.               
  52.               
  53.               #if OS_ARG_CHK_EN > 0
  54.                   if (pevent == (OS_EVENT *)0) {                    /* Validate 'pevent'                             */
  55.                       return (0);
  56.                   }
  57.                   if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {   /* Validate event block type                     */
  58.                       return (0);
  59.                   }
  60.               #endif
  61. C51 COMPILER V8.02   OS_SEM                                                                06/22/2006 11:44:39 PAGE 2   
  62.                   OS_ENTER_CRITICAL();
  63.                   cnt = pevent->OSEventCnt;
  64.                   if (cnt > 0) {                                    /* See if resource is available                  */
  65.                       pevent->OSEventCnt--;                         /* Yes, decrement semaphore and notify caller    */
  66.                   }
  67.                   OS_EXIT_CRITICAL();
  68.                   return (cnt);                                     /* Return semaphore count                        */
  69.               }
  70.               #endif    
  71.               
  72.               /*$PAGE*/
  73.               /*
  74.               *********************************************************************************************************
  75.               *                                           CREATE A SEMAPHORE
  76.               *
  77.               * Description: This function creates a semaphore.
  78.               *
  79.               * Arguments  : cnt           is the initial value for the semaphore.  If the value is 0, no resource is
  80.               *                            available (or no event has occurred).  You initialize the semaphore to a
  81.               *                            non-zero value to specify how many resources are available (e.g. if you have
  82.               *                            10 resources, you would initialize the semaphore to 10).
  83.               *
  84.               * Returns    : != (void *)0  is a pointer to the event control clock (OS_EVENT) associated with the
  85.               *                            created semaphore
  86.               *              == (void *)0  if no event control blocks were available
  87.               *********************************************************************************************************
  88.               */
  89.               
  90.               OS_EVENT  *OSSemCreate (INT16U cnt) reentrant
  91.               {
  92.               #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  93.                   OS_CPU_SR  cpu_sr;
  94.               #endif    
  95.                   OS_EVENT  *pevent;
  96.               
  97.               
  98.                   if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
  99.                       return ((OS_EVENT *)0);                            /* ... can't CREATE from an ISR             */
  100.                   }
  101.                   OS_ENTER_CRITICAL();
  102.                   pevent = OSEventFreeList;                              /* Get next free event control block        */
  103.                   if (OSEventFreeList != (OS_EVENT *)0) {                /* See if pool of free ECB pool was empty   */
  104.                       OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
  105.                   }
  106.                   OS_EXIT_CRITICAL();
  107.                   if (pevent != (OS_EVENT *)0) {                         /* Get an event control block               */
  108.                       pevent->OSEventType = OS_EVENT_TYPE_SEM;
  109.                       pevent->OSEventCnt  = cnt;                         /* Set semaphore value                      */
  110.                       OS_EventWaitListInit(pevent);
  111.                   }
  112.                   return (pevent);
  113.               }
  114.               
  115.               /*$PAGE*/
  116.               /*
  117.               *********************************************************************************************************
  118.               *                                         DELETE A SEMAPHORE
  119.               *
  120.               * Description: This function deletes a semaphore and readies all tasks pending on the semaphore.
  121.               *
  122.               * Arguments  : pevent        is a pointer to the event control block associated with the desired
  123.               *                            semaphore.
  124. C51 COMPILER V8.02   OS_SEM                                                                06/22/2006 11:44:39 PAGE 3   
  125.               *
  126.               *              opt           determines delete options as follows:
  127.               *                            opt == OS_DEL_NO_PEND   Delete semaphore ONLY if no task pending
  128.               *                            opt == OS_DEL_ALWAYS    Deletes the semaphore even if tasks are waiting.
  129.               *                                                    In this case, all the tasks pending will be readied.
  130.               *
  131.               *              err           is a pointer to an error code that can contain one of the following values:
  132.               *                            OS_NO_ERR               The call was successful and the semaphore was deleted
  133.               *                            OS_ERR_DEL_ISR          If you attempted to delete the semaphore from an ISR
  134.               *                            OS_ERR_INVALID_OPT      An invalid option was specified
  135.               *                            OS_ERR_TASK_WAITING     One or more tasks were waiting on the semaphore
  136.               *                            OS_ERR_EVENT_TYPE       If you didn't pass a pointer to a semaphore
  137.               *                            OS_ERR_PEVENT_NULL      If 'pevent' is a NULL pointer.
  138.               *
  139.               * Returns    : pevent        upon error
  140.               *              (OS_EVENT *)0 if the semaphore was successfully deleted.
  141.               *
  142.               * Note(s)    : 1) This function must be used with care.  Tasks that would normally expect the presence of
  143.               *                 the semaphore MUST check the return code of OSSemPend().
  144.               *              2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless
  145.               *                 they check 'pevent' to see that it's a NULL pointer.
  146.               *              3) This call can potentially disable interrupts for a long time.  The interrupt disable
  147.               *                 time is directly proportional to the number of tasks waiting on the semaphore.
  148.               *              4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in
  149.               *                 applications where the semaphore is used for mutual exclusion because the resource(s)
  150.               *                 will no longer be guarded by the semaphore.
  151.               *********************************************************************************************************
  152.               */
  153.               
  154.               #if OS_SEM_DEL_EN > 0
  155.               OS_EVENT  *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err) reentrant
  156.               {
  157.               #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  158.                   OS_CPU_SR  cpu_sr;
  159.               #endif    
  160.                   BOOLEAN    tasks_waiting;
  161.               
  162.               
  163.                   if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
  164.                       *err = OS_ERR_DEL_ISR;                             /* ... can't DELETE from an ISR             */
  165.                       return (pevent);
  166.                   }
  167.               #if OS_ARG_CHK_EN > 0
  168.                   if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
  169.                       *err = OS_ERR_PEVENT_NULL;
  170.                       return (pevent);
  171.                   }
  172.                   if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {        /* Validate event block type                */
  173.                       *err = OS_ERR_EVENT_TYPE;
  174.                       return (pevent);
  175.                   }
  176.               #endif
  177.                   OS_ENTER_CRITICAL();
  178.                   if (pevent->OSEventGrp != 0x00) {                      /* See if any tasks waiting on semaphore    */
  179.                       tasks_waiting = TRUE;                              /* Yes                                      */
  180.                   } else {
  181.                       tasks_waiting = FALSE;                             /* No                                       */
  182.                   }
  183.                   switch (opt) {
  184.                       case OS_DEL_NO_PEND:                               /* Delete semaphore only if no task waiting */
  185.                            if (tasks_waiting == FALSE) {
  186.                                pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
  187. C51 COMPILER V8.02   OS_SEM                                                                06/22/2006 11:44:39 PAGE 4   
  188.                                pevent->OSEventPtr  = OSEventFreeList;    /* Return Event Control Block to free list  */
  189.                                OSEventFreeList     = pevent;             /* Get next free event control block        */
  190.                                OS_EXIT_CRITICAL();
  191.                                *err = OS_NO_ERR;
  192.                                return ((OS_EVENT *)0);                   /* Semaphore has been deleted               */
  193.                            } else {
  194.                                OS_EXIT_CRITICAL();
  195.                                *err = OS_ERR_TASK_WAITING;
  196.                                return (pevent);
  197.                            }
  198.               
  199.                       case OS_DEL_ALWAYS:                                /* Always delete the semaphore              */
  200.                            while (pevent->OSEventGrp != 0x00) {          /* Ready ALL tasks waiting for semaphore    */
  201.                                OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);
  202.                            }
  203.                            pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
  204.                            pevent->OSEventPtr  = OSEventFreeList;        /* Return Event Control Block to free list  */
  205.                            OSEventFreeList     = pevent;                 /* Get next free event control block        */
  206.                            OS_EXIT_CRITICAL();
  207.                            if (tasks_waiting == TRUE) {                  /* Reschedule only if task(s) were waiting  */
  208.                                OS_Sched();                               /* Find highest priority task ready to run  */
  209.                            }
  210.                            *err = OS_NO_ERR;
  211.                            return ((OS_EVENT *)0);                       /* Semaphore has been deleted               */
  212.               
  213.                       default:
  214.                            OS_EXIT_CRITICAL();
  215.                            *err = OS_ERR_INVALID_OPT;
  216.                            return (pevent);
  217.                   }
  218.               }
  219.               #endif
  220.               
  221.               /*$PAGE*/
  222.               /*
  223.               *********************************************************************************************************
  224.               *                                           PEND ON SEMAPHORE
  225.               *
  226.               * Description: This function waits for a semaphore.
  227.               *
  228.               * Arguments  : pevent        is a pointer to the event control block associated with the desired
  229.               *                            semaphore.
  230.               *
  231.               *              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
  232.               *                            wait for the resource up to the amount of time specified by this argument.
  233.               *                            If you specify 0, however, your task will wait forever at the specified
  234.               *                            semaphore or, until the resource becomes available (or the event occurs).
  235.               *
  236.               *              err           is a pointer to where an error message will be deposited.  Possible error
  237.               *                            messages are:
  238.               *
  239.               *                            OS_NO_ERR           The call was successful and your task owns the resource
  240.               *                                                or, the event you are waiting for occurred.
  241.               *                            OS_TIMEOUT          The semaphore was not received within the specified
  242.               *                                                timeout.
  243.               *                            OS_ERR_EVENT_TYPE   If you didn't pass a pointer to a semaphore.
  244.               *                            OS_ERR_PEND_ISR     If you called this function from an ISR and the result
  245.               *                                                would lead to a suspension.
  246.               *                            OS_ERR_PEVENT_NULL  If 'pevent' is a NULL pointer.
  247.               *
  248.               * Returns    : none
  249.               *********************************************************************************************************
  250. C51 COMPILER V8.02   OS_SEM                                                                06/22/2006 11:44:39 PAGE 5   
  251.               */
  252.               
  253.               void  OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) reentrant
  254.               {
  255.               #if OS_CRITICAL_METHOD == 3                           /* Allocate storage for CPU status register      */
  256.                   OS_CPU_SR  cpu_sr;
  257.               #endif    
  258.               
  259.               
  260.                   if (OSIntNesting > 0) {                           /* See if called from ISR ...                    */
  261.                       *err = OS_ERR_PEND_ISR;                       /* ... can't PEND from an ISR                    */
  262.                       return;
  263.                   }
  264.               #if OS_ARG_CHK_EN > 0
  265.                   if (pevent == (OS_EVENT *)0) {                    /* Validate 'pevent'                             */
  266.                       *err = OS_ERR_PEVENT_NULL;
  267.                       return;
  268.                   }
  269.                   if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {   /* Validate event block type                     */
  270.                       *err = OS_ERR_EVENT_TYPE;
  271.                       return;
  272.                   }
  273.               #endif
  274.                   OS_ENTER_CRITICAL();
  275.                   if (pevent->OSEventCnt > 0) {                     /* If sem. is positive, resource available ...   */
  276.                       pevent->OSEventCnt--;                         /* ... decrement semaphore only if positive.     */
  277.                       OS_EXIT_CRITICAL();
  278.                       *err = OS_NO_ERR;
  279.                       return;
  280.                   }
  281.                                                                     /* Otherwise, must wait until event occurs       */
  282.                   OSTCBCur->OSTCBStat |= OS_STAT_SEM;               /* Resource not available, pend on semaphore     */
  283.                   OSTCBCur->OSTCBDly   = timeout;                   /* Store pend timeout in TCB                     */
  284.                   OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */
  285.                   OS_EXIT_CRITICAL();
  286.                   OS_Sched();                                       /* Find next highest priority task ready         */
  287.                   OS_ENTER_CRITICAL();
  288.                   if (OSTCBCur->OSTCBStat & OS_STAT_SEM) {          /* Must have timed out if still waiting for event*/
  289.                       OS_EventTO(pevent);
  290.                       OS_EXIT_CRITICAL();
  291.                       *err = OS_TIMEOUT;                            /* Indicate that didn't get event within TO      */
  292.                       return;
  293.                   }
  294.                   OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
  295.                   OS_EXIT_CRITICAL();
  296.                   *err = OS_NO_ERR;
  297.               }
  298.               /*$PAGE*/
  299.               /*
  300.               *********************************************************************************************************
  301.               *                                         POST TO A SEMAPHORE
  302.               *
  303.               * Description: This function signals a semaphore
  304.               *
  305.               * Arguments  : pevent        is a pointer to the event control block associated with the desired
  306.               *                            semaphore.
  307.               *
  308.               * Returns    : OS_NO_ERR           The call was successful and the semaphore was signaled.
  309.               *              OS_SEM_OVF          If the semaphore count exceeded its limit.  In other words, you have
  310.               *                                  signalled the semaphore more often than you waited on it with either
  311.               *                                  OSSemAccept() or OSSemPend().
  312.               *              OS_ERR_EVENT_TYPE   If you didn't pass a pointer to a semaphore
  313. C51 COMPILER V8.02   OS_SEM                                                                06/22/2006 11:44:39 PAGE 6   
  314.               *              OS_ERR_PEVENT_NULL  If 'pevent' is a NULL pointer.
  315.               *********************************************************************************************************
  316.               */
  317.               
  318.               INT8U  OSSemPost (OS_EVENT *pevent) reentrant
  319.               {
  320.               #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  321.                   OS_CPU_SR  cpu_sr;                               
  322.               #endif    
  323.               
  324.               
  325.               #if OS_ARG_CHK_EN > 0
  326.                   if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
  327.                       return (OS_ERR_PEVENT_NULL);
  328.                   }
  329.                   if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {        /* Validate event block type                */
  330.                       return (OS_ERR_EVENT_TYPE);
  331.                   }
  332.               #endif
  333.                   OS_ENTER_CRITICAL();
  334.                   if (pevent->OSEventGrp != 0x00) {                      /* See if any task waiting for semaphore    */
  335.                       OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);   /* Ready highest prio task waiting on event */
  336.                       OS_EXIT_CRITICAL();
  337.                       OS_Sched();                                   /* Find highest priority task ready to run       */
  338.                       return (OS_NO_ERR);
  339.                   }
  340.                   if (pevent->OSEventCnt < 65535) {                 /* Make sure semaphore will not overflow         */
  341.                       pevent->OSEventCnt++;                         /* Increment semaphore count to register event   */
  342.                       OS_EXIT_CRITICAL();
  343.                       return (OS_NO_ERR);
  344.                   }
  345.                   OS_EXIT_CRITICAL();                               /* Semaphore value has reached its maximum       */
  346.                   return (OS_SEM_OVF);
  347.               }
  348.               /*
  349.               *********************************************************************************************************
  350.               *                                          QUERY A SEMAPHORE
  351.               *
  352.               * Description: This function obtains information about a semaphore
  353.               *
  354.               * Arguments  : pevent        is a pointer to the event control block associated with the desired
  355.               *                            semaphore
  356.               *
  357.               *              ppdata         is a pointer to a structure that will contain information about the
  358.               *                            semaphore.
  359.               *
  360.               * Returns    : OS_NO_ERR           The call was successful and the message was sent
  361.               *              OS_ERR_EVENT_TYPE   If you are attempting to obtain data from a non semaphore.
  362.               *              OS_ERR_PEVENT_NULL  If 'pevent' is a NULL pointer.
  363.               *********************************************************************************************************
  364.               */
  365.               
  366.               #if OS_SEM_QUERY_EN > 0
  367.               INT8U  OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *ppdata) reentrant
  368.               {
  369.               #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  370.                   OS_CPU_SR  cpu_sr;
  371.               #endif    
  372.                   INT8U     *psrc;
  373.                   INT8U     *pdest;
  374.               
  375.               
  376. C51 COMPILER V8.02   OS_SEM                                                                06/22/2006 11:44:39 PAGE 7   
  377.               #if OS_ARG_CHK_EN > 0
  378.                   if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
  379.                       return (OS_ERR_PEVENT_NULL);
  380.                   }
  381.                   if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {        /* Validate event block type                */
  382.                       return (OS_ERR_EVENT_TYPE);
  383.                   }
  384.               #endif
  385.                   OS_ENTER_CRITICAL();
  386.                   ppdata->OSEventGrp = pevent->OSEventGrp;                /* Copy message mailbox wait list           */
  387.                   psrc              = &pevent->OSEventTbl[0];
  388.                   pdest             = &ppdata->OSEventTbl[0];
  389.               #if OS_EVENT_TBL_SIZE > 0
  390.                   *pdest++          = *psrc++;
  391.               #endif
  392.               
  393.               #if OS_EVENT_TBL_SIZE > 1
  394.                   *pdest++          = *psrc++;
  395.               #endif
  396.               
  397.               #if OS_EVENT_TBL_SIZE > 2
  398.                   *pdest++          = *psrc++;
  399.               #endif
  400.               
  401.               #if OS_EVENT_TBL_SIZE > 3
  402.                   *pdest++          = *psrc++;
  403.               #endif
  404.               
  405.               #if OS_EVENT_TBL_SIZE > 4
  406.                   *pdest++          = *psrc++;
  407.               #endif
  408.               
  409.               #if OS_EVENT_TBL_SIZE > 5
  410.                   *pdest++          = *psrc++;
  411.               #endif
  412.               
  413.               #if OS_EVENT_TBL_SIZE > 6
  414.                   *pdest++          = *psrc++;
  415.               #endif
  416.               
  417.               #if OS_EVENT_TBL_SIZE > 7
  418.                   *pdest            = *psrc;
  419.               #endif
  420.                   ppdata->OSCnt      = pevent->OSEventCnt;                /* Get semaphore count                      */
  421.                   OS_EXIT_CRITICAL();
  422.                   return (OS_NO_ERR);
  423.               }
  424.               #endif                                                     /* OS_SEM_QUERY_EN                          */
  425.               #endif                                                     /* OS_SEM_EN                                */
  426. MODULE INFORMATION:   STATIC OVERLAYABLE
  427.    CODE SIZE        =   ----    ----
  428.    CONSTANT SIZE    =   ----    ----
  429.    XDATA SIZE       =   ----    ----
  430.    PDATA SIZE       =   ----    ----
  431.    DATA SIZE        =   ----    ----
  432.    IDATA SIZE       =   ----    ----
  433.    BIT SIZE         =   ----    ----
  434. END OF MODULE INFORMATION.
  435. C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)