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

Visual C++

  1. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 1   
  2. C51 COMPILER V8.02, COMPILATION OF MODULE OS_MUTEX
  3. OBJECT MODULE PLACED IN .objOS_MUTEX.obj
  4. COMPILER INVOKED BY: C:KeilC51BINC51.EXE uCosiiOS_MUTEX.C LARGE BROWSE DEBUG OBJECTEXTEND PRINT(.lstOS_MUTEX.lst)
  5.                     - OBJECT(.objOS_MUTEX.obj)
  6. line level    source
  7.    1          /*
  8.    2          *********************************************************************************************************
  9.    3          *                                                uC/OS-II
  10.    4          *                                          The Real-Time Kernel
  11.    5          *                                  MUTUAL EXCLUSION 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_MUTEX.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          *                                            LOCAL CONSTANTS
  28.   22          *********************************************************************************************************
  29.   23          */
  30.   24          
  31.   25          #define  OS_MUTEX_KEEP_LOWER_8   0x00FF
  32.   26          #define  OS_MUTEX_KEEP_UPPER_8   0xFF00
  33.   27          
  34.   28          #define  OS_MUTEX_AVAILABLE      0x00FF
  35.   29          
  36.   30          
  37.   31          #if OS_MUTEX_EN > 0
  38.               /*
  39.               *********************************************************************************************************
  40.               *                                   ACCEPT MUTUAL EXCLUSION SEMAPHORE
  41.               *
  42.               * Description: This  function checks the mutual exclusion semaphore to see if a resource is available.
  43.               *              Unlike OSMutexPend(), OSMutexAccept() does not suspend the calling task if the resource is
  44.               *              not available or the event did not occur.
  45.               *
  46.               * Arguments  : pevent     is a pointer to the event control block
  47.               *
  48.               *              err        is a pointer to an error code which will be returned to your application:
  49.               *                            OS_NO_ERR          if the call was successful.
  50.               *                            OS_ERR_EVENT_TYPE  if 'pevent' is not a pointer to a mutex
  51.               *                            OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
  52.               *                            OS_ERR_PEND_ISR     if you called this function from an ISR
  53.               *
  54.               * Returns    : == 1       if the resource is available, the mutual exclusion semaphore is acquired
  55.               *              == 0       a) if the resource is not available
  56.               *                         b) you didn't pass a pointer to a mutual exclusion semaphore
  57.               *                         c) you called this function from an ISR
  58.               *
  59.               * Warning(s) : This function CANNOT be called from an ISR because mutual exclusion semaphores are
  60.               *              intended to be used by tasks only.
  61. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 2   
  62.               *********************************************************************************************************
  63.               */
  64.               
  65.               #if OS_MUTEX_ACCEPT_EN > 0
  66.               INT8U  OSMutexAccept (OS_EVENT *pevent, INT8U *err) reentrant
  67.               {
  68.               #if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
  69.                   OS_CPU_SR  cpu_sr;
  70.               #endif    
  71.                   
  72.                   
  73.                   if (OSIntNesting > 0) {                            /* Make sure it's not called from an ISR        */
  74.                       *err = OS_ERR_PEND_ISR;
  75.                       return (0);
  76.                   }
  77.               #if OS_ARG_CHK_EN > 0
  78.                   if (pevent == (OS_EVENT *)0) {                     /* Validate 'pevent'                            */
  79.                       *err = OS_ERR_PEVENT_NULL;
  80.                       return (0);
  81.                   }
  82.                   if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {  /* Validate event block type                    */
  83.                       *err = OS_ERR_EVENT_TYPE;
  84.                       return (0);
  85.                   }
  86.               #endif                                                     
  87.                   OS_ENTER_CRITICAL();                                                           /* Get value (0 or 1) of Mutex                  */
  88.                   if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {     
  89.                       pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;   /*      Mask off LSByte (Acquire Mutex)         */
  90.                       pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;     /*      Save current task priority in LSByte    */
  91.                       pevent->OSEventPtr  = (void *)OSTCBCur;        /*      Link TCB of task owning Mutex           */
  92.                       OS_EXIT_CRITICAL();
  93.                       *err = OS_NO_ERR;
  94.                       return (1);
  95.                   }
  96.                   OS_EXIT_CRITICAL();
  97.                   *err = OS_NO_ERR;
  98.                   return (0);
  99.               }
  100.               #endif                                                     
  101.               
  102.               /*$PAGE*/
  103.               /*
  104.               *********************************************************************************************************
  105.               *                                  CREATE A MUTUAL EXCLUSION SEMAPHORE
  106.               *
  107.               * Description: This function creates a mutual exclusion semaphore.
  108.               *
  109.               * Arguments  : prio          is the priority to use when accessing the mutual exclusion semaphore.  In
  110.               *                            other words, when the semaphore is acquired and a higher priority task
  111.               *                            attempts to obtain the semaphore then the priority of the task owning the
  112.               *                            semaphore is raised to this priority.  It is assumed that you will specify
  113.               *                            a priority that is LOWER in value than ANY of the tasks competing for the
  114.               *                            mutex.
  115.               *
  116.               *              err           is a pointer to an error code which will be returned to your application:
  117.               *                               OS_NO_ERR           if the call was successful.
  118.               *                               OS_ERR_CREATE_ISR   if you attempted to create a MUTEX from an ISR
  119.               *                               OS_PRIO_EXIST       if a task at the priority inheritance priority
  120.               *                                                   already exist.
  121.               *                               OS_ERR_PEVENT_NULL  No more event control blocks available.
  122.               *                               OS_PRIO_INVALID     if the priority you specify is higher that the 
  123.               *                                                   maximum allowed (i.e. > OS_LOWEST_PRIO)
  124. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 3   
  125.               *
  126.               * Returns    : != (void *)0  is a pointer to the event control clock (OS_EVENT) associated with the
  127.               *                            created mutex.
  128.               *              == (void *)0  if an error is detected.
  129.               *
  130.               * Note(s)    : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number
  131.               *                 of the task owning the mutex or 0xFF if no task owns the mutex.
  132.               *              2) The MOST  significant 8 bits of '.OSEventCnt' are used to hold the priority number
  133.               *                 to use to reduce priority inversion.
  134.               *********************************************************************************************************
  135.               */
  136.               
  137.               OS_EVENT  *OSMutexCreate (INT8U prio, INT8U *err) reentrant
  138.               {
  139.               #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  140.                   OS_CPU_SR  cpu_sr;
  141.               #endif    
  142.                   OS_EVENT  *pevent;
  143.               
  144.               
  145.                   if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
  146.                       *err = OS_ERR_CREATE_ISR;                          /* ... can't CREATE mutex from an ISR       */
  147.                       return ((OS_EVENT *)0);
  148.                   }
  149.               #if OS_ARG_CHK_EN > 0
  150.                   if (prio >= OS_LOWEST_PRIO) {                          /* Validate PIP                             */
  151.                       *err = OS_PRIO_INVALID;
  152.                       return ((OS_EVENT *)0);
  153.                   }
  154.               #endif
  155.                   OS_ENTER_CRITICAL();
  156.                   if (OSTCBPrioTbl[prio] != (OS_TCB *)0) {               /* Mutex priority must not already exist    */
  157.                       OS_EXIT_CRITICAL();                                /* Task already exist at priority ...       */
  158.                       *err = OS_PRIO_EXIST;                              /* ... inheritance priority                 */
  159.                       return ((OS_EVENT *)0);                            
  160.                   }
  161.                   OSTCBPrioTbl[prio] = (OS_TCB *)1;                      /* Reserve the table entry                  */
  162.                   pevent             = OSEventFreeList;                  /* Get next free event control block        */
  163.                   if (pevent == (OS_EVENT *)0) {                         /* See if an ECB was available              */
  164.                       OSTCBPrioTbl[prio] = (OS_TCB *)0;                  /* No, Release the table entry              */
  165.                       OS_EXIT_CRITICAL();
  166.                       *err               = OS_ERR_PEVENT_NULL;           /* No more event control blocks             */
  167.                       return (pevent);
  168.                   }
  169.                   OSEventFreeList     = (OS_EVENT *)OSEventFreeList->OSEventPtr;   /* Adjust the free list           */
  170.                   OS_EXIT_CRITICAL();
  171.                   pevent->OSEventType = OS_EVENT_TYPE_MUTEX;
  172.                   pevent->OSEventCnt  = (prio << 8) | OS_MUTEX_AVAILABLE;/* Resource is available                    */
  173.                   pevent->OSEventPtr  = (void *)0;                       /* No task owning the mutex                 */
  174.                   OS_EventWaitListInit(pevent);
  175.                   *err                = OS_NO_ERR;
  176.                   return (pevent);
  177.               }
  178.               
  179.               /*$PAGE*/
  180.               /*
  181.               *********************************************************************************************************
  182.               *                                          DELETE A MUTEX
  183.               *
  184.               * Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it.
  185.               *
  186.               * Arguments  : pevent        is a pointer to the event control block associated with the desired mutex.
  187. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 4   
  188.               *
  189.               *              opt           determines delete options as follows:
  190.               *                            opt == OS_DEL_NO_PEND   Delete mutex ONLY if no task pending
  191.               *                            opt == OS_DEL_ALWAYS    Deletes the mutex even if tasks are waiting.
  192.               *                                                    In this case, all the tasks pending will be readied.
  193.               *
  194.               *              err           is a pointer to an error code that can contain one of the following values:
  195.               *                            OS_NO_ERR               The call was successful and the mutex was deleted
  196.               *                            OS_ERR_DEL_ISR          If you attempted to delete the MUTEX from an ISR
  197.               *                            OS_ERR_INVALID_OPT      An invalid option was specified
  198.               *                            OS_ERR_TASK_WAITING     One or more tasks were waiting on the mutex
  199.               *                            OS_ERR_EVENT_TYPE       If you didn't pass a pointer to a mutex
  200.               *                            OS_ERR_PEVENT_NULL      If 'pevent' is a NULL pointer.
  201.               *
  202.               * Returns    : pevent        upon error
  203.               *              (OS_EVENT *)0 if the mutex was successfully deleted.
  204.               *
  205.               * Note(s)    : 1) This function must be used with care.  Tasks that would normally expect the presence of
  206.               *                 the mutex MUST check the return code of OSMutexPend().
  207.               *              2) This call can potentially disable interrupts for a long time.  The interrupt disable
  208.               *                 time is directly proportional to the number of tasks waiting on the mutex.
  209.               *              3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the
  210.               *                 resource(s) will no longer be guarded by the mutex.
  211.               *********************************************************************************************************
  212.               */
  213.               
  214.               #if OS_MUTEX_DEL_EN
  215.               OS_EVENT  *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err) reentrant
  216.               {
  217.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  218.                   OS_CPU_SR  cpu_sr;
  219.               #endif    
  220.                   BOOLEAN    tasks_waiting;
  221.                   INT8U      pip;
  222.               
  223.               
  224.                   if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
  225.                       *err = OS_ERR_DEL_ISR;                             /* ... can't DELETE from an ISR             */
  226.                       return (pevent);
  227.                   }
  228.               #if OS_ARG_CHK_EN > 0
  229.                   if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
  230.                       *err = OS_ERR_PEVENT_NULL;
  231.                       return ((OS_EVENT *)0);
  232.                   }
  233.                   if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
  234.                       *err = OS_ERR_EVENT_TYPE;
  235.                       return (pevent);
  236.                   }
  237.               #endif
  238.                   OS_ENTER_CRITICAL();
  239.                   if (pevent->OSEventGrp != 0x00) {                      /* See if any tasks waiting on mutex        */
  240.                       tasks_waiting = TRUE;                              /* Yes                                      */
  241.                   } else {
  242.                       tasks_waiting = FALSE;                             /* No                                       */
  243.                   }
  244.                   switch (opt) {
  245.                       case OS_DEL_NO_PEND:                               /* Delete mutex only if no task waiting     */
  246.                            if (tasks_waiting == FALSE) {
  247.                                pip                 = (INT8U)(pevent->OSEventCnt >> 8);
  248.                                OSTCBPrioTbl[pip]   = (OS_TCB *)0;        /* Free up the PIP                          */
  249.                                pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
  250. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 5   
  251.                                pevent->OSEventPtr  = OSEventFreeList;    /* Return Event Control Block to free list  */
  252.                                OSEventFreeList     = pevent;
  253.                                OS_EXIT_CRITICAL();
  254.                                *err = OS_NO_ERR;
  255.                                return ((OS_EVENT *)0);                   /* Mutex has been deleted                   */
  256.                            } else {
  257.                                OS_EXIT_CRITICAL();
  258.                                *err = OS_ERR_TASK_WAITING;
  259.                                return (pevent);
  260.                            }
  261.               
  262.                       case OS_DEL_ALWAYS:                                /* Always delete the mutex                  */
  263.                            while (pevent->OSEventGrp != 0x00) {          /* Ready ALL tasks waiting for mutex        */
  264.                                OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);
  265.                            }
  266.                            pip                 = (INT8U)(pevent->OSEventCnt >> 8);
  267.                            OSTCBPrioTbl[pip]   = (OS_TCB *)0;            /* Free up the PIP                          */
  268.                            pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
  269.                            pevent->OSEventPtr  = OSEventFreeList;        /* Return Event Control Block to free list  */
  270.                            OSEventFreeList     = pevent;                 /* Get next free event control block        */
  271.                            OS_EXIT_CRITICAL();
  272.                            if (tasks_waiting == TRUE) {                  /* Reschedule only if task(s) were waiting  */
  273.                                OS_Sched();                               /* Find highest priority task ready to run  */
  274.                            }
  275.                            *err = OS_NO_ERR;
  276.                            return ((OS_EVENT *)0);                       /* Mutex has been deleted                   */
  277.               
  278.                       default:
  279.                            OS_EXIT_CRITICAL();
  280.                            *err = OS_ERR_INVALID_OPT;
  281.                            return (pevent);
  282.                   }
  283.               }
  284.               #endif
  285.               
  286.               /*$PAGE*/
  287.               /*
  288.               *********************************************************************************************************
  289.               *                                  PEND ON MUTUAL EXCLUSION SEMAPHORE
  290.               *
  291.               * Description: This function waits for a mutual exclusion semaphore.
  292.               *
  293.               * Arguments  : pevent        is a pointer to the event control block associated with the desired
  294.               *                            mutex.
  295.               *
  296.               *              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
  297.               *                            wait for the resource up to the amount of time specified by this argument.
  298.               *                            If you specify 0, however, your task will wait forever at the specified
  299.               *                            mutex or, until the resource becomes available.
  300.               *
  301.               *              err           is a pointer to where an error message will be deposited.  Possible error
  302.               *                            messages are:
  303.               *                               OS_NO_ERR          The call was successful and your task owns the mutex
  304.               *                               OS_TIMEOUT         The mutex was not available within the specified time.
  305.               *                               OS_ERR_EVENT_TYPE  If you didn't pass a pointer to a mutex
  306.               *                               OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
  307.               *                               OS_ERR_PEND_ISR    If you called this function from an ISR and the result
  308.               *                                                  would lead to a suspension.
  309.               *
  310.               * Returns    : none
  311.               *
  312.               * Note(s)    : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
  313. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 6   
  314.               *              2) You MUST NOT change the priority of the task that owns the mutex
  315.               *********************************************************************************************************
  316.               */
  317.               void  OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) reentrant
  318.               {
  319.               #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  320.                   OS_CPU_SR  cpu_sr;
  321.               #endif    
  322.                   INT8U      pip;                                        /* Priority Inheritance Priority (PIP)      */
  323.                   INT8U      mprio;                                      /* Mutex owner priority                     */
  324.                   BOOLEAN    rdy;                                        /* Flag indicating task was ready           */
  325.                   OS_TCB    *ptcb;
  326.               
  327.               
  328.                   if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
  329.                       *err = OS_ERR_PEND_ISR;                            /* ... can't PEND from an ISR               */
  330.                       return;
  331.                   }
  332.               #if OS_ARG_CHK_EN > 0
  333.                   if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
  334.                       *err = OS_ERR_PEVENT_NULL;
  335.                       return;
  336.                   }
  337.                   if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
  338.                       *err = OS_ERR_EVENT_TYPE;
  339.                       return;
  340.                   }
  341.               #endif
  342.                   OS_ENTER_CRITICAL();                                                                   /* Is Mutex available?                      */
  343.                   if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
  344.                       pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;       /* Yes, Acquire the resource                */
  345.                       pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;         /*      Save priority of owning task        */
  346.                       pevent->OSEventPtr  = (void *)OSTCBCur;            /*      Point to owning task's OS_TCB       */
  347.                       OS_EXIT_CRITICAL();
  348.                       *err  = OS_NO_ERR;
  349.                       return;
  350.                   }
  351.                   pip   = (INT8U)(pevent->OSEventCnt >> 8);                     /* No, Get PIP from mutex            */
  352.                   mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);  /*     Get priority of mutex owner   */
  353.                   ptcb  = (OS_TCB *)(pevent->OSEventPtr);                       /*     Point to TCB of mutex owner   */
  354.                   if (ptcb->OSTCBPrio != pip && mprio > OSTCBCur->OSTCBPrio) {  /*     Need to promote prio of owner?*/
  355.                       if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { /*     See if mutex owner is ready   */
  356.                                                                                 /*     Yes, Remove owner from Rdy ...*/
  357.                                                                                 /*          ... list at current prio */
  358.                           if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
  359.                               OSRdyGrp &= ~ptcb->OSTCBBitY;
  360.                           }
  361.                           rdy = TRUE;
  362.                       } else {
  363.                           rdy = FALSE;                                          /* No                                */
  364.                       }
  365.                       ptcb->OSTCBPrio         = pip;                     /* Change owner task prio to PIP            */
  366.                       ptcb->OSTCBY            = ptcb->OSTCBPrio >> 3;
  367.                       ptcb->OSTCBBitY         = OSMapTbl[ptcb->OSTCBY];
  368.                       ptcb->OSTCBX            = ptcb->OSTCBPrio & 0x07;
  369.                       ptcb->OSTCBBitX         = OSMapTbl[ptcb->OSTCBX];
  370.                       if (rdy == TRUE) {                                 /* If task was ready at owner's priority ...*/
  371.                           OSRdyGrp               |= ptcb->OSTCBBitY;     /* ... make it ready at new priority.       */
  372.                           OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
  373.                       }
  374.                       OSTCBPrioTbl[pip]       = (OS_TCB *)ptcb;
  375.                   }
  376. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 7   
  377.                   OSTCBCur->OSTCBStat |= OS_STAT_MUTEX;             /* Mutex not available, pend current task        */
  378.                   OSTCBCur->OSTCBDly   = timeout;                   /* Store timeout in current task's TCB           */
  379.                   OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */
  380.                   OS_EXIT_CRITICAL();
  381.                   OS_Sched();                                       /* Find next highest priority task ready         */
  382.                   OS_ENTER_CRITICAL();
  383.                   if (OSTCBCur->OSTCBStat & OS_STAT_MUTEX) {        /* Must have timed out if still waiting for event*/
  384.                       OS_EventTO(pevent);
  385.                       OS_EXIT_CRITICAL();
  386.                       *err = OS_TIMEOUT;                            /* Indicate that we didn't get mutex within TO   */
  387.                       return;
  388.                   }
  389.                   OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
  390.                   OS_EXIT_CRITICAL();
  391.                   *err = OS_NO_ERR;
  392.               }
  393.               /*$PAGE*/
  394.               /*
  395.               *********************************************************************************************************
  396.               *                                  POST TO A MUTUAL EXCLUSION SEMAPHORE
  397.               *
  398.               * Description: This function signals a mutual exclusion semaphore
  399.               *
  400.               * Arguments  : pevent              is a pointer to the event control block associated with the desired
  401.               *                                  mutex.
  402.               *
  403.               * Returns    : OS_NO_ERR               The call was successful and the mutex was signaled.
  404.               *              OS_ERR_EVENT_TYPE       If you didn't pass a pointer to a mutex
  405.               *              OS_ERR_PEVENT_NULL      'pevent' is a NULL pointer
  406.               *              OS_ERR_POST_ISR         Attempted to post from an ISR (not valid for MUTEXes)
  407.               *              OS_ERR_NOT_MUTEX_OWNER  The task that did the post is NOT the owner of the MUTEX.
  408.               *********************************************************************************************************
  409.               */
  410.               
  411.               INT8U  OSMutexPost (OS_EVENT *pevent) reentrant
  412.               {
  413.               #if OS_CRITICAL_METHOD == 3                           /* Allocate storage for CPU status register      */
  414.                   OS_CPU_SR  cpu_sr;
  415.               #endif    
  416.                   INT8U      pip;                                   /* Priority inheritance priority                 */
  417.                   INT8U      prio;
  418.               
  419.               
  420.                   if (OSIntNesting > 0) {                           /* See if called from ISR ...                    */
  421.                       return (OS_ERR_POST_ISR);                     /* ... can't POST mutex from an ISR              */
  422.                   }
  423.               #if OS_ARG_CHK_EN > 0
  424.                   if (pevent == (OS_EVENT *)0) {                    /* Validate 'pevent'                             */
  425.                       return (OS_ERR_PEVENT_NULL);
  426.                   }
  427.                   if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type                     */
  428.                       return (OS_ERR_EVENT_TYPE);
  429.                   }                                                 
  430.               #endif
  431.                   OS_ENTER_CRITICAL();
  432.                   pip  = (INT8U)(pevent->OSEventCnt >> 8);          /* Get priority inheritance priority of mutex    */
  433.                   prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);  /* Get owner's original priority      */
  434.                   if (OSTCBCur->OSTCBPrio != pip && 
  435.                       OSTCBCur->OSTCBPrio != prio) {                /* See if posting task owns the MUTEX            */
  436.                       OS_EXIT_CRITICAL();
  437.                       return (OS_ERR_NOT_MUTEX_OWNER);
  438.                   }
  439. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 8   
  440.                   if (OSTCBCur->OSTCBPrio == pip) {                 /* Did we have to raise current task's priority? */
  441.                                                                     /* Yes, Return to original priority              */
  442.                                                                     /*      Remove owner from ready list at 'pip'    */
  443.                       if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {
  444.                           OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
  445.                       }
  446.                       OSTCBCur->OSTCBPrio         = prio;
  447.                       OSTCBCur->OSTCBY            = prio >> 3;
  448.                       OSTCBCur->OSTCBBitY         = OSMapTbl[OSTCBCur->OSTCBY];
  449.                       OSTCBCur->OSTCBX            = prio & 0x07;
  450.                       OSTCBCur->OSTCBBitX         = OSMapTbl[OSTCBCur->OSTCBX];
  451.                       OSRdyGrp                   |= OSTCBCur->OSTCBBitY;
  452.                       OSRdyTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
  453.                       OSTCBPrioTbl[prio]          = (OS_TCB *)OSTCBCur;
  454.                   }
  455.                   OSTCBPrioTbl[pip] = (OS_TCB *)1;                  /* Reserve table entry                           */
  456.                   if (pevent->OSEventGrp != 0x00) {                 /* Any task waiting for the mutex?               */
  457.                                                                     /* Yes, Make HPT waiting for mutex ready         */
  458.                       prio                = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);
  459.                       pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;  /*      Save priority of mutex's new owner       */
  460.                       pevent->OSEventCnt |= prio;
  461.                       pevent->OSEventPtr  = OSTCBPrioTbl[prio];     /*      Link to mutex owner's OS_TCB             */
  462.                       OS_EXIT_CRITICAL();
  463.                       OS_Sched();                                   /*      Find highest priority task ready to run  */
  464.                       return (OS_NO_ERR);
  465.                   }
  466.                   pevent->OSEventCnt |= OS_MUTEX_AVAILABLE;         /* No,  Mutex is now available                   */
  467.                   pevent->OSEventPtr  = (void *)0;
  468.                   OS_EXIT_CRITICAL();
  469.                   return (OS_NO_ERR);
  470.               }
  471.               /*$PAGE*/
  472.               /*
  473.               *********************************************************************************************************
  474.               *                                     QUERY A MUTUAL EXCLUSION SEMAPHORE
  475.               *
  476.               * Description: This function obtains information about a mutex
  477.               *
  478.               * Arguments  : pevent        is a pointer to the event control block associated with the desired mutex
  479.               *
  480.               *              ppdata         is a pointer to a structure that will contain information about the mutex
  481.               *
  482.               * Returns    : OS_NO_ERR            The call was successful and the message was sent
  483.               *              OS_ERR_QUERY_ISR     If you called this function from an ISR
  484.               *              OS_ERR_PEVENT_NULL   'pevent' is a NULL pointer
  485.               *              OS_ERR_EVENT_TYPE    If you are attempting to obtain data from a non mutex.
  486.               *********************************************************************************************************
  487.               */
  488.               
  489.               #if OS_MUTEX_QUERY_EN > 0
  490.               INT8U  OSMutexQuery (OS_EVENT *pevent, OS_MUTEX_DATA *ppdata) reentrant
  491.               {
  492.               #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
  493.                   OS_CPU_SR  cpu_sr;
  494.               #endif    
  495.                   INT8U     *psrc;
  496.                   INT8U     *pdest;
  497.               
  498.               
  499.                   if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
  500.                       return (OS_ERR_QUERY_ISR);                         /* ... can't QUERY mutex from an ISR        */
  501.                   }
  502. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 9   
  503.               #if OS_ARG_CHK_EN > 0
  504.                   if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
  505.                       return (OS_ERR_PEVENT_NULL);
  506.                   }
  507.                   if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
  508.                       return (OS_ERR_EVENT_TYPE);
  509.                   }
  510.               #endif
  511.                   OS_ENTER_CRITICAL();
  512.                   ppdata->OSMutexPIP  = (INT8U)(pevent->OSEventCnt >> 8);
  513.                   ppdata->OSOwnerPrio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);
  514.                   if (ppdata->OSOwnerPrio == 0xFF) {
  515.                       ppdata->OSValue = 1;
  516.                   } else {
  517.                       ppdata->OSValue = 0;
  518.                   }
  519.                   ppdata->OSEventGrp  = pevent->OSEventGrp;               /* Copy wait list                           */
  520.                   psrc               = &pevent->OSEventTbl[0];
  521.                   pdest              = &ppdata->OSEventTbl[0];
  522.               #if OS_EVENT_TBL_SIZE > 0
  523.                   *pdest++           = *psrc++;
  524.               #endif
  525.               
  526.               #if OS_EVENT_TBL_SIZE > 1
  527.                   *pdest++           = *psrc++;
  528.               #endif
  529.               
  530.               #if OS_EVENT_TBL_SIZE > 2
  531.                   *pdest++           = *psrc++;
  532.               #endif
  533.               
  534.               #if OS_EVENT_TBL_SIZE > 3
  535.                   *pdest++           = *psrc++;
  536.               #endif
  537.               
  538.               #if OS_EVENT_TBL_SIZE > 4
  539.                   *pdest++           = *psrc++;
  540.               #endif
  541.               
  542.               #if OS_EVENT_TBL_SIZE > 5
  543.                   *pdest++           = *psrc++;
  544.               #endif
  545.               
  546.               #if OS_EVENT_TBL_SIZE > 6
  547.                   *pdest++           = *psrc++;
  548.               #endif
  549.               
  550.               #if OS_EVENT_TBL_SIZE > 7
  551.                   *pdest             = *psrc;
  552.               #endif
  553.                   OS_EXIT_CRITICAL();
  554.                   return (OS_NO_ERR);
  555.               }
  556.               #endif                                                     /* OS_MUTEX_QUERY_EN                        */
  557.               #endif                                                     /* OS_MUTEX_EN                              */
  558. MODULE INFORMATION:   STATIC OVERLAYABLE
  559.    CODE SIZE        =   ----    ----
  560.    CONSTANT SIZE    =   ----    ----
  561.    XDATA SIZE       =   ----    ----
  562.    PDATA SIZE       =   ----    ----
  563. C51 COMPILER V8.02   OS_MUTEX                                                              06/22/2006 11:44:38 PAGE 10  
  564.    DATA SIZE        =   ----    ----
  565.    IDATA SIZE       =   ----    ----
  566.    BIT SIZE         =   ----    ----
  567. END OF MODULE INFORMATION.
  568. C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)