# Semaphores & Mutexes
[RTOS]

Thread-safe methods to protect access to shared resources. More...

## Functions
void * | SemaphoreCreate ()
| Create a semaphore.
int | SemaphoreTake (void *semaphore, int blockTime)
| Obtain a semaphore.
int | SemaphoreGive (void *semaphore)
| Release a semaphore.
int | SemaphoreGiveFromISR (void *semaphore, int taskWoken)
| Release a semaphore from within an ISR.

## Detailed Description

Thread-safe methods to protect access to shared resources.

Quite often you'll have more than one task trying to get access to the same resources. To ensure that the resource is not in some intermediate state between reading and writing, it's necessary to serialize access to it. Semaphores and mutexes provide a way to do this.

Binary semaphores and mutexes are very similar but have some subtle differences: Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes binary semaphores the better choice for implementing synchronisation (between tasks or between tasks and an interrupt), and mutexes the better choice for implementing simple mutual exclusion.

A binary semaphore need not be given back once obtained, so task synchronisation can be implemented by one task/interrupt continuously 'giving' the semaphore while another continuously 'takes' the semaphore.

The priority of a task that 'takes' a mutex can potentially be raised if another task of higher priority attempts to obtain the same mutex. The task that owns the mutex 'inherits' the priority of the task attempting to 'take' the same mutex. This means the mutex must always be 'given' back - otherwise the higher priority task will never be able to obtain the mutex, and the lower priority task will never 'disinherit' the priority.

More info at http://www.freertos.org - much documentation here used from the FreeRTOS doc by Richard Barry.

## Function Documentation

void* SemaphoreCreate | ( | void |  | ) |

Create a semaphore.

Returns:
  A pointer to the newly created semaphore, or NULL on failure.

Example

        void* mySemaphore = SemaphoreCreate( );
        if( mySemaphore != NULL )
        {
          // The semaphore was created successfully and can now be used.
        }

Definition at line 891 of file rtos.c.

int SemaphoreGive | ( | void * | semaphore | ) |

Release a semaphore.

This must not be used from an ISR. See SemaphoreGiveFromISR( ) for an alternative which can be used from an ISR.

Parameters:

  | semaphore | The semaphore to release.

Returns:
  1 if the semaphore was released. 0 if an error occurred. Semaphores are implemented using queues. An error can occur if there is no space on the queue to post a message - indicating that the semaphore was not first obtained correctly.

See also:
  SemaphoreCreate( ), SemaphoreTake( )

Example

        void* mySemaphore;
        SemaphoreCreate( mySemaphore );
        if( SemaphoreTake( mySemaphore, 1000 ) ) // wait 1000 milliseconds on this semaphore
        {
          // access the protected resources

          // then release the semaphore
          if( !SemaphoreGive( mySemaphore ) )
            // then handle the error here
        }

Definition at line 950 of file rtos.c.

int SemaphoreGiveFromISR | ( | void * | semaphore,
|  | int | taskWoken |
| ) |  |  |

Release a semaphore from within an ISR.

See SemaphoreGive( ) for an alternative which can be used when not in an ISR.

Parameters:

  | semaphore | The semaphore to release.
  | taskWoken | This is included so an ISR can make multiple calls to SemaphoreGiveFromISR() from a single interrupt. The first call should always pass in 0. Subsequent calls should pass in the value returned from the previous call.

Returns:
  1 if the semaphore was released. 0 if an error occurred. Semaphores are implemented using queues. An error can occur if there is no space on the queue to post a message - indicating that the semaphore was not first obtained correctly.

Example

        void* mySemaphore;
        SemaphoreCreate( mySemaphore );
        void TimerISR( )
        {
          static int taskWoken = 0;
          taskWoken = SemaphoreGiveFromISR( mySemaphore, taskWoken );
          // If taskWoken was set to true you may want to yield (force a switch)
          // here.
        }

Definition at line 977 of file rtos.c.

int SemaphoreTake | ( | void * | semaphore,
|  | int | blockTime |
| ) |  |  |

Obtain a semaphore.

The semaphore must have first been created with SemaphoreCreate( ).

Parameters:

  | semaphore | The semaphore to take.
  | blockTime | The time, in milliseconds, to wait for the semaphore to become available.

Returns:
  1 if the semaphore was obtained. 0 if blockTime expired without the semaphore becoming available.

See also:
  SemaphoreCreate( ), SemaphoreGive( )

Example

        void* mySemaphore;
        SemaphoreCreate( mySemaphore );
        if( SemaphoreTake( mySemaphore, 100 ) ) // wait 100 milliseconds on this semaphore
        {
          // now access the protected resources
        }

Definition at line 923 of file rtos.c.