os_sem.lst

来自「在51上运行的小的OS系统」· LST 代码 · 共 578 行 · 第 1/3 页

LST
578
字号

 123          * Arguments  : pevent        is a pointer to the event control block associated with the desired
 124          *                            semaphore.
 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)
 156          {
 157              BOOLEAN    tasks_waiting;
 158              OS_EVENT  *pevent_return;
 159          #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
                  OS_CPU_SR  cpu_sr = 0;
              #endif
 162          
 163          
 164          
 165          #if OS_ARG_CHK_EN > 0
 166              if (err == (INT8U *)0) {                               /* Validate 'err'                           */
 167                  return (pevent);
 168              }
 169              if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
 170                  *err = OS_ERR_PEVENT_NULL;
 171                  return (pevent);
 172              }
 173          #endif
 174              if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {        /* Validate event block type                */
 175                  *err = OS_ERR_EVENT_TYPE;
 176                  return (pevent);
 177              }
 178              if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
 179                  *err = OS_ERR_DEL_ISR;                             /* ... can't DELETE from an ISR             */
 180                  return (pevent);
 181              }
 182              OS_ENTER_CRITICAL();
 183              if (pevent->OSEventGrp != 0) {                         /* See if any tasks waiting on semaphore    */
 184                  tasks_waiting = TRUE;                              /* Yes                                      */
C51 COMPILER V8.08   OS_SEM                                                                08/04/2008 21:49:52 PAGE 5   

 185              } else {
 186                  tasks_waiting = FALSE;                             /* No                                       */
 187              }
 188              switch (opt) {
 189                  case OS_DEL_NO_PEND:                               /* Delete semaphore only if no task waiting */
 190                       if (tasks_waiting == FALSE) {
 191          #if OS_EVENT_NAME_SIZE > 1
 192                           pevent->OSEventName[0] = '?';             /* Unknown name                             */
 193                           pevent->OSEventName[1] = OS_ASCII_NUL;
 194          #endif
 195                           pevent->OSEventType    = OS_EVENT_TYPE_UNUSED;
 196                           pevent->OSEventPtr     = OSEventFreeList; /* Return Event Control Block to free list  */
 197                           pevent->OSEventCnt     = 0;
 198                           OSEventFreeList        = pevent;          /* Get next free event control block        */
 199                           OS_EXIT_CRITICAL();
 200                           *err                   = OS_NO_ERR;
 201                           pevent_return          = (OS_EVENT *)0;   /* Semaphore has been deleted               */
 202                       } else {
 203                           OS_EXIT_CRITICAL();
 204                           *err                   = OS_ERR_TASK_WAITING;
 205                           pevent_return          = pevent;
 206                       }
 207                       break;
 208          
 209                  case OS_DEL_ALWAYS:                                /* Always delete the semaphore              */
 210                       while (pevent->OSEventGrp != 0) {             /* Ready ALL tasks waiting for semaphore    */
 211                           (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);
 212                       }
 213          #if OS_EVENT_NAME_SIZE > 1
 214                       pevent->OSEventName[0] = '?';                 /* Unknown name                             */
 215                       pevent->OSEventName[1] = OS_ASCII_NUL;
 216          #endif
 217                       pevent->OSEventType    = OS_EVENT_TYPE_UNUSED;
 218                       pevent->OSEventPtr     = OSEventFreeList;     /* Return Event Control Block to free list  */
 219                       pevent->OSEventCnt     = 0;
 220                       OSEventFreeList        = pevent;              /* Get next free event control block        */
 221                       OS_EXIT_CRITICAL();
 222                       if (tasks_waiting == TRUE) {                  /* Reschedule only if task(s) were waiting  */
 223                           OS_Sched();                               /* Find highest priority task ready to run  */
 224                       }
 225                       *err                   = OS_NO_ERR;
 226                       pevent_return          = (OS_EVENT *)0;       /* Semaphore has been deleted               */
 227                       break;
 228          
 229                  default:
 230                       OS_EXIT_CRITICAL();
 231                       *err                   = OS_ERR_INVALID_OPT;
 232                       pevent_return          = pevent;
 233                       break;
 234              }
 235              return (pevent_return);
 236          }
 237          #endif
 238          
 239          /*$PAGE*/
 240          /*
 241          *********************************************************************************************************
 242          *                                           PEND ON SEMAPHORE
 243          *
 244          * Description: This function waits for a semaphore.
 245          *
 246          * Arguments  : pevent        is a pointer to the event control block associated with the desired
C51 COMPILER V8.08   OS_SEM                                                                08/04/2008 21:49:52 PAGE 6   

 247          *                            semaphore.
 248          *
 249          *              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
 250          *                            wait for the resource up to the amount of time specified by this argument.
 251          *                            If you specify 0, however, your task will wait forever at the specified
 252          *                            semaphore or, until the resource becomes available (or the event occurs).
 253          *
 254          *              err           is a pointer to where an error message will be deposited.  Possible error
 255          *                            messages are:
 256          *
 257          *                            OS_NO_ERR           The call was successful and your task owns the resource
 258          *                                                or, the event you are waiting for occurred.
 259          *                            OS_TIMEOUT          The semaphore was not received within the specified
 260          *                                                timeout.
 261          *                            OS_ERR_EVENT_TYPE   If you didn't pass a pointer to a semaphore.
 262          *                            OS_ERR_PEND_ISR     If you called this function from an ISR and the result
 263          *                                                would lead to a suspension.
 264          *                            OS_ERR_PEVENT_NULL  If 'pevent' is a NULL pointer.
 265          *
 266          * Returns    : none
 267          *********************************************************************************************************
 268          */
 269          
 270          void  OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
 271          {
 272          #if OS_CRITICAL_METHOD == 3                           /* Allocate storage for CPU status register      */
                  OS_CPU_SR  cpu_sr = 0;
              #endif
 275          
 276          
 277          
 278          #if OS_ARG_CHK_EN > 0
 279              if (err == (INT8U *)0) {                          /* Validate 'err'                                */
 280                  return;
 281              }
 282              if (pevent == (OS_EVENT *)0) {                    /* Validate 'pevent'                             */
 283                  *err = OS_ERR_PEVENT_NULL;
 284                  return;
 285              }
 286          #endif
 287              if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {   /* Validate event block type                     */
 288                  *err = OS_ERR_EVENT_TYPE;
 289                  return;
 290              }
 291              if (OSIntNesting > 0) {                           /* See if called from ISR ...                    */
 292                  *err = OS_ERR_PEND_ISR;                       /* ... can't PEND from an ISR                    */
 293                  return;
 294              }
 295              OS_ENTER_CRITICAL();
 296              if (pevent->OSEventCnt > 0) {                     /* If sem. is positive, resource available ...   */
 297                  pevent->OSEventCnt--;                         /* ... decrement semaphore only if positive.     */
 298                  OS_EXIT_CRITICAL();
 299                  *err = OS_NO_ERR;
 300                  return;
 301              }
 302                                                                /* Otherwise, must wait until event occurs       */
 303              OSTCBCur->OSTCBStat   |= OS_STAT_SEM;             /* Resource not available, pend on semaphore     */
 304              OSTCBCur->OSTCBPendTO  = FALSE;
 305              OSTCBCur->OSTCBDly     = timeout;                 /* Store pend timeout in TCB                     */
 306              OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */
 307              OS_EXIT_CRITICAL();
 308              OS_Sched();                                       /* Find next highest priority task ready         */
C51 COMPILER V8.08   OS_SEM                                                                08/04/2008 21:49:52 PAGE 7   

⌨️ 快捷键说明

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