天天看點

FreeRTOS 的互斥信号量與二進制信号量

URL: http://bbs.ednchina.com/BLOG_ARTICLE_145889.HTM

FreeRTOS Ver4.5以上支援兩種信号量:  互斥型性号量mutex和二進制信号量binary.

二進制信号量相關宏或函數:

vSemaphoreCreateBinary  // Macro that creates a Binary semaphore

xSemaphoreTake  // Macro to obtain a semaphore

xSemaphoreGive  // Macro to release a semaphore

xSemaphoreGiveFromISR // Macro to release a semaphore (used from ISR)

互斥型信号量相關宏或函數:

xSemaphoreCreateRecursiveMutex  // Macro that creates a mutex semaphore

xQueueTakeMutexRecursive  // obtain a semaphore

xQueueGiveMutexRecursive  // release a semaphore

注:二進制信号量與互斥型信号量比較

英文版:

         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.

======================================

中文版:

互斥型信号量必須是同一個任務申請,同一個任務釋放,其他任務釋放無效。

二進制信号量,一個任務申請成功後,可以由另一個任務釋放。

二進制信号量實作任務互斥: 列印機資源隻有一個,abc三個任務共享,當a取得使用權後,為了防止其他任務錯誤地釋放了信号量(),必須将列印機房的門關起來(進入臨界段),用完後,釋放信号量,再把門打開(出臨界段),其他任務再進去列印。(而互斥型信号量由于必須由取得信号量的那個任務釋放,故不會出現其他任務錯誤地釋放了信号量的情況出現,故不需要有臨界段。互斥型信号量是二進制信号量的子集。)

二進制信号量實作任務同步: a任務一直等待信号量,b任務定時釋放信号量,完成同步功能

========================================

Example usage:

xSemaphoreHandle xSemaphore = NULL;

// A task that creates a semaphore.

void vATask( void * pvParameters )

{

    xSemaphore = xSemaphoreCreateMutex();

}

// A task that uses the semaphore.

void vAnotherTask( void * pvParameters )

{

// ... Do other things.

    if( xSemaphore != NULL )

    {

        if(xSemaphoreTake(xSemaphore,(portTickType)10)

           ==pdTRUE)

        {

            xSemaphoreGive( xSemaphore );

        }

        else

        {

        }

    }

}

繼續閱讀