xSemaphoreGiveRecursive

semphr. h

    xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )

Macro to recursively release, or 'give', a mutex type semaphore. The mutex must have previously been created using a call to xSemaphoreCreateRecursiveMutex();

configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this macro to be available.

This macro must not be used on mutexes created using xSemaphoreCreateMutex().

A mutex used recursively can be 'taken' repeatedly by the owner. The mutex doesn't become available again until the owner has called xSemaphoreGiveRecursive() for each successful 'take' request. For example, if a task successfully 'takes' the same mutex 5 times then the mutex will not be available to any other task until it has also 'given' the mutex back exactly five times.

Parameters

  xMutex | A handle to the mutex being released, or 'given'. This is the handle returned by xSemaphoreCreateMutex();

Returns
  pdTRUE if the semaphore was given.

Example usage:

    SemaphoreHandle_t xMutex = NULL;

    // A task that creates a mutex.
    void vATask( void * pvParameters )
    {
       // Create the mutex to guard a shared resource.
       xMutex = xSemaphoreCreateRecursiveMutex();
    }

    // A task that uses the mutex.
    void vAnotherTask( void * pvParameters )
    {
       // ... Do other things.

       if( xMutex != NULL )
       {
           // See if we can obtain the mutex.  If the mutex is not available
           // wait 10 ticks to see if it becomes free.
           if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
           {
               // We were able to obtain the mutex and can now access the
               // shared resource.

               // ...
               // For some reason due to the nature of the code further calls to
            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
            // code these would not be just sequential calls as this would make
            // no sense.  Instead the calls are likely to be buried inside
            // a more complex call structure.
               xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
               xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );

               // The mutex has now been 'taken' three times, so will not be
            // available to another task until it has also been given back
            // three times.  Again it is unlikely that real code would have
            // these calls sequentially, it would be more likely that the calls
            // to xSemaphoreGiveRecursive() would be called as a call stack
            // unwound.  This is just for demonstrative purposes.
               xSemaphoreGiveRecursive( xMutex );
            xSemaphoreGiveRecursive( xMutex );
            xSemaphoreGiveRecursive( xMutex );

            // Now the mutex can be taken by other tasks.
           }
           else
           {
               // We could not obtain the mutex and can therefore not access
               // the shared resource safely.
           }
       }
    }