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:當沒有指定超時時間時,獲得訊號量失敗。
osErrorParameter:semaphore_id引數錯誤。
osStatus_tosSemaphoreRelease (osSemaphoreId_t semaphore_id):
釋放訊號量。
返回值:
osOK:釋放訊號量成功。
osErrorResource:訊號量不能被釋放。訊號量令牌數已經達到最大值。
osErrorParameter:semaphore_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 }