OSSemPend
Description
Used when a task wants exclusive access to a resource, needs to synchronize its activities with an ISR or task, or is waiting until an event occurs.
When the semaphore is used for resource sharing, if a task calls OSSemPend()
and the value of the semaphore is greater than 0, OSSemPend()
decrements the semaphore and returns to its caller. However, if the value of the semaphore is 0, OSSemPend()
places the calling task in the waiting list for the semaphore. The task waits until the owner of the semaphore releases the semaphore by calling OSSemPost()
, or the specified timeout expires. If the semaphore is signaled before the timeout expires, µC/OS-III resumes the highest-priority task waiting for the semaphore.
When the semaphore is used as a signaling mechanism, the calling task waits until a task or an ISR signals the semaphore by calling OSSemPost()
, or the specified timeout expires.
A pended task that has been suspended with OSTaskSuspend()
can obtain the semaphore. However, the task remains suspended until it is resumed by calling OSTaskResume()
.
OSSemPend()
also returns if the pend is aborted or, the semaphore is deleted.
Files
os.h/os_sem.c
Prototype
OS_SEM_CTR OSSemPend (OS_SEM *p_sem, OS_TICK timeout, OS_OPT opt, CPU_TS *p_ts, OS_ERR *p_err)
Arguments
p_sem
is a pointer to the semaphore.
timeout
allows the task to resume execution if a semaphore is not posted within the specified number of clock ticks. A timeout value of 0 indicates that the task waits forever for the semaphore. The timeout value is not synchronized with the clock tick. The timeout count begins decrementing on the next clock tick, which could potentially occur immediately.
opt
specifies whether the call is to block if the semaphore is not available, or not block.
OS_OPT_PEND_BLOCKING
to block the caller until the semaphore is available or a timeout occurs.
OS_OPT_PEND_NON_BLOCKING
If the semaphore is not available, OSSemPend()
will not block but return to the caller with an appropriate error code.
p_ts
is a pointer to a variable that will receive a timestamp of when the semaphore was posted, pend aborted, or deleted. Passing a NULL
pointer is valid and indicates that a timestamp is not required.
A timestamp is useful when the task must know when the semaphore was posted or, how long it took for the task to resume after the semaphore was posted. In the latter case, call OS_TS_GET()
and compute the difference between the current value of the timestamp and *p_ts
. In other words:
delta = OS_TS_GET() - *p_ts;
p_err
is a pointer to a variable used to hold an error code:
OS_ERR_NONE
If the semaphore is available.
OS_ERR_OBJ_DEL
If the semaphore was deleted.
OS_ERR_OBJ_PTR_NULL
If OS_CFG_ARG_CHK_EN
is set to DEF_ENABLED
in os_cfg.h
: if p_sem
is a NULL
pointer.
OS_ERR_OBJ_TYPE
If OS_CFG_OBJ_TYPE_CHK_EN
is set to DEF_ENABLED
in os_cfg.h
: if p_sem
is not pointing to a semaphore.
OS_ERR_OPT_INVALID
If OS_CFG_ARG_CHK_EN
is set to DEF_ENABLED
in os_cfg.h
: if opt
is not OS_OPT_PEND_NON_BLOCKING or
OS_OPT_PEND_BLOCKING
.
OS_ERR_OS_NOT_RUNNING
If OS_CFG_INVALID_OS_CALLS_CHK_EN
is set to DEF_ENABLED
in os_cfg.h
: if µC/OS-III is not running yet.
OS_ERR_PEND_ABORT
if
the pend was aborted
OS_ERR_PEND_ISR
If OS_CFG_CALLED_FROM_ISR_CHK_EN
set to DEF_ENABLED
in os_cfg.h
: if
this function is called from an ISR.
OS_ERR_PEND_WOULD_BLOCK
if
this function is called as specified OS_OPT_PEND_NON_BLOCKING
, and the semaphore was not available.
OS_ERR_SCHED_LOCKED
If calling this function when the scheduler is locked.
OS_ERR_STATUS_INVALID
If the pend status has an invalid value.
OS_ERR_TIMEOUT
If the semaphore is not signaled within the specified timeout.
Returned Value
The new value of the semaphore count.
Required Configuration
OS_CFG_SEM_EN
must be enabled in os_cfg.h
. Refer to µC-OS-III Configuration Manual.
Callers
Application.
Notes/Warnings
- Semaphores must be created before they are used.
Example Usage
OS_SEM SwSem; void DispTask (void *p_arg) { OS_ERR err; CPU_TS ts; OS_SEM_CTR ctr; (void)&p_arg; while (DEF_ON) { : : ctr = OSSemPend(&SwSem, 0, OS_OPT_PEND_BLOCKING, &ts, &err); /* Check "err" */ : : } }