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

  1. Semaphores must be created before they are used.

Example Usage

OSSemPend() 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" */
                  :
                  :
              }
          }