CMSIS-RTOS2 文档翻译 之 参考(CMSIS-RTOS2 API 之 信号量)
数据结构 | |
struct | osSemaphoreAttr_t |
信号量的属性结构体。 更多... |
|
类型定义 | |
typedef void * | osSemaphoreId_t |
函数 | |
osSemaphoreId_t | osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) |
创建并初始化信号量对象。更多... |
|
const char * | osSemaphoreGetName (osSemaphoreId_t semaphore_id) |
获取信号量对象的名称。更多... |
|
osStatus_t | osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) |
如果没有令牌可用,则获取信号量标记或超时。更多... |
|
osStatus_t | osSemaphoreRelease (osSemaphoreId_t semaphore_id) |
释放一个信号量令牌直到最初的最大数量。更多... |
|
uint32_t | osSemaphoreGetCount (osSemaphoreId_t semaphore_id) |
获取当前的信号量令牌计数。更多... |
|
osStatus_t | osSemaphoreDelete (osSemaphoreId_t semaphore_id) |
删除一个信号量对象。更多... |
|
描述
信号量用于管理和保护对共享资源的访问。信号量与互斥锁非常相似。尽管互斥锁允许一次只有一个线程访问共享资源,但信号量可用于允许固定数量的线程/ ISR 访问共享资源池。使用信号量可以管理对一组相同外设的访问(例如多个 DMA 通道)。
信号量对象应初始化为可用令牌的最大数量。这个可用资源的数量被指定为 osSemaphoreNew 函数的参数。每次使用 osSemaphoreAcquire(处于可用状态)获得信号量标记时,信号量计数递减。当信号量计数为 0(即耗尽状态)时,不能获得更多的信号量标记。尝试获取信号量标记的线程/ISR 需要等待,直到下一个标记为空。信号量与 osSemaphoreRelease 一起发布,增加信号量计数。
- 注意
- 可以从中断服务例程调用函数 osSemaphoreAcquire ,osSemaphoreGetCount 和 osSemaphoreRelease 。
- 有关 RTX5 配置选项,请参阅信号量配置。
信号量用例
由于其灵活性,信号量涵盖了广泛的同步应用程序。同时,它们也许是要了解的最具挑战性的 RTOS 对象。下面解释一下信号量的用例,取自 Allen B . Downey 的小信号小册子,该小册子可以免费下载。
非二制信号量(复用)
多路复用限制了可以访问代码的关键部分的线程数量。例如,这可能是访问只支持有限数量的呼叫的 DMA 资源的函数。
要允许多个线程运行该函数,请将信号量初始化为可允许的最大线程数。信号量中的令牌数表示可能输入的附加线程的数量。如果这个数字为零,那么下一个尝试访问该函数的线程将不得不等待,直到其他线程退出并释放其令牌。当所有线程退出时,令牌编号返回 n 。以下示例显示了可能访问该资源的其中一个线程的代码:
生产者/消费者信号量
生产者 - 消费者问题可以使用两个信号量来解决。
第一个信号量(empty_id)对可用(空)缓冲区进行倒计数,即生产者线程可以通过从这个缓冲区获取可用缓冲区时隙。
第二个信号量(filled_id)对使用过的(填充的)缓冲区进行计数,即消费者线程可以通过从这个缓冲区获取可用数据来等待。
线程在给定序列中获取和释放两个信号量的正确行为是至关重要的。根据这个例子,可以有多个生产者和/或消费者线程同时运行。
数据结构文档
struct osSemaphoreAttr_t |
Data Fields | ||
---|---|---|
const char * | name |
信号量的名称 指向具有人类可读名称的信号量对象的字符串。 |
uint32_t | attr_bits |
属性位 保留以供将来使用(设为'0')。 |
void * | cb_mem |
内存控制块 指向信号量控制块对象的内存位置的指针。这可以选择用于自定义内存管理系统。 |
uint32_t | cb_size |
为控制块提供的内存大小 内存块的大小与 cb_mem 一起传递。必须是信号量控制块对象的大小或更大。 |
类型定义文档
函数文档
osSemaphoreId_t osSemaphoreNew | ( | uint32_t | max_count, |
uint32_t | initial_count, | ||
const osSemaphoreAttr_t * | attr | ||
) |
- 参数
-
[in] max_count 可用令牌的最大数量。 [in] initial_count 可用令牌的初始数量。 [in] attr 信号量属性; NULL:默认值。
- 返回
- 信号标识以供其他功能参考,或者在发生错误时使用 NULL 。
osSemaphoreNew 函数创建并初始化一个信号量对象,该对象用于管理对共享资源的访问,并返回指向信号量对象标识符的指针或在发生错误时返回 NULL 。它可以在 RTOS 启动之前(调用 osKernelStart)安全地调用,但不能在它初始化之前(调用 osKernelInitialize)调用。
参数 max_count 指定可用令牌的最大数量。max_count 值为 1 会创建一个二制信号量。
参数 initial_count 设置可用令牌的初始数量。
参数 attr 指定了额外的信号量属性。如果设置为 NULL ,则会使用默认属性。
- 注意
- 该函数不能从中断服务程序调用。
代码示例
const char * osSemaphoreGetName | ( | osSemaphoreId_t | semaphore_id | ) |
- 参数
-
[in] semaphore_id 由 osSemaphoreNew 获得的信号量 ID 。
- 返回
- 名称为 NULL 终止的字符串。
函数 osSemaphoreGetName 返回指向由参数 semaphore_id 标识的信号量的名称字符串的指针,或者在出现错误时返回 NULL 。
- 注意
- 该函数不能从中断服务程序调用。
osStatus_t osSemaphoreAcquire | ( | osSemaphoreId_t | semaphore_id, |
uint32_t | timeout | ||
) |
- 返回
- 状态代码,指示该函数的执行状态。
阻塞函数 osSemaphoreAcquire 一直等待,直到由参数 semaphore_id 指定的信号量对象的标记变为可用。如果令牌可用,该函数立即返回并减少令牌计数。
参数超时指定系统等待获取令牌的时间。系统等待时,调用此函数的线程将进入 BLOCKED 状态。参数超时可以有以下值:
- 当超时为 0 时,函数立即返回(即尝试语义)。
- 当超时设置为 osWaitForever 时,函数将等待无限的时间,直到信号量变为可用(即等待语义)。
- 所有其他值都指定了内核中的超时时间(即定时等待语义)。
可能的 osStatus_t 返回值:
- osOK: 该令牌已被获得。
- osErrorTimeout: 在给定的时间内无法获得令牌。
- osErrorResource: 未指定超时时无法获取令牌。
- osErrorParameter: 参数 semaphore_id 不正确。
- 注意
- 如果参数 timeout 设置为 0 ,可以从中断服务例程调用。
代码示例
请参阅 osSemaphoreNew 。
osStatus_t osSemaphoreRelease | ( | osSemaphoreId_t | semaphore_id | ) |
- 参数
-
[in] semaphore_id 由 osSemaphoreNew 获得的信号量 ID 。
- 返回
- 状态代码,指示该函数的执行状态。
函数 osSemaphoreRelease 释放由参数 semaphore_id 指定的信号量对象的标记。令牌只能在创建时指定的最大数量发布,请参阅 osSemaphoreNew 。 当前等待此信号量对象标记的其他线程将被置于 READY 状态。
可能的 osStatus_t 返回值:
- osOK: 令牌已被正确释放并且计数增加。
- osErrorResource: 已达到最大令牌计数。
- osErrorParameter: 参数 semaphore_id 不正确。
- 注意
- 这个函数可以从中断服务程序中调用。
代码示例
请参阅 osSemaphoreNew 。
uint32_t osSemaphoreGetCount | ( | osSemaphoreId_t | semaphore_id | ) |
- 参数
-
[in] semaphore_id 由 osSemaphoreNew 获得的信号量 ID 。
- 返回
- 可用的令牌数量。
函数 osSemaphoreGetCount 返回由参数 semaphore_id 指定的信号量对象的可用令牌的数量。如果发生错误,则返回 0 。
- 注意
- 这个函数可以从中断服务程序中调用。
osStatus_t osSemaphoreDelete | ( | osSemaphoreId_t | semaphore_id | ) |
- 参数
-
[in] semaphore_id 由 osSemaphoreNew 获得的信号量 ID 。
- 返回
- 状态代码,指示该函数的执行状态。
函数 osSemaphoreDelete 删除由参数 semaphore_id 指定的信号量对象。它释放信号量处理获得的内部内存。在这次调用之后,semaphore_id 不再有效并且不能使用。可以使用函数 osSemaphoreNew 再次创建信号量。
可能的 osStatus_t 返回值:
- osOK: 信号量对象已被删除。
- osErrorParameter: 参数 semaphore_id 是 NULL 或无效的。
- osErrorResource: 由参数 semaphore_id 指定的信号量处于无效信号量状态。
- osErrorISR: osSemaphoreDelete 不能从中断服务程序调用。
- 注意
- 该函数不能从中断服务程序调用。