RTX笔记8 - 信号量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_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr):
创建信号量。
输入参数:
max_count - 可用令牌/资源的最大数。设置为1,创建一个二值信号量。
initial_count - 可用令牌/资源的初始值。
attr - 信号量属性。NULL,使用默认属性。
返回信号量ID,或者NULL。
osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout):
申请信号量。timeout是等待信号量的节拍数,0代表立即返回,不阻塞;osWaitForever代表一直等待,直到有可用的信号量。
返回值:
osOK:获取信号量成功。
osErrorTimeout:等待超时失败。
osErrorResource:当没有指定超时时间时,获得信号量失败。
osErrorParameter:semaphore_id参数错误。
osStatus_t osSemaphoreRelease (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 }