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

📄 os_mutex.lst

📁 在51上运行的小的OS系统
💻 LST
📖 第 1 页 / 共 4 页
字号:
 272                           pevent_return       = pevent;
 273                       }
 274                       break;
 275          
 276                  case OS_DEL_ALWAYS:                                /* Always delete the mutex                  */
 277                       while (pevent->OSEventGrp != 0) {             /* Ready ALL tasks waiting for mutex        */
 278                           (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);
 279                       }
 280          #if OS_EVENT_NAME_SIZE > 1
 281                       pevent->OSEventName[0] = '?';                 /* Unknown name                             */
 282                       pevent->OSEventName[1] = OS_ASCII_NUL;
 283          #endif
 284                       pip                 = (INT8U)(pevent->OSEventCnt >> 8);
 285                       OSTCBPrioTbl[pip]   = (OS_TCB *)0;            /* Free up the PIP                          */
 286                       pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
 287                       pevent->OSEventPtr  = OSEventFreeList;        /* Return Event Control Block to free list  */
 288                       pevent->OSEventCnt  = 0;
 289                       OSEventFreeList     = pevent;                 /* Get next free event control block        */
 290                       OS_EXIT_CRITICAL();
 291                       if (tasks_waiting == TRUE) {                  /* Reschedule only if task(s) were waiting  */
 292                           OS_Sched();                               /* Find highest priority task ready to run  */
 293                       }
 294                       *err          = OS_NO_ERR;
 295                       pevent_return = (OS_EVENT *)0;                /* Mutex has been deleted                   */
 296                       break;
 297          
 298                  default:
 299                       OS_EXIT_CRITICAL();
 300                       *err          = OS_ERR_INVALID_OPT;
 301                       pevent_return = pevent;
 302                       break;
 303              }
 304              return (pevent_return);
 305          }
 306          #endif
 307          
C51 COMPILER V8.08   OS_MUTEX                                                              08/04/2008 21:49:52 PAGE 7   

 308          /*$PAGE*/
 309          /*
 310          *********************************************************************************************************
 311          *                                  PEND ON MUTUAL EXCLUSION SEMAPHORE
 312          *
 313          * Description: This function waits for a mutual exclusion semaphore.
 314          *
 315          * Arguments  : pevent        is a pointer to the event control block associated with the desired
 316          *                            mutex.
 317          *
 318          *              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
 319          *                            wait for the resource up to the amount of time specified by this argument.
 320          *                            If you specify 0, however, your task will wait forever at the specified
 321          *                            mutex or, until the resource becomes available.
 322          *
 323          *              err           is a pointer to where an error message will be deposited.  Possible error
 324          *                            messages are:
 325          *                               OS_NO_ERR          The call was successful and your task owns the mutex
 326          *                               OS_TIMEOUT         The mutex was not available within the specified time.
 327          *                               OS_ERR_EVENT_TYPE  If you didn't pass a pointer to a mutex
 328          *                               OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
 329          *                               OS_ERR_PEND_ISR    If you called this function from an ISR and the result
 330          *                                                  would lead to a suspension.
 331          *                               OS_ERR_PIP_LOWER   If the priority of the task that owns the Mutex is
 332          *                                                  HIGHER (i.e. a lower number) than the PIP.  This error
 333          *                                                  indicates that you did not set the PIP higher (lower
 334          *                                                  number) than ALL the tasks that compete for the Mutex.
 335          *                                                  Unfortunately, this is something that could not be
 336          *                                                  detected when the Mutex is created because we don't kno
             -w
 337          *                                                  what tasks will be using the Mutex.
 338          *
 339          * Returns    : none
 340          *
 341          * Note(s)    : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
 342          *              2) You MUST NOT change the priority of the task that owns the mutex
 343          *********************************************************************************************************
 344          */
 345          void  OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
 346          {
 347              INT8U      pip;                                        /* Priority Inheritance Priority (PIP)      */
 348              INT8U      mprio;                                      /* Mutex owner priority                     */
 349              BOOLEAN    rdy;                                        /* Flag indicating task was ready           */
 350              OS_TCB    *ptcb;
 351              OS_EVENT  *pevent2;
 352              INT8U      y;
 353          #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
                  OS_CPU_SR  cpu_sr = 0;
              #endif
 356          
 357          
 358          
 359          #if OS_ARG_CHK_EN > 0
 360              if (err == (INT8U *)0) {                               /* Validate 'err'                           */
 361                  return;
 362              }
 363              if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
 364                  *err = OS_ERR_PEVENT_NULL;
 365                  return;
 366              }
 367          #endif
 368              if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
C51 COMPILER V8.08   OS_MUTEX                                                              08/04/2008 21:49:52 PAGE 8   

 369                  *err = OS_ERR_EVENT_TYPE;
 370                  return;
 371              }
 372              if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
 373                  *err = OS_ERR_PEND_ISR;                            /* ... can't PEND from an ISR               */
 374                  return;
 375              }
 376              OS_ENTER_CRITICAL();                                
 377              pip = (INT8U)(pevent->OSEventCnt >> 8);                /* Get PIP from mutex                       */
 378                                                                     /* Is Mutex available?                      */
 379              if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
 380                  pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;       /* Yes, Acquire the resource                */
 381                  pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;         /*      Save priority of owning task        */
 382                  pevent->OSEventPtr  = (void *)OSTCBCur;            /*      Point to owning task's OS_TCB       */
 383                  if (OSTCBCur->OSTCBPrio <= pip) {                  /*      PIP 'must' have a SMALLER prio ...  */
 384                      OS_EXIT_CRITICAL();                            /*      ... than current task!              */
 385                      *err  = OS_ERR_PIP_LOWER;
 386                  } else {
 387                      OS_EXIT_CRITICAL();
 388                      *err  = OS_NO_ERR;
 389                  }
 390                  return;
 391              }
 392              mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);  /* No, Get priority of mutex owner   */
 393              ptcb  = (OS_TCB *)(pevent->OSEventPtr);                       /*     Point to TCB of mutex owner   */
 394              if (ptcb->OSTCBPrio > pip) {                                  /*     Need to promote prio of owner?*/
 395                  if (mprio > OSTCBCur->OSTCBPrio) {
 396                      y = ptcb->OSTCBY;
 397                      if ((OSRdyTbl[y] & ptcb->OSTCBBitX) != 0) {           /*     See if mutex owner is ready   */
 398                          OSRdyTbl[y] &= ~ptcb->OSTCBBitX;                  /*     Yes, Remove owner from Rdy ...*/
 399                          if (OSRdyTbl[y] == 0) {                           /*          ... list at current prio */
 400                              OSRdyGrp &= ~ptcb->OSTCBBitY;
 401                          }
 402                          rdy = TRUE;
 403                      } else {
 404                          pevent2 = ptcb->OSTCBEventPtr;
 405                          if (pevent2 != (OS_EVENT *)0) {                   /* Remove from event wait list       */
 406                              if ((pevent2->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {
 407                                  pevent2->OSEventGrp &= ~ptcb->OSTCBBitY;
 408                              }
 409                          }
 410                          rdy = FALSE;                               /* No                                       */
 411                      }
 412                      ptcb->OSTCBPrio = pip;                         /* Change owner task prio to PIP            */
 413          #if OS_LOWEST_PRIO <= 63
 414                      ptcb->OSTCBY    =  ptcb->OSTCBPrio >> 3;
 415                      ptcb->OSTCBX    =  ptcb->OSTCBPrio & 0x07;
 416          #else
                          ptcb->OSTCBY    = (ptcb->OSTCBPrio >> 4) & 0xFF;
                          ptcb->OSTCBX    =  ptcb->OSTCBPrio & 0x0F;
              #endif
 420                      ptcb->OSTCBBitY = 1 << ptcb->OSTCBY;
 421                      ptcb->OSTCBBitX = 1 << ptcb->OSTCBX;
 422                      if (rdy == TRUE) {                             /* If task was ready at owner's priority ...*/
 423                          OSRdyGrp               |= ptcb->OSTCBBitY; /* ... make it ready at new priority.       */
 424                          OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
 425                      } else {
 426                          pevent2 = ptcb->OSTCBEventPtr;
 427                          if (pevent2 != (OS_EVENT *)0) {            /* Remove from event wait list              */
 428                              pevent2->OSEventGrp               |= ptcb->OSTCBBitY;
 429                              pevent2->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
 430                          }
C51 COMPILER V8.08   OS_MUTEX                                                              08/04/2008 21:49:52 PAGE 9   

 431                      }
 432                      OSTCBPrioTbl[pip] = ptcb;
 433                  }
 434              }
 435              OSTCBCur->OSTCBStat   |= OS_STAT_MUTEX;           /* Mutex not available, pend current task        */
 436              OSTCBCur->OSTCBPendTO  = FALSE;
 437              OSTCBCur->OSTCBDly     = timeout;                 /* Store timeout in current task's TCB           */
 438              OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */

⌨️ 快捷键说明

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