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

📄 os_mutex.s79

📁 ARM仿真案例
💻 S79
📖 第 1 页 / 共 5 页
字号:
//  192 *                            OS_ERR_INVALID_OPT      An invalid option was specified
//  193 *                            OS_ERR_TASK_WAITING     One or more tasks were waiting on the mutex
//  194 *                            OS_ERR_EVENT_TYPE       If you didn't pass a pointer to a mutex
//  195 *                            OS_ERR_PEVENT_NULL      If 'pevent' is a NULL pointer.
//  196 *
//  197 * Returns    : pevent        upon error
//  198 *              (OS_EVENT *)0 if the mutex was successfully deleted.
//  199 *
//  200 * Note(s)    : 1) This function must be used with care.  Tasks that would normally expect the presence of
//  201 *                 the mutex MUST check the return code of OSMutexPend().
//  202 *              2) This call can potentially disable interrupts for a long time.  The interrupt disable
//  203 *                 time is directly proportional to the number of tasks waiting on the mutex.
//  204 *              3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the
//  205 *                 resource(s) will no longer be guarded by the mutex.
//  206 *********************************************************************************************************
//  207 */
//  208 
//  209 #if OS_MUTEX_DEL_EN

        RSEG CODE:CODE:NOROOT(2)
        CFI Block cfiBlock5 Using cfiCommon1
        CFI Function OSMutexDel
        THUMB
//  210 OS_EVENT  *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
//  211 {
OSMutexDel:
        PUSH     {R1,R4-R7,LR}
        CFI ?RET Frame(CFA, -4)
        CFI R7 Frame(CFA, -8)
        CFI R6 Frame(CFA, -12)
        CFI R5 Frame(CFA, -16)
        CFI R4 Frame(CFA, -20)
        CFI CFA R13+24
        MOVS     R4,R0
        MOVS     R5,R2
//  212 #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
//  213     OS_CPU_SR  cpu_sr;
//  214 #endif    
//  215     BOOLEAN    tasks_waiting;
//  216     INT8U      pip;
//  217 
//  218 
//  219     if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
        LDR      R0,??DataTable10  ;; OSIntNesting
        LDRB     R0,[R0, #+0]
        CMP      R0,#+1
        BCC      ??OSMutexDel_0
//  220         *err = OS_ERR_DEL_ISR;                             /* ... can't DELETE from an ISR             */
        MOVS     R0,#+140
        STRB     R0,[R5, #+0]
//  221         return (pevent);
        MOVS     R0,R4
        B        ??OSMutexDel_1
//  222     }
//  223 #if OS_ARG_CHK_EN > 0
//  224     if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
??OSMutexDel_0:
        CMP      R4,#+0
        BNE      ??OSMutexDel_2
//  225         *err = OS_ERR_PEVENT_NULL;
        MOVS     R0,#+4
        STRB     R0,[R5, #+0]
//  226         return ((OS_EVENT *)0);
        MOVS     R0,#+0
        B        ??OSMutexDel_1
//  227     }
//  228 #endif
//  229     if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
??OSMutexDel_2:
        LDRB     R0,[R4, #+0]
        CMP      R0,#+4
        BEQ      ??OSMutexDel_3
//  230         *err = OS_ERR_EVENT_TYPE;
        MOVS     R0,#+1
        STRB     R0,[R5, #+0]
//  231         return (pevent);
        MOVS     R0,R4
        B        ??OSMutexDel_1
//  232     }
//  233     OS_ENTER_CRITICAL();
??OSMutexDel_3:
        _BLF     OS_CPU_SR_Save,??OS_CPU_SR_Save??rT
        MOVS     R6,R0
//  234     if (pevent->OSEventGrp != 0x00) {                      /* See if any tasks waiting on mutex        */
        LDRB     R0,[R4, #+1]
        CMP      R0,#+0
        BEQ      ??OSMutexDel_4
//  235         tasks_waiting = TRUE;                              /* Yes                                      */
        MOVS     R7,#+1
        B        ??OSMutexDel_5
//  236     } else {
//  237         tasks_waiting = FALSE;                             /* No                                       */
??OSMutexDel_4:
        MOVS     R7,#+0
//  238     }
//  239     switch (opt) {
??OSMutexDel_5:
        MOV      R0,SP
        LDRB     R0,[R0, #+0]
        CMP      R0,#+0
        BEQ      ??OSMutexDel_6
        CMP      R0,#+1
        BEQ      ??OSMutexDel_7
        B        ??OSMutexDel_8
//  240         case OS_DEL_NO_PEND:                               /* Delete mutex only if no task waiting     */
//  241              if (tasks_waiting == FALSE) {
??OSMutexDel_6:
        CMP      R7,#+0
        BNE      ??OSMutexDel_9
//  242 #if OS_EVENT_NAME_SIZE > 1
//  243                  pevent->OSEventName[0] = '?';             /* Unknown name                             */
        MOVS     R0,#+63
        STRB     R0,[R4, #+16]
//  244                  pevent->OSEventName[1] = OS_ASCII_NUL;
        MOVS     R0,#+0
        STRB     R0,[R4, #+17]
//  245 #endif
//  246                  pip                 = (INT8U)(pevent->OSEventCnt >> 8);
        LDRH     R0,[R4, #+2]
        LSLS     R0,R0,#+16       ;; ZeroExtS R0,R0,#+16,#+16
        LSRS     R0,R0,#+16
        LSRS     R0,R0,#+8
//  247                  OSTCBPrioTbl[pip]   = (OS_TCB *)0;        /* Free up the PIP                          */
        LSLS     R0,R0,#+24       ;; ZeroExtS R0,R0,#+24,#+24
        LSRS     R0,R0,#+24
        MOVS     R1,#+4
        MULS     R0,R1,R0
        LDR      R1,??DataTable14  ;; OSTCBPrioTbl
        MOVS     R2,#+0
        STR      R2,[R1, R0]
//  248                  pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
        MOVS     R0,#+0
        STRB     R0,[R4, #+0]
//  249                  pevent->OSEventPtr  = OSEventFreeList;    /* Return Event Control Block to free list  */
        LDR      R0,??DataTable16  ;; OSEventFreeList
        LDR      R0,[R0, #+0]
        STR      R0,[R4, #+4]
//  250                  pevent->OSEventCnt  = 0;
        MOVS     R0,#+0
        STRH     R0,[R4, #+2]
//  251                  OSEventFreeList     = pevent;
        LDR      R0,??DataTable16  ;; OSEventFreeList
        STR      R4,[R0, #+0]
//  252                  OS_EXIT_CRITICAL();
        MOVS     R0,R6
        _BLF     OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
//  253                  *err                = OS_NO_ERR;
        MOVS     R0,#+0
        STRB     R0,[R5, #+0]
//  254                  return ((OS_EVENT *)0);                   /* Mutex has been deleted                   */
        MOVS     R0,#+0
        B        ??OSMutexDel_1
//  255              } else {
//  256                  OS_EXIT_CRITICAL();
??OSMutexDel_9:
        MOVS     R0,R6
        _BLF     OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
//  257                  *err                = OS_ERR_TASK_WAITING;
        MOVS     R0,#+8
        STRB     R0,[R5, #+0]
//  258                  return (pevent);
        MOVS     R0,R4
        B        ??OSMutexDel_1
//  259              }
//  260 
//  261         case OS_DEL_ALWAYS:                                /* Always delete the mutex                  */
//  262              while (pevent->OSEventGrp != 0x00) {          /* Ready ALL tasks waiting for mutex        */
//  263                  OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);
??OSMutexDel_10:
        MOVS     R2,#+16
        MOVS     R1,#+0
        MOVS     R0,R4
        _BLF     OS_EventTaskRdy,??OS_EventTaskRdy??rT
//  264              }
??OSMutexDel_7:
        LDRB     R0,[R4, #+1]
        CMP      R0,#+0
        BNE      ??OSMutexDel_10
//  265 #if OS_EVENT_NAME_SIZE > 1
//  266              pevent->OSEventName[0] = '?';                 /* Unknown name                             */
        MOVS     R0,#+63
        STRB     R0,[R4, #+16]
//  267              pevent->OSEventName[1] = OS_ASCII_NUL;
        MOVS     R0,#+0
        STRB     R0,[R4, #+17]
//  268 #endif
//  269              pip                 = (INT8U)(pevent->OSEventCnt >> 8);
        LDRH     R0,[R4, #+2]
        LSLS     R0,R0,#+16       ;; ZeroExtS R0,R0,#+16,#+16
        LSRS     R0,R0,#+16
        LSRS     R0,R0,#+8
//  270              OSTCBPrioTbl[pip]   = (OS_TCB *)0;            /* Free up the PIP                          */
        LSLS     R0,R0,#+24       ;; ZeroExtS R0,R0,#+24,#+24
        LSRS     R0,R0,#+24
        MOVS     R1,#+4
        MULS     R0,R1,R0
        LDR      R1,??DataTable14  ;; OSTCBPrioTbl
        MOVS     R2,#+0
        STR      R2,[R1, R0]
//  271              pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
        MOVS     R0,#+0
        STRB     R0,[R4, #+0]
//  272              pevent->OSEventPtr  = OSEventFreeList;        /* Return Event Control Block to free list  */
        LDR      R0,??DataTable16  ;; OSEventFreeList
        LDR      R0,[R0, #+0]
        STR      R0,[R4, #+4]
//  273              pevent->OSEventCnt  = 0;
        MOVS     R0,#+0
        STRH     R0,[R4, #+2]
//  274              OSEventFreeList     = pevent;                 /* Get next free event control block        */
        LDR      R0,??DataTable16  ;; OSEventFreeList
        STR      R4,[R0, #+0]
//  275              OS_EXIT_CRITICAL();
        MOVS     R0,R6
        _BLF     OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
//  276              if (tasks_waiting == TRUE) {                  /* Reschedule only if task(s) were waiting  */
        CMP      R7,#+1
        BNE      ??OSMutexDel_11
//  277                  OS_Sched();                               /* Find highest priority task ready to run  */
        _BLF     OS_Sched,??OS_Sched??rT
//  278              }
//  279              *err = OS_NO_ERR;
??OSMutexDel_11:
        MOVS     R0,#+0
        STRB     R0,[R5, #+0]
//  280              return ((OS_EVENT *)0);                       /* Mutex has been deleted                   */
        MOVS     R0,#+0
        B        ??OSMutexDel_1
//  281 
//  282         default:
//  283              OS_EXIT_CRITICAL();
??OSMutexDel_8:
        MOVS     R0,R6
        _BLF     OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
//  284              *err = OS_ERR_INVALID_OPT;
        MOVS     R0,#+7
        STRB     R0,[R5, #+0]
//  285              return (pevent);
        MOVS     R0,R4
??OSMutexDel_1:
        ADD      SP,SP,#+4
        CFI CFA R13+20
        POP      {R4-R7}
        POP      {R1}
        BX       R1               ;; return
        CFI EndBlock cfiBlock5
//  286     }
//  287 }

        RSEG CODE:CODE:NOROOT(2)
        DATA
??DataTable10:
        DC32     OSIntNesting

        RSEG CODE:CODE:NOROOT(2)
        DATA
??DataTable14:
        DC32     OSTCBPrioTbl

        RSEG CODE:CODE:NOROOT(2)
        DATA
??DataTable16:
        DC32     OSEventFreeList

        RSEG CODE:CODE:NOROOT(2)
        CFI Block cfiBlock6 Using cfiCommon0
        CFI NoFunction
        ARM
??OSMutexPend??rA:
        ADD      R12,PC,#+1
        BX       R12
        CFI EndBlock cfiBlock6
        REQUIRE OSMutexPend
//  288 #endif
//  289 
//  290 /*$PAGE*/
//  291 /*
//  292 *********************************************************************************************************
//  293 *                                  PEND ON MUTUAL EXCLUSION SEMAPHORE
//  294 *
//  295 * Description: This function waits for a mutual exclusion semaphore.
//  296 *
//  297 * Arguments  : pevent        is a pointer to the event control block associated with the desired
//  298 *                            mutex.
//  299 *
//  300 *              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
//  301 *                            wait for the resource up to the amount of time specified by this argument.
//  302 *                            If you specify 0, however, your task will wait forever at the specified
//  303 *                            mutex or, until the resource becomes available.
//  304 *
//  305 *              err           is a pointer to where an error message will be deposited.  Possible error
//  306 *                            messages are:
//  307 *                               OS_NO_ERR          The call was successful and your task owns the mutex
//  308 *                               OS_TIMEOUT         The mutex was not available within the specified time.
//  309 *                               OS_ERR_EVENT_TYPE  If you didn't pass a pointer to a mutex
//  310 *                               OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
//  311 *                               OS_ERR_PEND_ISR    If you called this function from an ISR and the result
//  312 *                                                  would lead to a suspension.
//  313 *
//  314 * Returns    : none
//  315 *
//  316 * Note(s)    : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
//  317 *              2) You MUST NOT change the priority of the task that owns the mutex
//  318 *********************************************************************************************************
//  319 */

        RSEG CODE:CODE:NOROOT(2)
        CFI Block cfiBlock7 Using cfiCommon1
        CFI Function OSMutexPend
        THUMB
//  320 void  OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
//  321 {
OSMutexPend:
        PUSH     {R1,R4-R7,LR}
        CFI ?RET Frame(CFA, -4)
        CFI R7 Frame(CFA, -8)
        CFI R6 Frame(CFA, -12)
        CFI R5 Frame(CFA, -16)

⌨️ 快捷键说明

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