Semaphore

Features Supported

  • APIs to create binary and counting semaphore’s

  • APIs to create mutual exclusion semaphore

  • Nesting of mutual exclusion semaphores

  • Priority inheritance when supported by the underlying OS

Features NOT Supported

NA

Important Usage Guidelines

  • SemaphoreP_post can be called from ISR as well as task context

  • SemaphoreP_pend should not be called within ISR context. It can be called from task context.

  • SemaphoreP_pend will block until the user specific timeout ticks have expired or semaphore is acquired.

    • In baremetal case, there is only a single main task and that will block or spin until the ticks have elasped or semaphore acquire is successful

    • In RTOS case, the current executing task will ‘pend’ and schedular will switch to another ready task until the ticks have elasped or semaphore acquire is successful

    • In both cases ISR’s are still active

  • There is nothing like priority inheritance in NO RTOS mode

Example Usage

Include the below file to access the APIs,


//! [include]
#include <kernel/dpl/SemaphoreP.h>
#include <kernel/dpl/ClockP.h>
//! [include]

//! [define]
/* semaphore objects, typically these are global's */
SemaphoreP_Object gBinarySem;
SemaphoreP_Object gMutexSem;

Example usage to define a semaphore:


/* resource to protect with counting semaphore */
#define NUM_RESOURCES   (10u)
uint32_t gResource[NUM_RESOURCES];

//! [define]

//! [callback]
/* peripheral ISR which post's the binary semaphore */
void myISR(void *args)
{
    SemaphoreP_post(&gBinarySem);
}
//! [callback]

Example usage to post a binary semaphore from an ISR:

void samples()
{
{
//! [mutex]
    SemaphoreP_constructMutex(&gMutexSem);

    /* wait forever for the mutex to be available, lock or enter the critical section */
    SemaphoreP_pend(&gMutexSem, SystemP_WAIT_FOREVER);

    /* mutual exclusion, critical section */

    /* unlock the mutex, exit critical section */
    SemaphoreP_post(&gMutexSem);
//! [mutex]

Example usage to create and use a mutex:

{
//! [binary]
    int32_t status;

    SemaphoreP_constructBinary(&gBinarySem, 0);

    // initialize peripheral
    // register myISR
    // enable peripheral

    /* wait for 10ms for the semaphore to be post by the peripheral */
    status = SemaphoreP_pend(&gBinarySem, ClockP_usecToTicks(10*1000));
    if(status==SystemP_SUCCESS)
    {

Example usage to create and use a binary semaphore with timeout:

    }
    else
    if(status==SystemP_TIMEOUT)
    {
        /* failed due to timeout */
    }
    else
    {
        /* other failure */
    }

//! [binary]
}
{

Example usage to create and use a counting semaphore:

    uint32_t resourceId = 0;

    SemaphoreP_constructCounting(&gCountingSem, NUM_RESOURCES, NUM_RESOURCES);

    /* wait for a resource to be available */
    SemaphoreP_pend(&gCountingSem, SystemP_WAIT_FOREVER);

    /* access the resource */

    /* release resoource */
    resourceId = (resourceId+1)%NUM_RESOURCES;
    SemaphoreP_post(&gCountingSem);

//! [counting]

API Reference

Defines

SemaphoreP_OBJECT_SIZE_MAX

Max size of semaphore object across no-RTOS and all OS’s.

Functions

int32_t SemaphoreP_constructMutex(SemaphoreP_Object *obj)

Create a mutex semaphore object.

Parameters:

obj – [out] created object

Returns:

SystemP_SUCCESS on success, SystemP_FAILURE on error

int32_t SemaphoreP_constructBinary(SemaphoreP_Object *obj, uint32_t initValue)

Create a binary semaphore object.

Parameters:
  • obj – [out] created object

  • initValue – [in] Initial value of the binary semaphore, MUST be 0 or 1

Returns:

SystemP_SUCCESS on success, SystemP_FAILURE on error

int32_t SemaphoreP_constructCounting(SemaphoreP_Object *obj, uint32_t initValue, uint32_t maxValue)

Create a counting semaphore object.

Parameters:
  • obj – [out] created object

  • initValue – [in] Initial value of the counting semaphore, MUST be between 0 .. maxValue

  • maxValue – [in] Maximum value of counting semaphore

Returns:

SystemP_SUCCESS on success, SystemP_FAILURE on error

void SemaphoreP_destruct(SemaphoreP_Object *obj)

Cleanup, delete, destruct a semaphore object.

Parameters:

obj – [in] semaphore object

void SemaphoreP_post(SemaphoreP_Object *obj)

Post a semaphore object or unlock a mutex.

Parameters:

obj – [in] semaphore object

int32_t SemaphoreP_pend(SemaphoreP_Object *obj, uint32_t timeToWaitInTicks)

Pend on a semaphore object or lock a mutex.

Parameters:
  • obj – [in] semaphore object

  • timeToWaitInTicks – [in] amount of time to block waiting for semaphore to be available, in units of system ticks (see KERNEL_DPL_CLOCK_PAGE)

Returns:

SystemP_SUCCESS on successful acquire of the semaphore

Returns:

SystemP_TIMEOUT on failure to acquire the semaphore due to timeout condition

Returns:

SystemP_FAILURE on failure to acquire the semaphore due to other conditions

int32_t SemaphoreP_getCount(SemaphoreP_Object *obj)

Function to return the count of a semaphore. Supported only on FreeRTOS.

Parameters:

obj – A SemaphoreP_Handle

Returns:

The count of the semaphore

struct SemaphoreP_Object
#include <SemaphoreP.h>

Opaque semaphore object used with the semaphore APIs.

Public Members

uintptr_t rsv[SemaphoreP_OBJECT_SIZE_MAX / sizeof(uint32_t)]

reserved, should NOT be modified by end users