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

📄 os_mutex.lst

📁 一个关于UCOS的KEIL工程
💻 LST
📖 第 1 页 / 共 3 页
字号:
 181          *                            opt == OS_DEL_NO_PEND   Delete mutex ONLY if no task pending
 182          *                            opt == OS_DEL_ALWAYS    Deletes the mutex even if tasks are waiting.
 183          *                                                    In this case, all the tasks pending will be readied.
 184          *
 185          *              err           is a pointer to an error code that can contain one of the following values:
 186          *                            OS_NO_ERR               The call was successful and the mutex was deleted
 187          *                            OS_ERR_DEL_ISR          If you attempted to delete the MUTEX from an ISR
 188          *                            OS_ERR_INVALID_OPT      An invalid option was specified
 189          *                            OS_ERR_TASK_WAITING     One or more tasks were waiting on the mutex
 190          *                            OS_ERR_EVENT_TYPE       If you didn't pass a pointer to a mutex
 191          *                            OS_ERR_PEVENT_NULL      If 'pevent' is a NULL pointer.
 192          *
 193          * Returns    : pevent        upon error
 194          *              (OS_EVENT *)0 if the mutex was successfully deleted.
 195          *
 196          * Note(s)    : 1) This function must be used with care.  Tasks that would normally expect the presence of
 197          *                 the mutex MUST check the return code of OSMutexPend().
 198          *              2) This call can potentially disable interrupts for a long time.  The interrupt disable
 199          *                 time is directly proportional to the number of tasks waiting on the mutex.
 200          *              3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the
 201          *                 resource(s) will no longer be guarded by the mutex.
 202          *********************************************************************************************************
 203          */
 204          
 205          #if OS_MUTEX_DEL_EN
 206          OS_EVENT  *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err) KCREENTRANT
 207          {
 208   1      #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
                  OS_CPU_SR  cpu_sr;
              #endif    
 211   1          BOOLEAN    tasks_waiting;
 212   1          INT8U      pip;
 213   1      
 214   1      
 215   1          if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
 216   2              *err = OS_ERR_DEL_ISR;                             /* ... can't DELETE from an ISR             */
 217   2              return (pevent);
 218   2          }
 219   1      #if OS_ARG_CHK_EN > 0
 220   1          if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
 221   2              *err = OS_ERR_PEVENT_NULL;
 222   2              return ((OS_EVENT *)0);
 223   2          }
 224   1          if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
 225   2              *err = OS_ERR_EVENT_TYPE;
 226   2              return (pevent);
 227   2          }
 228   1      #endif
 229   1          OS_ENTER_CRITICAL();
 230   1          if (pevent->OSEventGrp != 0x00) {                      /* See if any tasks waiting on mutex        */
 231   2              tasks_waiting = TRUE;                              /* Yes                                      */
 232   2          } else {
 233   2              tasks_waiting = FALSE;                             /* No                                       */
 234   2          }
 235   1          switch (opt) {
 236   2              case OS_DEL_NO_PEND:                               /* Delete mutex only if no task waiting     */
 237   2                   if (tasks_waiting == FALSE) {
 238   3                       pip                 = (INT8U)(pevent->OSEventCnt >> 8);
 239   3                       OSTCBPrioTbl[pip]   = (OS_TCB *)0;        /* Free up the PIP                          */
 240   3                       pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
 241   3                       pevent->OSEventPtr  = OSEventFreeList;    /* Return Event Control Block to free list  */
C51 COMPILER V6.23a  OS_MUTEX                                                              12/09/2004 16:50:26 PAGE 5   

 242   3                       OSEventFreeList     = pevent;
 243   3                       OS_EXIT_CRITICAL();
 244   3                       *err = OS_NO_ERR;
 245   3                       return ((OS_EVENT *)0);                   /* Mutex has been deleted                   */
 246   3                   } else {
 247   3                       OS_EXIT_CRITICAL();
 248   3                       *err = OS_ERR_TASK_WAITING;
 249   3                       return (pevent);
 250   3                   }
 251   2      
 252   2              case OS_DEL_ALWAYS:                                /* Always delete the mutex                  */
 253   2                   while (pevent->OSEventGrp != 0x00) {          /* Ready ALL tasks waiting for mutex        */
 254   3                       OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);
 255   3                   }
 256   2                   pip                 = (INT8U)(pevent->OSEventCnt >> 8);
 257   2                   OSTCBPrioTbl[pip]   = (OS_TCB *)0;            /* Free up the PIP                          */
 258   2                   pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
 259   2                   pevent->OSEventPtr  = OSEventFreeList;        /* Return Event Control Block to free list  */
 260   2                   OSEventFreeList     = pevent;                 /* Get next free event control block        */
 261   2                   OS_EXIT_CRITICAL();
 262   2                   if (tasks_waiting == TRUE) {                  /* Reschedule only if task(s) were waiting  */
 263   3                       OS_Sched();                               /* Find highest priority task ready to run  */
 264   3                   }
 265   2                   *err = OS_NO_ERR;
 266   2                   return ((OS_EVENT *)0);                       /* Mutex has been deleted                   */
 267   2      
 268   2              default:
 269   2                   OS_EXIT_CRITICAL();
 270   2                   *err = OS_ERR_INVALID_OPT;
 271   2                   return (pevent);
 272   2          }
 273   1      }
 274          #endif
 275          
 276          /*$PAGE*/
 277          /*
 278          *********************************************************************************************************
 279          *                                  PEND ON MUTUAL EXCLUSION SEMAPHORE
 280          *
 281          * Description: This function waits for a mutual exclusion semaphore.
 282          *
 283          * Arguments  : pevent        is a pointer to the event control block associated with the desired
 284          *                            mutex.
 285          *
 286          *              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
 287          *                            wait for the resource up to the amount of time specified by this argument.
 288          *                            If you specify 0, however, your task will wait forever at the specified
 289          *                            mutex or, until the resource becomes available.
 290          *
 291          *              err           is a pointer to where an error message will be deposited.  Possible error
 292          *                            messages are:
 293          *                               OS_NO_ERR          The call was successful and your task owns the mutex
 294          *                               OS_TIMEOUT         The mutex was not available within the specified time.
 295          *                               OS_ERR_EVENT_TYPE  If you didn't pass a pointer to a mutex
 296          *                               OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
 297          *                               OS_ERR_PEND_ISR    If you called this function from an ISR and the result
 298          *                                                  would lead to a suspension.
 299          *
 300          * Returns    : none
 301          *
 302          * Note(s)    : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
 303          *              2) You MUST NOT change the priority of the task that owns the mutex
C51 COMPILER V6.23a  OS_MUTEX                                                              12/09/2004 16:50:26 PAGE 6   

 304          *********************************************************************************************************
 305          */
 306          void  OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) KCREENTRANT
 307          {
 308   1      #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
                  OS_CPU_SR  cpu_sr;
              #endif    
 311   1          INT8U      pip;                                        /* Priority Inheritance Priority (PIP)      */
 312   1          INT8U      mprio;                                      /* Mutex owner priority                     */
 313   1          BOOLEAN    rdy;                                        /* Flag indicating task was ready           */
 314   1          OS_TCB    *ptcb;
 315   1      
 316   1      
 317   1          if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
 318   2              *err = OS_ERR_PEND_ISR;                            /* ... can't PEND from an ISR               */
 319   2              return;
 320   2          }
 321   1      #if OS_ARG_CHK_EN > 0
 322   1          if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
 323   2              *err = OS_ERR_PEVENT_NULL;
 324   2              return;
 325   2          }
 326   1          if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
 327   2              *err = OS_ERR_EVENT_TYPE;
 328   2              return;
 329   2          }
 330   1      #endif
 331   1          OS_ENTER_CRITICAL();                                                                   /* Is Mutex available?                      */
 332   1          if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
 333   2              pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;       /* Yes, Acquire the resource                */
 334   2              pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;         /*      Save priority of owning task        */
 335   2              pevent->OSEventPtr  = (void *)OSTCBCur;            /*      Point to owning task's OS_TCB       */
 336   2              OS_EXIT_CRITICAL();
 337   2              *err  = OS_NO_ERR;
 338   2              return;
 339   2          }
 340   1          pip   = (INT8U)(pevent->OSEventCnt >> 8);                     /* No, Get PIP from mutex            */
 341   1          mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);  /*     Get priority of mutex owner   */
 342   1          ptcb  = (OS_TCB *)(pevent->OSEventPtr);                       /*     Point to TCB of mutex owner   */
 343   1          if (ptcb->OSTCBPrio != pip && mprio > OSTCBCur->OSTCBPrio) {  /*     Need to promote prio of owner?*/
 344   2              if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { /*     See if mutex owner is ready   */
 345   3                                                                        /*     Yes, Remove owner from Rdy ...*/
 346   3                                                                        /*          ... list at current prio */
 347   3                  if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
 348   4                      OSRdyGrp &= ~ptcb->OSTCBBitY;
 349   4                  }
 350   3                  rdy = TRUE;
 351   3              } else {
 352   3                  rdy = FALSE;                                          /* No                                */
 353   3              }
 354   2              ptcb->OSTCBPrio         = pip;                     /* Change owner task prio to PIP            */
 355   2              ptcb->OSTCBY            = ptcb->OSTCBPrio >> 3;
 356   2              ptcb->OSTCBBitY         = OSMapTbl[ptcb->OSTCBY];
 357   2              ptcb->OSTCBX            = ptcb->OSTCBPrio & 0x07;
 358   2              ptcb->OSTCBBitX         = OSMapTbl[ptcb->OSTCBX];
 359   2              if (rdy == TRUE) {                                 /* If task was ready at owner's priority ...*/
 360   3                  OSRdyGrp               |= ptcb->OSTCBBitY;     /* ... make it ready at new priority.       */
 361   3                  OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
 362   3              }
 363   2              OSTCBPrioTbl[pip]       = (OS_TCB *)ptcb;
 364   2          }
 365   1          OSTCBCur->OSTCBStat |= OS_STAT_MUTEX;             /* Mutex not available, pend current task        */
C51 COMPILER V6.23a  OS_MUTEX                                                              12/09/2004 16:50:26 PAGE 7   

 366   1          OSTCBCur->OSTCBDly   = timeout;                   /* Store timeout in current task's TCB           */
 367   1          OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */
 368   1          OS_EXIT_CRITICAL();
 369   1          OS_Sched();                                        /* Find next highest priority task ready         */

⌨️ 快捷键说明

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