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当没有指定超时时间时,获得信号量失败。

      osErrorParametersemaphore_id参数错误。

  osStatus_t osSemaphoreRelease (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 }

 

posted @ 2021-10-04 18:52  Ivan0512  阅读(2006)  评论(0编辑  收藏  举报