📄 os_mutex.s79
字号:
// 62 OS_CPU_SR cpu_sr;
// 63 #endif
// 64
// 65
// 66 if (OSIntNesting > 0) { /* Make sure it's not called from an ISR */
LDR R0,??DataTable6 ;; OSIntNesting
LDRB R0,[R0, #+0]
CMP R0,#+0
BEQ ??OSMutexAccept_0
// 67 *err = OS_ERR_PEND_ISR;
MOVS R0,#+2
??OSMutexAccept_1:
STRB R0,[R4, #+0]
// 68 return (0);
MOVS R0,#+0
B ??OSMutexAccept_2
// 69 }
// 70 #if OS_ARG_CHK_EN > 0
// 71 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
??OSMutexAccept_0:
CMP R5,#+0
BNE ??OSMutexAccept_3
// 72 *err = OS_ERR_PEVENT_NULL;
MOVS R0,#+4
B.N ??OSMutexAccept_1
// 73 return (0);
// 74 }
// 75 #endif
// 76 if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
??OSMutexAccept_3:
LDRB R0,[R5, #+0]
CMP R0,#+4
BEQ ??OSMutexAccept_4
// 77 *err = OS_ERR_EVENT_TYPE;
MOVS R0,#+1
STRB R0,[R4, #+0]
// 78 return (0);
MOVS R0,#+0
B ??OSMutexAccept_2
// 79 }
// 80 OS_ENTER_CRITICAL(); /* Get value (0 or 1) of Mutex */
??OSMutexAccept_4:
_BLF OS_CPU_SR_Save,??OS_CPU_SR_Save??rT
// 81 if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
LDRH R1,[R5, #+2]
LSLS R1,R1,#+24
LSRS R1,R1,#+24
CMP R1,#+255
BNE ??OSMutexAccept_5
// 82 pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Mask off LSByte (Acquire Mutex) */
LDRH R1,[R5, #+2]
MOVS R2,#+255
LSLS R2,R2,#+8 ;; #+65280
ANDS R2,R2,R1
STRH R2,[R5, #+2]
// 83 pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save current task priority in LSByte */
MOVS R1,R2
LDR R2,??DataTable2 ;; OSTCBCur
LDR R2,[R2, #+0]
ADDS R2,R2,#+45
LDRB R2,[R2, #+0]
ORRS R2,R2,R1
STRH R2,[R5, #+2]
// 84 pevent->OSEventPtr = (void *)OSTCBCur; /* Link TCB of task owning Mutex */
LDR R1,??DataTable2 ;; OSTCBCur
LDR R1,[R1, #+0]
STR R1,[R5, #+4]
// 85 OS_EXIT_CRITICAL();
_BLF OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
// 86 *err = OS_NO_ERR;
MOVS R0,#+0
STRB R0,[R4, #+0]
// 87 return (1);
MOVS R0,#+1
B ??OSMutexAccept_2
// 88 }
// 89 OS_EXIT_CRITICAL();
??OSMutexAccept_5:
_BLF OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
// 90 *err = OS_NO_ERR;
MOVS R0,#+0
STRB R0,[R4, #+0]
// 91 return (0);
??OSMutexAccept_2:
POP {R4,R5}
POP {R1}
BX R1 ;; return
CFI EndBlock cfiBlock1
// 92 }
RSEG CODE:CODE:NOROOT(2)
DATA
??DataTable2:
DC32 OSTCBCur
RSEG CODE:CODE:NOROOT(2)
CFI Block cfiBlock2 Using cfiCommon0
CFI NoFunction
ARM
??OSMutexCreate??rA:
ADD R12,PC,#+1
BX R12
CFI EndBlock cfiBlock2
REQUIRE OSMutexCreate
// 93 #endif
// 94
// 95 /*$PAGE*/
// 96 /*
// 97 *********************************************************************************************************
// 98 * CREATE A MUTUAL EXCLUSION SEMAPHORE
// 99 *
// 100 * Description: This function creates a mutual exclusion semaphore.
// 101 *
// 102 * Arguments : prio is the priority to use when accessing the mutual exclusion semaphore. In
// 103 * other words, when the semaphore is acquired and a higher priority task
// 104 * attempts to obtain the semaphore then the priority of the task owning the
// 105 * semaphore is raised to this priority. It is assumed that you will specify
// 106 * a priority that is LOWER in value than ANY of the tasks competing for the
// 107 * mutex.
// 108 *
// 109 * err is a pointer to an error code which will be returned to your application:
// 110 * OS_NO_ERR if the call was successful.
// 111 * OS_ERR_CREATE_ISR if you attempted to create a MUTEX from an ISR
// 112 * OS_PRIO_EXIST if a task at the priority inheritance priority
// 113 * already exist.
// 114 * OS_ERR_PEVENT_NULL No more event control blocks available.
// 115 * OS_PRIO_INVALID if the priority you specify is higher that the
// 116 * maximum allowed (i.e. > OS_LOWEST_PRIO)
// 117 *
// 118 * Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the
// 119 * created mutex.
// 120 * == (void *)0 if an error is detected.
// 121 *
// 122 * Note(s) : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number
// 123 * of the task owning the mutex or 0xFF if no task owns the mutex.
// 124 * 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the priority number
// 125 * to use to reduce priority inversion.
// 126 *********************************************************************************************************
// 127 */
// 128
RSEG CODE:CODE:NOROOT(2)
CFI Block cfiBlock3 Using cfiCommon1
CFI Function OSMutexCreate
THUMB
// 129 OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err)
// 130 {
OSMutexCreate:
PUSH {R4-R6,LR}
CFI ?RET Frame(CFA, -4)
CFI R6 Frame(CFA, -8)
CFI R5 Frame(CFA, -12)
CFI R4 Frame(CFA, -16)
CFI CFA R13+16
MOVS R4,R0
MOVS R5,R1
// 131 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
// 132 OS_CPU_SR cpu_sr;
// 133 #endif
// 134 OS_EVENT *pevent;
// 135
// 136
// 137 if (OSIntNesting > 0) { /* See if called from ISR ... */
LDR R0,??DataTable6 ;; OSIntNesting
LDRB R0,[R0, #+0]
CMP R0,#+0
BEQ ??OSMutexCreate_0
// 138 *err = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */
MOVS R0,#+141
??OSMutexCreate_1:
STRB R0,[R5, #+0]
// 139 return ((OS_EVENT *)0);
MOVS R0,#+0
B ??OSMutexCreate_2
// 140 }
// 141 #if OS_ARG_CHK_EN > 0
// 142 if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */
??OSMutexCreate_0:
CMP R4,#+63
BCC ??OSMutexCreate_3
// 143 *err = OS_PRIO_INVALID;
MOVS R0,#+42
B.N ??OSMutexCreate_1
// 144 return ((OS_EVENT *)0);
// 145 }
// 146 #endif
// 147 OS_ENTER_CRITICAL();
??OSMutexCreate_3:
_BLF OS_CPU_SR_Save,??OS_CPU_SR_Save??rT
// 148 if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */
LSLS R1,R4,#+2
LDR R2,??DataTable10 ;; OSTCBPrioTbl
LDR R1,[R2, R1]
CMP R1,#+0
BEQ ??OSMutexCreate_4
// 149 OS_EXIT_CRITICAL(); /* Task already exist at priority ... */
_BLF OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
// 150 *err = OS_PRIO_EXIST; /* ... inheritance priority */
MOVS R0,#+40
STRB R0,[R5, #+0]
// 151 return ((OS_EVENT *)0);
MOVS R0,#+0
B ??OSMutexCreate_2
// 152 }
// 153 OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the table entry */
??OSMutexCreate_4:
LSLS R1,R4,#+2
MOVS R3,#+1
STR R3,[R2, R1]
// 154 pevent = OSEventFreeList; /* Get next free event control block */
LDR R1,??DataTable12 ;; OSEventFreeList
LDR R6,[R1, #+0]
// 155 if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */
CMP R6,#+0
BNE ??OSMutexCreate_5
// 156 OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */
LSLS R1,R4,#+2
MOVS R3,#+0
STR R3,[R2, R1]
// 157 OS_EXIT_CRITICAL();
_BLF OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
// 158 *err = OS_ERR_PEVENT_NULL; /* No more event control blocks */
MOVS R0,#+4
B.N ??OSMutexCreate_1
// 159 return (pevent);
// 160 }
// 161 OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */
??OSMutexCreate_5:
LDR R2,[R6, #+4]
STR R2,[R1, #+0]
// 162 OS_EXIT_CRITICAL();
_BLF OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
// 163 pevent->OSEventType = OS_EVENT_TYPE_MUTEX;
MOVS R0,#+4
STRB R0,[R6, #+0]
// 164 pevent->OSEventCnt = ((INT16U)prio << 8) | OS_MUTEX_AVAILABLE; /* Resource is available */
LSLS R0,R4,#+8
MOVS R1,#+255
ORRS R1,R1,R0
STRH R1,[R6, #+2]
// 165 pevent->OSEventPtr = (void *)0; /* No task owning the mutex */
MOVS R0,#+0
STR R0,[R6, #+4]
// 166 #if OS_EVENT_NAME_SIZE > 1
// 167 pevent->OSEventName[0] = '?';
MOVS R0,#+63
STRB R0,[R6, #+16]
// 168 pevent->OSEventName[1] = OS_ASCII_NUL;
MOVS R0,#+0
STRB R0,[R6, #+17]
// 169 #endif
// 170 OS_EventWaitListInit(pevent);
MOVS R0,R6
_BLF OS_EventWaitListInit,??OS_EventWaitListInit??rT
// 171 *err = OS_NO_ERR;
MOVS R0,#+0
STRB R0,[R5, #+0]
// 172 return (pevent);
MOVS R0,R6
??OSMutexCreate_2:
POP {R4-R6}
POP {R1}
BX R1 ;; return
CFI EndBlock cfiBlock3
// 173 }
RSEG CODE:CODE:NOROOT(2)
CFI Block cfiBlock4 Using cfiCommon0
CFI NoFunction
ARM
??OSMutexDel??rA:
ADD R12,PC,#+1
BX R12
CFI EndBlock cfiBlock4
REQUIRE OSMutexDel
// 174
// 175 /*$PAGE*/
// 176 /*
// 177 *********************************************************************************************************
// 178 * DELETE A MUTEX
// 179 *
// 180 * Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it.
// 181 *
// 182 * Arguments : pevent is a pointer to the event control block associated with the desired mutex.
// 183 *
// 184 * opt determines delete options as follows:
// 185 * opt == OS_DEL_NO_PEND Delete mutex ONLY if no task pending
// 186 * opt == OS_DEL_ALWAYS Deletes the mutex even if tasks are waiting.
// 187 * In this case, all the tasks pending will be readied.
// 188 *
// 189 * err is a pointer to an error code that can contain one of the following values:
// 190 * OS_NO_ERR The call was successful and the mutex was deleted
// 191 * OS_ERR_DEL_ISR If you attempted to delete the MUTEX from an ISR
// 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}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -