📄 os_sem.lst
字号:
\ 0068 OSSemDel:
108
109 /*$PAGE*/
110 /*
111 *********************************************************************************************************
112 * DELETE A SEMAPHORE
113 *
114 * Description: This function deletes a semaphore and readies all tasks pending on the semaphore.
115 *
116 * Arguments : pevent is a pointer to the event control block associated with the desired
117 * semaphore.
118 *
119 * opt determines delete options as follows:
120 * opt == OS_DEL_NO_PEND Delete semaphore ONLY if no task pending
121 * opt == OS_DEL_ALWAYS Deletes the semaphore even if tasks are waiting.
122 * In this case, all the tasks pending will be readied.
123 *
124 * err is a pointer to an error code that can contain one of the following values:
125 * OS_NO_ERR The call was successful and the semaphore was deleted
126 * OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR
127 * OS_ERR_INVALID_OPT An invalid option was specified
128 * OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore
129 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
130 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
131 *
132 * Returns : pevent upon error
133 * (OS_EVENT *)0 if the semaphore was successfully deleted.
134 *
135 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
136 * the semaphore MUST check the return code of OSSemPend().
137 * 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless
138 * they check 'pevent' to see that it's a NULL pointer.
139 * 3) This call can potentially disable interrupts for a long time. The interrupt disable
140 * time is directly proportional to the number of tasks waiting on the semaphore.
141 * 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in
142 * applications where the semaphore is used for mutual exclusion because the resource(s)
143 * will no longer be guarded by the semaphore.
144 *********************************************************************************************************
145 */
146
147 #if OS_SEM_DEL_EN > 0
148 OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
149 {
\ 0068 0A12 PUSH R10
\ 006A 0B12 PUSH R11
\ 006C 0812 PUSH R8
\ 006E 0B4C MOV R12,R11
\ 0070 18410800 MOV 8(SP),R8
150 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
151 OS_CPU_SR cpu_sr;
152 #endif
153 BOOLEAN tasks_waiting;
154
155
156 if (OSIntNesting > 0) { /* See if called from ISR ... */
\ 0074 C2930000 CMP.B #0,&OSIntNesting
\ 0078 0524 JEQ (?0071)
157 *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
\ 007A F8408C00 MOV.B #140,0(R8)
\ 007E 0000
158 return (pevent);
\ 0080 0C4B MOV R11,R12
159 }
\ 0082 4C3C JMP (?0090)
\ 0084 ?0071:
160 #if OS_ARG_CHK_EN > 0
161 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
\ 0084 0B93 CMP #0,R11
\ 0086 0420 JNE (?0073)
162 *err = OS_ERR_PEVENT_NULL;
\ 0088 E8420000 MOV.B #4,0(R8)
163 return (pevent);
\ 008C 0C43 MOV #0,R12
164 }
\ 008E 463C JMP (?0090)
\ 0090 ?0073:
165 if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
\ 0090 7C400300 MOV.B #3,R12
\ 0094 6C9B CMP.B @R11,R12
\ 0096 0424 JEQ (?0075)
166 *err = OS_ERR_EVENT_TYPE;
\ 0098 D8430000 MOV.B #1,0(R8)
167 return (pevent);
\ 009C 0C4B MOV R11,R12
168 }
\ 009E 3E3C JMP (?0090)
\ 00A0 ?0075:
169 #endif
170 OS_ENTER_CRITICAL();
\ 00A0 32C2 DINT
171 if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on semaphore */
\ 00A2 CB930100 CMP.B #0,1(R11)
\ 00A6 0224 JEQ (?0077)
172 tasks_waiting = TRUE; /* Yes */
\ 00A8 5A43 MOV.B #1,R10
173 } else {
\ 00AA 013C JMP (?0078)
\ 00AC ?0077:
174 tasks_waiting = FALSE; /* No */
\ 00AC 4A43 MOV.B #0,R10
\ 00AE ?0078:
175 }
176 switch (opt) {
\ 00AE 4E83 SUB.B #0,R14
\ 00B0 0324 JEQ (?0080)
\ 00B2 5E83 SUB.B #1,R14
\ 00B4 1424 JEQ (?0083)
\ 00B6 2D3C JMP (?0089)
\ 00B8 ?0080:
177 case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */
178 if (tasks_waiting == FALSE) {
\ 00B8 4A93 CMP.B #0,R10
\ 00BA 0C20 JNE (?0082)
179 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
\ 00BC CB430000 MOV.B #0,0(R11)
180 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
\ 00C0 9B420000 MOV &OSEventFreeList,4(R11)
\ 00C4 0400
181 OSEventFreeList = pevent; /* Get next free event control block */
\ 00C6 824B0000 MOV R11,&OSEventFreeList
182 OS_EXIT_CRITICAL();
\ 00CA 32D2 EINT
183 *err = OS_NO_ERR;
\ 00CC C8430000 MOV.B #0,0(R8)
184 return ((OS_EVENT *)0); /* Semaphore has been deleted */
\ 00D0 0C43 MOV #0,R12
185 } else {
\ 00D2 243C JMP (?0090)
\ 00D4 ?0082:
186 OS_EXIT_CRITICAL();
\ 00D4 32D2 EINT
187 *err = OS_ERR_TASK_WAITING;
\ 00D6 F8420000 MOV.B #8,0(R8)
188 return (pevent);
\ 00DA 0C4B MOV R11,R12
189 }
\ 00DC 1F3C JMP (?0090)
\ 00DE ?0083:
190
191 case OS_DEL_ALWAYS: /* Always delete the semaphore */
192 while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for semaphore */
\ 00DE CB930100 CMP.B #0,1(R11)
\ 00E2 0724 JEQ (?0084)
193 OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);
\ 00E4 5312 PUSH.B #1
\ 00E6 0E43 MOV #0,R14
\ 00E8 0C4B MOV R11,R12
\ 00EA B0120000 CALL #OS_EventTaskRdy
\ 00EE 2153 ADD #2,SP
\ 00F0 F63F JMP (?0083)
\ 00F2 ?0084:
194 }
195 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
\ 00F2 CB430000 MOV.B #0,0(R11)
196 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
\ 00F6 9B420000 MOV &OSEventFreeList,4(R11)
\ 00FA 0400
197 OSEventFreeList = pevent; /* Get next free event control block */
\ 00FC 824B0000 MOV R11,&OSEventFreeList
198 OS_EXIT_CRITICAL();
\ 0100 32D2 EINT
199 if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
\ 0102 5A93 CMP.B #1,R10
\ 0104 0220 JNE (?0088)
200 OS_Sched(); /* Find highest priority task ready to run */
\ 0106 B0120000 CALL #OS_Sched
\ 010A ?0088:
201 }
202 *err = OS_NO_ERR;
\ 010A C8430000 MOV.B #0,0(R8)
203 return ((OS_EVENT *)0); /* Semaphore has been deleted */
\ 010E 0C43 MOV #0,R12
204
205 default:
\ 0110 053C JMP (?0090)
\ 0112 ?0089:
206 OS_EXIT_CRITICAL();
\ 0112 32D2 EINT
207 *err = OS_ERR_INVALID_OPT;
\ 0114 F8400700 MOV.B #7,0(R8)
\ 0118 0000
208 return (pevent);
\ 011A 0C4B MOV R11,R12
209 }
\ 011C ?0090:
\ 011C 3841 POP R8
\ 011E 3B41 POP R11
\ 0120 3A41 POP R10
\ 0122 3041 RET
\ 0124 ?0079:
210 }
\ 0124 OSSemPend:
211 #endif
212
213 /*$PAGE*/
214 /*
215 *********************************************************************************************************
216 * PEND ON SEMAPHORE
217 *
218 * Description: This function waits for a semaphore.
219 *
220 * Arguments : pevent is a pointer to the event control block associated with the desired
221 * semaphore.
222 *
223 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
224 * wait for the resource up to the amount of time specified by this argument.
225 * If you specify 0, however, your task will wait forever at the specified
226 * semaphore or, until the resource becomes available (or the event occurs).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -