⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_mutex.lst

📁 编译环境是 iar EWARM ,STM32 下的UCOSII
💻 LST
📖 第 1 页 / 共 4 页
字号:
    337                       pevent->OSEventCnt  = 0;
    338                       OSEventFreeList     = pevent;                 /* Get next free event control block        */
    339                       OS_EXIT_CRITICAL();
    340                       if (tasks_waiting == OS_TRUE) {               /* Reschedule only if task(s) were waiting  */
    341                           OS_Sched();                               /* Find highest priority task ready to run  */
    342                       }
    343                       *perr         = OS_ERR_NONE;
    344                       pevent_return = (OS_EVENT *)0;                /* Mutex has been deleted                   */
    345                       break;
    346          
    347                  default:
    348                       OS_EXIT_CRITICAL();
    349                       *perr         = OS_ERR_INVALID_OPT;
    350                       pevent_return = pevent;
    351                       break;
    352              }
    353              return (pevent_return);
    354          }
    355          #endif
    356          
    357          /*$PAGE*/
    358          /*
    359          *********************************************************************************************************
    360          *                                  PEND ON MUTUAL EXCLUSION SEMAPHORE
    361          *
    362          * Description: This function waits for a mutual exclusion semaphore.
    363          *
    364          * Arguments  : pevent        is a pointer to the event control block associated with the desired
    365          *                            mutex.
    366          *
    367          *              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
    368          *                            wait for the resource up to the amount of time specified by this argument.
    369          *                            If you specify 0, however, your task will wait forever at the specified
    370          *                            mutex or, until the resource becomes available.
    371          *
    372          *              perr          is a pointer to where an error message will be deposited.  Possible error
    373          *                            messages are:
    374          *                               OS_ERR_NONE        The call was successful and your task owns the mutex
    375          *                               OS_ERR_TIMEOUT     The mutex was not available within the specified 'timeout'.
    376          *                               OS_ERR_PEND_ABORT  The wait on the mutex was aborted.
    377          *                               OS_ERR_EVENT_TYPE  If you didn't pass a pointer to a mutex
    378          *                               OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
    379          *                               OS_ERR_PEND_ISR    If you called this function from an ISR and the result
    380          *                                                  would lead to a suspension.
    381          *                               OS_ERR_PIP_LOWER   If the priority of the task that owns the Mutex is
    382          *                                                  HIGHER (i.e. a lower number) than the PIP.  This error
    383          *                                                  indicates that you did not set the PIP higher (lower
    384          *                                                  number) than ALL the tasks that compete for the Mutex.
    385          *                                                  Unfortunately, this is something that could not be
    386          *                                                  detected when the Mutex is created because we don't know
    387          *                                                  what tasks will be using the Mutex.
    388          *                               OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked
    389          *
    390          * Returns    : none
    391          *
    392          * Note(s)    : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
    393          *
    394          *              2) You MUST NOT change the priority of the task that owns the mutex
    395          *********************************************************************************************************
    396          */
    397          
    398          void  OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr)
    399          {
    400              INT8U      pip;                                        /* Priority Inheritance Priority (PIP)      */
    401              INT8U      mprio;                                      /* Mutex owner priority                     */
    402              BOOLEAN    rdy;                                        /* Flag indicating task was ready           */
    403              OS_TCB    *ptcb;
    404              OS_EVENT  *pevent2;
    405              INT8U      y;
    406          #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    407              OS_CPU_SR  cpu_sr = 0;
    408          #endif
    409          
    410          
    411          
    412          #if OS_ARG_CHK_EN > 0
    413              if (perr == (INT8U *)0) {                              /* Validate 'perr'                          */
    414                  return;
    415              }
    416              if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
    417                  *perr = OS_ERR_PEVENT_NULL;
    418                  return;
    419              }
    420          #endif
    421              if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
    422                  *perr = OS_ERR_EVENT_TYPE;
    423                  return;
    424              }
    425              if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
    426                  *perr = OS_ERR_PEND_ISR;                           /* ... can't PEND from an ISR               */
    427                  return;
    428              }
    429              if (OSLockNesting > 0) {                               /* See if called with scheduler locked ...  */
    430                  *perr = OS_ERR_PEND_LOCKED;                        /* ... can't PEND when locked               */
    431                  return;
    432              }
    433          /*$PAGE*/
    434              OS_ENTER_CRITICAL();
    435              pip = (INT8U)(pevent->OSEventCnt >> 8);                /* Get PIP from mutex                       */
    436                                                                     /* Is Mutex available?                      */
    437              if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
    438                  pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;       /* Yes, Acquire the resource                */
    439                  pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;         /*      Save priority of owning task        */
    440                  pevent->OSEventPtr  = (void *)OSTCBCur;            /*      Point to owning task's OS_TCB       */
    441                  if (OSTCBCur->OSTCBPrio <= pip) {                  /*      PIP 'must' have a SMALLER prio ...  */
    442                      OS_EXIT_CRITICAL();                            /*      ... than current task!              */
    443                      *perr = OS_ERR_PIP_LOWER;
    444                  } else {
    445                      OS_EXIT_CRITICAL();
    446                      *perr = OS_ERR_NONE;
    447                  }
    448                  return;
    449              }
    450              mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);  /* No, Get priority of mutex owner   */
    451              ptcb  = (OS_TCB *)(pevent->OSEventPtr);                       /*     Point to TCB of mutex owner   */
    452              if (ptcb->OSTCBPrio > pip) {                                  /*     Need to promote prio of owner?*/
    453                  if (mprio > OSTCBCur->OSTCBPrio) {
    454                      y = ptcb->OSTCBY;
    455                      if ((OSRdyTbl[y] & ptcb->OSTCBBitX) != 0) {           /*     See if mutex owner is ready   */
    456                          OSRdyTbl[y] &= ~ptcb->OSTCBBitX;                  /*     Yes, Remove owner from Rdy ...*/
    457                          if (OSRdyTbl[y] == 0) {                           /*          ... list at current prio */
    458                              OSRdyGrp &= ~ptcb->OSTCBBitY;
    459                          }
    460                          rdy = OS_TRUE;
    461                      } else {
    462                          pevent2 = ptcb->OSTCBEventPtr;
    463                          if (pevent2 != (OS_EVENT *)0) {                   /* Remove from event wait list       */
    464                              if ((pevent2->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {
    465                                  pevent2->OSEventGrp &= ~ptcb->OSTCBBitY;
    466                              }
    467                          }
    468                          rdy = OS_FALSE;                            /* No                                       */
    469                      }
    470                      ptcb->OSTCBPrio = pip;                         /* Change owner task prio to PIP            */
    471          #if OS_LOWEST_PRIO <= 63
    472                      ptcb->OSTCBY    = (INT8U)( ptcb->OSTCBPrio >> 3);
    473                      ptcb->OSTCBX    = (INT8U)( ptcb->OSTCBPrio & 0x07);
    474                      ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY);
    475                      ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX);
    476          #else
    477                      ptcb->OSTCBY    = (INT8U)((ptcb->OSTCBPrio >> 4) & 0xFF);
    478                      ptcb->OSTCBX    = (INT8U)( ptcb->OSTCBPrio & 0x0F);
    479                      ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY);
    480                      ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX);
    481          #endif
    482                      if (rdy == OS_TRUE) {                          /* If task was ready at owner's priority ...*/
    483                          OSRdyGrp               |= ptcb->OSTCBBitY; /* ... make it ready at new priority.       */
    484                          OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
    485                      } else {
    486                          pevent2 = ptcb->OSTCBEventPtr;
    487                          if (pevent2 != (OS_EVENT *)0) {            /* Add to event wait list                   */
    488                              pevent2->OSEventGrp               |= ptcb->OSTCBBitY;
    489                              pevent2->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
    490                          }
    491                      }
    492                      OSTCBPrioTbl[pip] = ptcb;
    493                  }
    494              }
    495              OSTCBCur->OSTCBStat     |= OS_STAT_MUTEX;         /* Mutex not available, pend current task        */
    496              OSTCBCur->OSTCBStatPend  = OS_STAT_PEND_OK;
    497              OSTCBCur->OSTCBDly       = timeout;               /* Store timeout in current task's TCB           */
    498              OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */
    499              OS_EXIT_CRITICAL();
    500              OS_Sched();                                       /* Find next highest priority task ready         */
    501              OS_ENTER_CRITICAL();
    502              switch (OSTCBCur->OSTCBStatPend) {                /* See if we timed-out or aborted                */
    503                  case OS_STAT_PEND_OK:
    504                       *perr = OS_ERR_NONE;
    505                       break;
    506          
    507                  case OS_STAT_PEND_ABORT:
    508                       *perr = OS_ERR_PEND_ABORT;               /* Indicate that we aborted getting mutex        */
    509                       break;
    510                       
    511                  case OS_STAT_PEND_TO:
    512                  default:
    513                       OS_EventTaskRemove(OSTCBCur, pevent);
    514                       *perr = OS_ERR_TIMEOUT;                  /* Indicate that we didn't get mutex within TO   */
    515                       break;
    516              }
    517              OSTCBCur->OSTCBStat          =  OS_STAT_RDY;      /* Set   task  status to ready                   */
    518              OSTCBCur->OSTCBStatPend      =  OS_STAT_PEND_OK;  /* Clear pend  status                            */
    519              OSTCBCur->OSTCBEventPtr      = (OS_EVENT  *)0;    /* Clear event pointers                          */
    520          #if (OS_EVENT_MULTI_EN > 0)
    521              OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
    522          #endif
    523              OS_EXIT_CRITICAL();
    524          }
    525          /*$PAGE*/
    526          /*
    527          *********************************************************************************************************
    528          *                                  POST TO A MUTUAL EXCLUSION SEMAPHORE
    529          *
    530          * Description: This function signals a mutual exclusion semaphore
    531          *
    532          * Arguments  : pevent              is a pointer to the event control block associated with the desired
    533          *                                  mutex.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -