📄 os_mutex.lst
字号:
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
\ In segment CODE, align 4, keep-with-next
129 OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err)
130 {
\ OSMutexCreate:
\ 00000000 70B5 PUSH {R4-R6,LR}
\ 00000002 0400 MOVS R4,R0
\ 00000004 0D00 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 ... */
\ 00000006 .... LDR R0,??DataTable6 ;; OSIntNesting
\ 00000008 0078 LDRB R0,[R0, #+0]
\ 0000000A 0028 CMP R0,#+0
\ 0000000C 03D0 BEQ ??OSMutexCreate_0
138 *err = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */
\ 0000000E 8D20 MOVS R0,#+141
\ ??OSMutexCreate_1:
\ 00000010 2870 STRB R0,[R5, #+0]
139 return ((OS_EVENT *)0);
\ 00000012 0020 MOVS R0,#+0
\ 00000014 34E0 B ??OSMutexCreate_2
140 }
141 #if OS_ARG_CHK_EN > 0
142 if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */
\ ??OSMutexCreate_0:
\ 00000016 3F2C CMP R4,#+63
\ 00000018 01D3 BCC ??OSMutexCreate_3
143 *err = OS_PRIO_INVALID;
\ 0000001A 2A20 MOVS R0,#+42
\ 0000001C F8E7 B.N ??OSMutexCreate_1
144 return ((OS_EVENT *)0);
145 }
146 #endif
147 OS_ENTER_CRITICAL();
\ ??OSMutexCreate_3:
\ 0000001E ........ _BLF OS_CPU_SR_Save,??OS_CPU_SR_Save??rT
148 if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */
\ 00000022 A100 LSLS R1,R4,#+2
\ 00000024 .... LDR R2,??DataTable10 ;; OSTCBPrioTbl
\ 00000026 5158 LDR R1,[R2, R1]
\ 00000028 0029 CMP R1,#+0
\ 0000002A 05D0 BEQ ??OSMutexCreate_4
149 OS_EXIT_CRITICAL(); /* Task already exist at priority ... */
\ 0000002C ........ _BLF OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
150 *err = OS_PRIO_EXIST; /* ... inheritance priority */
\ 00000030 2820 MOVS R0,#+40
\ 00000032 2870 STRB R0,[R5, #+0]
151 return ((OS_EVENT *)0);
\ 00000034 0020 MOVS R0,#+0
\ 00000036 23E0 B ??OSMutexCreate_2
152 }
153 OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the table entry */
\ ??OSMutexCreate_4:
\ 00000038 A100 LSLS R1,R4,#+2
\ 0000003A 0123 MOVS R3,#+1
\ 0000003C 5350 STR R3,[R2, R1]
154 pevent = OSEventFreeList; /* Get next free event control block */
\ 0000003E .... LDR R1,??DataTable12 ;; OSEventFreeList
\ 00000040 0E68 LDR R6,[R1, #+0]
155 if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */
\ 00000042 002E CMP R6,#+0
\ 00000044 06D1 BNE ??OSMutexCreate_5
156 OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */
\ 00000046 A100 LSLS R1,R4,#+2
\ 00000048 0023 MOVS R3,#+0
\ 0000004A 5350 STR R3,[R2, R1]
157 OS_EXIT_CRITICAL();
\ 0000004C ........ _BLF OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
158 *err = OS_ERR_PEVENT_NULL; /* No more event control blocks */
\ 00000050 0420 MOVS R0,#+4
\ 00000052 DDE7 B.N ??OSMutexCreate_1
159 return (pevent);
160 }
161 OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */
\ ??OSMutexCreate_5:
\ 00000054 7268 LDR R2,[R6, #+4]
\ 00000056 0A60 STR R2,[R1, #+0]
162 OS_EXIT_CRITICAL();
\ 00000058 ........ _BLF OS_CPU_SR_Restore,??OS_CPU_SR_Restore??rT
163 pevent->OSEventType = OS_EVENT_TYPE_MUTEX;
\ 0000005C 0420 MOVS R0,#+4
\ 0000005E 3070 STRB R0,[R6, #+0]
164 pevent->OSEventCnt = ((INT16U)prio << 8) | OS_MUTEX_AVAILABLE; /* Resource is available */
\ 00000060 2002 LSLS R0,R4,#+8
\ 00000062 FF21 MOVS R1,#+255
\ 00000064 0143 ORRS R1,R1,R0
\ 00000066 7180 STRH R1,[R6, #+2]
165 pevent->OSEventPtr = (void *)0; /* No task owning the mutex */
\ 00000068 0020 MOVS R0,#+0
\ 0000006A 7060 STR R0,[R6, #+4]
166 #if OS_EVENT_NAME_SIZE > 1
167 pevent->OSEventName[0] = '?';
\ 0000006C 3F20 MOVS R0,#+63
\ 0000006E 3074 STRB R0,[R6, #+16]
168 pevent->OSEventName[1] = OS_ASCII_NUL;
\ 00000070 0020 MOVS R0,#+0
\ 00000072 7074 STRB R0,[R6, #+17]
169 #endif
170 OS_EventWaitListInit(pevent);
\ 00000074 3000 MOVS R0,R6
\ 00000076 ........ _BLF OS_EventWaitListInit,??OS_EventWaitListInit??rT
171 *err = OS_NO_ERR;
\ 0000007A 0020 MOVS R0,#+0
\ 0000007C 2870 STRB R0,[R5, #+0]
172 return (pevent);
\ 0000007E 3000 MOVS R0,R6
\ ??OSMutexCreate_2:
\ 00000080 70BC POP {R4-R6}
\ 00000082 02BC POP {R1}
\ 00000084 0847 BX R1 ;; return
173 }
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
\ In segment CODE, align 4, keep-with-next
210 OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
211 {
\ OSMutexDel:
\ 00000000 F2B5 PUSH {R1,R4-R7,LR}
\ 00000002 0400 MOVS R4,R0
\ 00000004 1500 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 ... */
\ 00000006 .... LDR R0,??DataTable6 ;; OSIntNesting
\ 00000008 0078 LDRB R0,[R0, #+0]
\ 0000000A 0028 CMP R0,#+0
\ 0000000C 01D0 BEQ ??OSMutexDel_0
220 *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
\ 0000000E 8C20 MOVS R0,#+140
\ 00000010 5FE0 B.N ??OSMutexDel_1
221 return (pevent);
222 }
223 #if OS_ARG_CHK_EN > 0
224 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
\ ??OSMutexDel_0:
\ 00000012 002C CMP R4,#+0
\ 00000014 03D1 BNE ??OSMutexDel_2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -