📄 os_sem.lst
字号:
109:os/source/os_sem.c **** /*
110:os/source/os_sem.c **** ***************************************************************************************************
111:os/source/os_sem.c **** * DELETE A SEMAPHORE
112:os/source/os_sem.c **** *
113:os/source/os_sem.c **** * Description: This function deletes a semaphore and readies all tasks pending on the semaphore.
114:os/source/os_sem.c **** *
115:os/source/os_sem.c **** * Arguments : pevent is a pointer to the event control block associated with the desired
116:os/source/os_sem.c **** * semaphore.
117:os/source/os_sem.c **** *
118:os/source/os_sem.c **** * opt determines delete options as follows:
119:os/source/os_sem.c **** * opt == OS_DEL_NO_PEND Delete semaphore ONLY if no task pending
120:os/source/os_sem.c **** * opt == OS_DEL_ALWAYS Deletes the semaphore even if tasks are waitin
121:os/source/os_sem.c **** * In this case, all the tasks pending will be re
122:os/source/os_sem.c **** *
123:os/source/os_sem.c **** * err is a pointer to an error code that can contain one of the following va
124:os/source/os_sem.c **** * OS_NO_ERR The call was successful and the semaphore was
125:os/source/os_sem.c **** * OS_ERR_DEL_ISR If you attempted to delete the semaphore from
126:os/source/os_sem.c **** * OS_ERR_INVALID_OPT An invalid option was specified
127:os/source/os_sem.c **** * OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphor
128:os/source/os_sem.c **** * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
129:os/source/os_sem.c **** * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
130:os/source/os_sem.c **** *
131:os/source/os_sem.c **** * Returns : pevent upon error
132:os/source/os_sem.c **** * (OS_EVENT *)0 if the semaphore was successfully deleted.
133:os/source/os_sem.c **** *
134:os/source/os_sem.c **** * Note(s) : 1) This function must be used with care. Tasks that would normally expect the prese
135:os/source/os_sem.c **** * the semaphore MUST check the return code of OSSemPend().
136:os/source/os_sem.c **** * 2) OSSemAccept() callers will not know that the intended semaphore has been deleted
137:os/source/os_sem.c **** * they check 'pevent' to see that it's a NULL pointer.
138:os/source/os_sem.c **** * 3) This call can potentially disable interrupts for a long time. The interrupt disa
139:os/source/os_sem.c **** * time is directly proportional to the number of tasks waiting on the semaphore.
140:os/source/os_sem.c **** * 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful i
141:os/source/os_sem.c **** * applications where the semaphore is used for mutual exclusion because the resourc
142:os/source/os_sem.c **** * will no longer be guarded by the semaphore.
143:os/source/os_sem.c **** ***************************************************************************************************
144:os/source/os_sem.c **** */
145:os/source/os_sem.c ****
146:os/source/os_sem.c **** #if OS_SEM_DEL_EN > 0
147:os/source/os_sem.c **** OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
148:os/source/os_sem.c **** {
149:os/source/os_sem.c **** #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status regis
150:os/source/os_sem.c **** OS_CPU_SR cpu_sr;
151:os/source/os_sem.c **** #endif
152:os/source/os_sem.c **** BOOLEAN tasks_waiting;
153:os/source/os_sem.c ****
154:os/source/os_sem.c ****
155:os/source/os_sem.c **** if (OSIntNesting > 0) { /* See if called from ISR ...
156:os/source/os_sem.c **** *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR
157:os/source/os_sem.c **** return (pevent);
158:os/source/os_sem.c **** }
159:os/source/os_sem.c **** #if OS_ARG_CHK_EN > 0
160:os/source/os_sem.c **** if (pevent == (OS_EVENT *)0) { /* Validate 'pevent'
161:os/source/os_sem.c **** *err = OS_ERR_PEVENT_NULL;
162:os/source/os_sem.c **** return (pevent);
163:os/source/os_sem.c **** }
164:os/source/os_sem.c **** if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type
165:os/source/os_sem.c **** *err = OS_ERR_EVENT_TYPE;
166:os/source/os_sem.c **** return (pevent);
167:os/source/os_sem.c **** }
168:os/source/os_sem.c **** #endif
169:os/source/os_sem.c **** OS_ENTER_CRITICAL();
170:os/source/os_sem.c **** if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on semaphore
171:os/source/os_sem.c **** tasks_waiting = TRUE; /* Yes
172:os/source/os_sem.c **** } else {
173:os/source/os_sem.c **** tasks_waiting = FALSE; /* No
174:os/source/os_sem.c **** }
175:os/source/os_sem.c **** switch (opt) {
176:os/source/os_sem.c **** case OS_DEL_NO_PEND: /* Delete semaphore only if no task wait
177:os/source/os_sem.c **** if (tasks_waiting == FALSE) {
178:os/source/os_sem.c **** pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
179:os/source/os_sem.c **** pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free li
180:os/source/os_sem.c **** OSEventFreeList = pevent; /* Get next free event control block
181:os/source/os_sem.c **** OS_EXIT_CRITICAL();
182:os/source/os_sem.c **** *err = OS_NO_ERR;
183:os/source/os_sem.c **** return ((OS_EVENT *)0); /* Semaphore has been deleted
184:os/source/os_sem.c **** } else {
185:os/source/os_sem.c **** OS_EXIT_CRITICAL();
186:os/source/os_sem.c **** *err = OS_ERR_TASK_WAITING;
187:os/source/os_sem.c **** return (pevent);
188:os/source/os_sem.c **** }
189:os/source/os_sem.c ****
190:os/source/os_sem.c **** case OS_DEL_ALWAYS: /* Always delete the semaphore
191:os/source/os_sem.c **** while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for semaphore
192:os/source/os_sem.c **** OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);
193:os/source/os_sem.c **** }
194:os/source/os_sem.c **** pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
195:os/source/os_sem.c **** pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free li
196:os/source/os_sem.c **** OSEventFreeList = pevent; /* Get next free event control block
197:os/source/os_sem.c **** OS_EXIT_CRITICAL();
198:os/source/os_sem.c **** if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiti
199:os/source/os_sem.c **** OS_Sched(); /* Find highest priority task ready to r
200:os/source/os_sem.c **** }
201:os/source/os_sem.c **** *err = OS_NO_ERR;
202:os/source/os_sem.c **** return ((OS_EVENT *)0); /* Semaphore has been deleted
203:os/source/os_sem.c ****
204:os/source/os_sem.c **** default:
205:os/source/os_sem.c **** OS_EXIT_CRITICAL();
206:os/source/os_sem.c **** *err = OS_ERR_INVALID_OPT;
207:os/source/os_sem.c **** return (pevent);
208:os/source/os_sem.c **** }
209:os/source/os_sem.c **** }
210:os/source/os_sem.c **** #endif
211:os/source/os_sem.c ****
212:os/source/os_sem.c **** /*$PAGE*/
213:os/source/os_sem.c **** /*
214:os/source/os_sem.c **** ***************************************************************************************************
215:os/source/os_sem.c **** * PEND ON SEMAPHORE
216:os/source/os_sem.c **** *
217:os/source/os_sem.c **** * Description: This function waits for a semaphore.
218:os/source/os_sem.c **** *
219:os/source/os_sem.c **** * Arguments : pevent is a pointer to the event control block associated with the desired
220:os/source/os_sem.c **** * semaphore.
221:os/source/os_sem.c **** *
222:os/source/os_sem.c **** * timeout is an optional timeout period (in clock ticks). If non-zero, your tas
223:os/source/os_sem.c **** * wait for the resource up to the amount of time specified by this argum
224:os/source/os_sem.c **** * If you specify 0, however, your task will wait forever at the specifie
225:os/source/os_sem.c **** * semaphore or, until the resource becomes available (or the event occur
226:os/source/os_sem.c **** *
227:os/source/os_sem.c **** * err is a pointer to where an error message will be deposited. Possible er
228:os/source/os_sem.c **** * messages are:
229:os/source/os_sem.c **** *
230:os/source/os_sem.c **** * OS_NO_ERR The call was successful and your task owns the res
231:os/source/os_sem.c **** * or, the event you are waiting for occurred.
232:os/source/os_sem.c **** * OS_TIMEOUT The semaphore was not received within the specifie
233:os/source/os_sem.c **** * timeout.
234:os/source/os_sem.c **** * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
235:os/source/os_sem.c **** * OS_ERR_PEND_ISR If you called this function from an ISR and the re
236:os/source/os_sem.c **** * would lead to a suspension.
237:os/source/os_sem.c **** * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
238:os/source/os_sem.c **** *
239:os/source/os_sem.c **** * Returns : none
240:os/source/os_sem.c **** ***************************************************************************************************
241:os/source/os_sem.c **** */
242:os/source/os_sem.c ****
243:os/source/os_sem.c **** void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
244:os/source/os_sem.c **** {
261 .LM20:
262 /* prologue: frame size=0 */
263 0062 FF92 push r15
264 0064 0F93 push r16
265 0066 1F93 push r17
266 0068 CF93 push r28
267 006a DF93 push r29
268 /* prologue end (size=5) */
269 006c EC01 movw r28,r24
270 006e 8A01 movw r16,r20
245:os/source/os_sem.c **** #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register
246:os/source/os_sem.c **** OS_CPU_SR cpu_sr;
247:os/source/os_sem.c **** #endif
248:os/source/os_sem.c ****
249:os/source/os_sem.c ****
250:os/source/os_sem.c **** if (OSIntNesting > 0) { /* See if called from ISR ...
272 .LM21:
273 0070 F090 0000 lds r15,OSIntNesting
274 0074 FF20 tst r15
275 0076 11F0 breq .L8
251:os/source/os_sem.c **** *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR
277 .LM22:
278 0078 82E0 ldi r24,lo8(2)
279 007a 2DC0 rjmp .L12
280 .L8:
252:os/source/os_sem.c **** return;
253:os/source/os_sem.c **** }
254:os/source/os_sem.c **** #if OS_ARG_CHK_EN > 0
255:os/source/os_sem.c **** if (pevent == (OS_EVENT *)0) { /* Validate 'pevent'
256:os/source/os_sem.c **** *err = OS_ERR_PEVENT_NULL;
257:os/source/os_sem.c **** return;
258:os/source/os_sem.c **** }
259:os/source/os_sem.c **** if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type
260:os/source/os_sem.c **** *err = OS_ERR_EVENT_TYPE;
261:os/source/os_sem.c **** return;
262:os/source/os_sem.c **** }
263:os/source/os_sem.c **** #endif
264:os/source/os_sem.c **** OS_ENTER_CRITICAL();
282 .LM23:
283 /* #APP */
284 007c F894 cli
265:os/source/os_sem.c **** if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ..
286 .LM24:
287 /* #NOAPP */
288 007e 8A81 ldd r24,Y+2
289 0080 9B81 ldd r25,Y+3
290 0082 0097 sbiw r24,0
291 0084 21F0 breq .L9
266:os/source/os_sem.c **** pevent->OSEventCnt--; /* ... decrement semaphore only if positive.
293 .LM25:
294 0086 0197 sbiw r24,1
295 0088 9B83 std Y+3,r25
296 008a 8A83 std Y+2,r24
297 008c 29C0 rjmp .L11
298 .L9:
267:os/source/os_sem.c **** OS_EXIT_CRITICAL();
268:os/source/os_sem.c **** *err = OS_NO_ERR;
269:os/source/os_sem.c **** return;
270:os/source/os_sem.c **** }
271:os/source/os_sem.c **** /* Otherwise, must wait until event occurs
272:os/source/os_sem.c **** OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore
300 .LM26:
301 008e E091 0000 lds r30,OSTCBCur
302 0092 F091 0000 lds r31,(OSTCBCur)+1
303 0096 808D ldd r24,Z+24
304 0098 8160 ori r24,lo8(1)
305 009a 808F std Z+24,r24
273:os/source/os_sem.c **** OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB
307 .LM27:
308 009c E091 0000 lds r30,OSTCBCur
309 00a0 F091 0000 lds r31,(OSTCBCur)+1
310 00a4 778B std Z+23,r23
311 00a6 668B std Z+22,r22
274:os/source/os_sem.c **** OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs
313 .LM28:
314 00a8 CE01 movw r24,r28
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -