1. 程式人生 > 其它 >RTX筆記7 - 訊號量Semaphores

RTX筆記7 - 訊號量Semaphores

  訊號量用於管理和保護對共享資源的訪問。訊號量非常類似於互斥鎖。互斥鎖一次只允許一個執行緒訪問一個共享資源,而訊號量可以用來允許固定數量的執行緒/ISR訪問共享資源池。通過使用訊號量,可以管理對一組相同外設的訪問(例如多個DMA通道)。

  訊號量物件應該初始化為可用令牌的最大數量。可用資源的數量被指定為 osSemaphoreNew 函式的引數。每次通過 osSemaphoreAcquire (處於可用狀態)獲得一個訊號量令牌時,訊號量計數就會減少。當訊號量計數為0(即耗盡狀態)時,不能再獲得訊號量標記。試圖獲取訊號量令牌的執行緒/ISR需要等待,直到下一個令牌空閒。通過ossemaphorerrelease 釋放訊號量。

  Note:osSemaphoreAcquire, osSemaphoreGetCount, osSemaphoreRelease 可在中斷中呼叫。

osSemaphoreAttr_t Data Fields
const char * name name of the semaphore

Pointer to a constant string with a human readable name (displayed during debugging) of the semaphore object.

Default: NULL no name specified.

uint32_t attr_bits attribute bits

Reserved for future use (must be set to '0' for future compatibility).

void * cb_mem memory for control block

Pointer to a memory for the semaphore control block object. Refer to Static Object Memory for more information.

Default: NULL to use Automatic Dynamic Allocation for the semaphore control block.

uint32_t cb_size size of provided memory for control block

The size (in bytes) of memory block passed with cb_mem. For RTX, the minimum value is defined with osRtxSemaphoreCbSize (higher values are permitted).

Default: 0 as the default is no memory provided with cb_mem.

  osSemaphoreId_tosSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr):

    建立訊號量。

    輸入引數:

      max_count - 可用令牌/資源的最大數。設定為1,建立一個二值訊號量。

      initial_count - 可用令牌/資源的初始值。

      attr - 訊號量屬性。NULL,使用預設屬性。

    返回訊號量ID,或者NULL。

  osStatus_tosSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout):

    申請訊號量。timeout是等待訊號量的節拍數,0代表立即返回,不阻塞;osWaitForever代表一直等待,直到有可用的訊號量。

    返回值:

      osOK:獲取訊號量成功。

      osErrorTimeout:等待超時失敗。

      osErrorResource當沒有指定超時時間時,獲得訊號量失敗。

      osErrorParametersemaphore_id引數錯誤。

  osStatus_tosSemaphoreRelease (osSemaphoreId_t semaphore_id):

    釋放訊號量。

    返回值:

      osOK:釋放訊號量成功。

      osErrorResource訊號量不能被釋放。訊號量令牌數已經達到最大值。

      osErrorParametersemaphore_id引數錯誤。

 1 osSemaphoreId_t sem;
 2 
 3 static void _ledThread(void *argument);
 4 
 5 void
 6 test_semaphore(void)
 7 {
 8     osThreadId_t thread;
 9     
10     sem = osSemaphoreNew(1, 1, NULL);
11     
12     osThreadNew(_ledThread, (void *)1, NULL);
13     osThreadNew(_ledThread, (void *)2, NULL);
14 }
15 
16 static void
17 _ledThread(void *argument)
18 {
19     osStatus_t status;
20     uint32_t id = (uint32_t)argument;
21     uint32_t delay;
22     
23     if(1 == id) {
24         delay = 500;
25     } else {
26         delay = 1000;
27     }
28     
29     for(;;) {
30         status = osSemaphoreAcquire(sem, osWaitForever);
31         if(osOK == status) {
32             menuShow(&seg_led, id, 0);
33             osDelay(delay);
34             osSemaphoreRelease(sem);
35         }
36     }
37 }