📄 os_sem.lst
字号:
#endif
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
pevent->OSEventCnt = 0;
OSEventFreeList = pevent; /* Get next free event control block */
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */
} else {
OS_EXIT_CRITICAL();
*perr = OS_ERR_TASK_WAITING;
pevent_return = pevent;
}
break;
case OS_DEL_ALWAYS: /* Always delete the semaphore */
while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for semaphore */
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK);
}
#if OS_EVENT_NAME_SIZE > 1
pevent->OSEventName[0] = '?'; /* Unknown name */
pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
pevent->OSEventCnt = 0;
OSEventFreeList = pevent; /* Get next free event control block */
OS_EXIT_CRITICAL();
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */
OS_Sched(); /* Find highest priority task ready to run */
}
*perr = OS_ERR_NONE;
pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */
break;
default:
OS_EXIT_CRITICAL();
C51 COMPILER V8.17 OS_SEM 03/26/2009 14:24:25 PAGE 5
*perr = OS_ERR_INVALID_OPT;
pevent_return = pevent;
break;
}
return (pevent_return);
}
#endif
247
248 /*$PAGE*/
249 /*
250 *********************************************************************************************************
251 * PEND ON SEMAPHORE
252 *
253 * Description: This function waits for a semaphore.
254 *
255 * Arguments : pevent is a pointer to the event control block associated with the desired
256 * semaphore.
257 *
258 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
259 * wait for the resource up to the amount of time specified by this argument.
260 * If you specify 0, however, your task will wait forever at the specified
261 * semaphore or, until the resource becomes available (or the event occurs).
262 *
263 * perr is a pointer to where an error message will be deposited. Possible error
264 * messages are:
265 *
266 * OS_ERR_NONE The call was successful and your task owns the resource
267 * or, the event you are waiting for occurred.
268 * OS_ERR_TIMEOUT The semaphore was not received within the specified
269 * 'timeout'.
270 * OS_ERR_PEND_ABORT The wait on the semaphore was aborted.
271 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
272 * OS_ERR_PEND_ISR If you called this function from an ISR and the result
273 * would lead to a suspension.
274 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
275 * OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked
276 *
277 * Returns : none
278 *********************************************************************************************************
279 */
280 /*$PAGE*/
281 void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) reentrant
282 {
283 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
286 1
287 1
288 1
289 1 #if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return;
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return;
}
#endif
298 1 if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
299 2 *perr = OS_ERR_EVENT_TYPE;
300 2 return;
301 2 }
C51 COMPILER V8.17 OS_SEM 03/26/2009 14:24:25 PAGE 6
302 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
303 2 *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
304 2 return;
305 2 }
306 1 if (OSLockNesting > 0) { /* See if called with scheduler locked ... */
307 2 *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
308 2 return;
309 2 }
310 1 OS_ENTER_CRITICAL();
311 1 if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */
312 2 pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */
313 2 OS_EXIT_CRITICAL();
314 2 *perr = OS_ERR_NONE;
315 2 return;
316 2 }
317 1 /* Otherwise, must wait until event occurs */
318 1 OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */
319 1 OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
320 1 OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */
321 1 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
322 1 OS_EXIT_CRITICAL();
323 1 OS_Sched(); /* Find next highest priority task ready */
324 1 OS_ENTER_CRITICAL();
325 1 switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */
326 2 case OS_STAT_PEND_OK:
327 2 *perr = OS_ERR_NONE;
328 2 break;
329 2
330 2 case OS_STAT_PEND_ABORT:
331 2 *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */
332 2 break;
333 2
334 2 case OS_STAT_PEND_TO:
335 2 default:
336 2 OS_EventTaskRemove(OSTCBCur, pevent);
337 2 *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */
338 2 break;
339 2 }
340 1 OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */
341 1 OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */
342 1 OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */
343 1 #if (OS_EVENT_MULTI_EN > 0)
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
#endif
346 1 OS_EXIT_CRITICAL();
347 1 }
348
349 /*$PAGE*/
350 /*
351 *********************************************************************************************************
352 * ABORT WAITING ON A SEMAPHORE
353 *
354 * Description: This function aborts & readies any tasks currently waiting on a semaphore. This function
355 * should be used to fault-abort the wait on the semaphore, rather than to normally signal
356 * the semaphore via OSSemPost().
357 *
358 * Arguments : pevent is a pointer to the event control block associated with the desired
359 * semaphore.
360 *
361 * opt determines the type of ABORT performed:
362 * OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the
363 * semaphore
C51 COMPILER V8.17 OS_SEM 03/26/2009 14:24:25 PAGE 7
364 * OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the
365 * semaphore
366 *
367 * perr is a pointer to where an error message will be deposited. Possible error
368 * messages are:
369 *
370 * OS_ERR_NONE No tasks were waiting on the semaphore.
371 * OS_ERR_PEND_ABORT At least one task waiting on the semaphore was readied
372 * and informed of the aborted wait; check return value
373 * for the number of tasks whose wait on the semaphore
374 * was aborted.
375 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
376 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
377 *
378 * Returns : == 0 if no tasks were waiting on the semaphore, or upon error.
379 * > 0 if one or more tasks waiting on the semaphore are now readied and informed.
380 *********************************************************************************************************
381 */
382
383 #if OS_SEM_PEND_ABORT_EN > 0
INT8U OSSemPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) reentrant
{
INT8U nbr_tasks;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return (0);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return (0);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return (0);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) { /* See if any task waiting on semaphore? */
nbr_tasks = 0;
switch (opt) {
case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */
while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on semaphore */
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT);
nbr_tasks++;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -