📄 os_mutex.lst
字号:
125 * to use to reduce priority inversion.
126 *********************************************************************************************************
127 */
128
129 OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err)
130 {
\ 0062 0A12 PUSH R10
\ 0064 0B12 PUSH R11
\ 0066 0A4E MOV R14,R10
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 ... */
\ 0068 C2930000 CMP.B #0,&OSIntNesting
\ 006C 0524 JEQ (?0066)
138 *err = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */
\ 006E FA408D00 MOV.B #141,0(R10)
\ 0072 0000
139 return ((OS_EVENT *)0);
\ 0074 0C43 MOV #0,R12
140 }
\ 0076 3B3C JMP (?0073)
\ 0078 ?0066:
141 #if OS_ARG_CHK_EN > 0
142 if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */
\ 0078 7C900C00 CMP.B #12,R12
\ 007C 0528 JNC (?0068)
143 *err = OS_PRIO_INVALID;
\ 007E FA402A00 MOV.B #42,0(R10)
\ 0082 0000
144 return ((OS_EVENT *)0);
\ 0084 0C43 MOV #0,R12
145 }
\ 0086 333C JMP (?0073)
\ 0088 ?0068:
146 #endif
147 OS_ENTER_CRITICAL();
\ 0088 32C2 DINT
148 if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */
\ 008A 4D4C MOV.B R12,R13
\ 008C 0D5D ADD R13,R13
\ 008E 8D930000 CMP #0,OSTCBPrioTbl(R13)
\ 0092 0624 JEQ (?0070)
149 OS_EXIT_CRITICAL(); /* Task already exist at priority ... */
\ 0094 32D2 EINT
150 *err = OS_PRIO_EXIST; /* ... inheritance priority */
\ 0096 FA402800 MOV.B #40,0(R10)
\ 009A 0000
151 return ((OS_EVENT *)0);
\ 009C 0C43 MOV #0,R12
152 }
\ 009E 273C JMP (?0073)
\ 00A0 ?0070:
153 OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the table entry */
\ 00A0 4D4C MOV.B R12,R13
\ 00A2 0D5D ADD R13,R13
\ 00A4 9D430000 MOV #1,OSTCBPrioTbl(R13)
154 pevent = OSEventFreeList; /* Get next free event control block */
\ 00A8 1B420000 MOV &OSEventFreeList,R11
155 if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */
\ 00AC 0B93 CMP #0,R11
\ 00AE 0920 JNE (?0072)
156 OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */
\ 00B0 7CF3 AND.B #-1,R12
\ 00B2 0C5C ADD R12,R12
\ 00B4 8C430000 MOV #0,OSTCBPrioTbl(R12)
157 OS_EXIT_CRITICAL();
\ 00B8 32D2 EINT
158 *err = OS_ERR_PEVENT_NULL; /* No more event control blocks */
\ 00BA EA420000 MOV.B #4,0(R10)
159 return (pevent);
\ 00BE 0C43 MOV #0,R12
160 }
\ 00C0 163C JMP (?0073)
\ 00C2 ?0072:
161 OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */
\ 00C2 1D420000 MOV &OSEventFreeList,R13
\ 00C6 924D0400 MOV 4(R13),&OSEventFreeList
\ 00CA 0000
162 OS_EXIT_CRITICAL();
\ 00CC 32D2 EINT
163 pevent->OSEventType = OS_EVENT_TYPE_MUTEX;
\ 00CE EB420000 MOV.B #4,0(R11)
164 pevent->OSEventCnt = (prio << 8) | OS_MUTEX_AVAILABLE;/* Resource is available */
\ 00D2 7CF3 AND.B #-1,R12
\ 00D4 8C10 SWPB R12
\ 00D6 3CD0FF00 BIS #255,R12
\ 00DA 8B4C0200 MOV R12,2(R11)
165 pevent->OSEventPtr = (void *)0; /* No task owning the mutex */
\ 00DE 8B430400 MOV #0,4(R11)
166 OS_EventWaitListInit(pevent);
\ 00E2 0C4B MOV R11,R12
\ 00E4 B0120000 CALL #OS_EventWaitListInit
167 *err = OS_NO_ERR;
\ 00E8 CA430000 MOV.B #0,0(R10)
168 return (pevent);
\ 00EC 0C4B MOV R11,R12
169 }
\ 00EE ?0073:
\ 00EE 3B41 POP R11
\ 00F0 3A41 POP R10
\ 00F2 3041 RET
\ 00F4 OSMutexDel:
170
171 /*$PAGE*/
172 /*
173 *********************************************************************************************************
174 * DELETE A MUTEX
175 *
176 * Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it.
177 *
178 * Arguments : pevent is a pointer to the event control block associated with the desired mutex.
179 *
180 * opt determines delete options as follows:
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)
207 {
\ 00F4 0A12 PUSH R10
\ 00F6 0B12 PUSH R11
\ 00F8 0812 PUSH R8
\ 00FA 0B4C MOV R12,R11
\ 00FC 18410800 MOV 8(SP),R8
208 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
209 OS_CPU_SR cpu_sr;
210 #endif
211 BOOLEAN tasks_waiting;
212 INT8U pip;
213
214
215 if (OSIntNesting > 0) { /* See if called from ISR ... */
\ 0100 C2930000 CMP.B #0,&OSIntNesting
\ 0104 0524 JEQ (?0075)
216 *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
\ 0106 F8408C00 MOV.B #140,0(R8)
\ 010A 0000
217 return (pevent);
\ 010C 0C4B MOV R11,R12
218 }
\ 010E 5A3C JMP (?0094)
\ 0110 ?0075:
219 #if OS_ARG_CHK_EN > 0
220 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
\ 0110 0B93 CMP #0,R11
\ 0112 0420 JNE (?0077)
221 *err = OS_ERR_PEVENT_NULL;
\ 0114 E8420000 MOV.B #4,0(R8)
222 return ((OS_EVENT *)0);
\ 0118 0C43 MOV #0,R12
223 }
\ 011A 543C JMP (?0094)
\ 011C ?0077:
224 if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
\ 011C 6C42 MOV.B #4,R12
\ 011E 6C9B CMP.B @R11,R12
\ 0120 0424 JEQ (?0079)
225 *err = OS_ERR_EVENT_TYPE;
\ 0122 D8430000 MOV.B #1,0(R8)
226 return (pevent);
\ 0126 0C4B MOV R11,R12
227 }
\ 0128 4D3C JMP (?0094)
\ 012A ?0079:
228 #endif
229 OS_ENTER_CRITICAL();
\ 012A 32C2 DINT
230 if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on mutex */
\ 012C CB930100 CMP.B #0,1(R11)
\ 0130 0224 JEQ (?0081)
231 tasks_waiting = TRUE; /* Yes */
\ 0132 5A43 MOV.B #1,R10
232 } else {
\ 0134 013C JMP (?0082)
\ 0136 ?0081:
233 tasks_waiting = FALSE; /* No */
\ 0136 4A43 MOV.B #0,R10
\ 0138 ?0082:
234 }
235 switch (opt) {
\ 0138 4E83 SUB.B #0,R14
\ 013A 0324 JEQ (?0084)
\ 013C 5E83 SUB.B #1,R14
\ 013E 1B24 JEQ (?0087)
\ 0140 3C3C JMP (?0093)
\ 0142 ?0084:
236 case OS_DEL_NO_PEND: /* Delete mutex only if no task waiting */
237 if (tasks_waiting == FALSE) {
\ 0142 4A93 CMP.B #0,R10
\ 0144 1320 JNE (?0086)
238 pip = (INT8U)(pevent->OSEventCnt >> 8);
\ 0146 1C4B0200 MOV 2(R11),R12
\ 014A 8C10 SWPB R12
\ 014C 7CF3 AND.B #-1,R12
239 OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */
\ 014E 0C5C ADD R12,R12
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -