核心接口
信号量通过初始化、等待和释放三个主要操作完成协作。 以下接口按本页提供的 HRTOS 声明整理,参数类型和返回值语义应以当前版本头文件为准。
char os_sem_init(u8 sid, char init_val); char os_sem_post(char sid); u8 os_sem_wait(u8 sid);
os_sem_init():初始化指定信号量的计数状态。os_sem_wait():请求获取一个信号量计数;当前无法获取时的行为由实现决定。os_sem_post():释放信号量或通知等待任务,具体处理顺序以实现为准。
os_sem_wait() 返回类型为 u8,
而初始化与释放接口返回 char。使用时应核对各接口的返回值定义、
错误表示和边界条件,不能直接假定三者采用相同的成功或失败约定。
数据模型与资源状态
按本页所描述的 HRTOS 实现,信号量使用通用资源管理结构中的计数与等待状态, 而不是必须为信号量单独创建一套独立对象布局。
OS_RESOURCE
{
value // 资源计数或可用状态
owner // 通用资源结构中的所有者相关字段
wait_mask // 等待任务位图
wait_cnt // 等待计数或预留字段,依实现而定
}
value:表示信号量计数状态,是计数型同步的关键字段。wait_mask:记录等待该资源的任务集合,具体位定义由内核实现决定。owner:通用资源结构中可能存在的所有者相关字段;信号量不应因此被理解为互斥量。wait_cnt:其实际用途应根据当前结构体定义和使用位置确认。
等待流程
等待操作首先检查信号量当前是否可获取。 当计数大于零时,常见实现会直接消耗一个计数;计数不可用时, 则可能登记当前任务并进入等待状态。
判断当前信号量是否有可获取的计数。
有计数则按实现获取;否则处理等待请求。
条件满足并经调度后,任务继续执行。
os_sem_wait()
│
▼
检查 value
├─ value > 0
│ └─ 消耗计数并返回
│
└─ value 不可获取
└─ 按内核机制登记等待并处理任务阻塞
原实现说明提到 WAIT_SEM 与 wait_mask。
具体的任务状态切换顺序、等待登记细节和返回路径,
应以当前版本源码为准。
释放与唤醒流程
释放信号量时,需要处理当前等待任务和计数状态之间的关系。 原页面描述的实现策略是:优先检查是否存在等待任务;有等待任务时尝试唤醒, 否则在计数范围允许时增加计数。
判断是否存在等待该信号量的任务。
按实现唤醒等待任务,或增加计数。
任务何时运行取决于内核调度规则。
os_sem_post()
│
▼
检查 wait_mask
├─ 存在等待任务
│ └─ 按实现选择并唤醒等待任务
│
└─ 没有等待任务
└─ 检查计数边界并按规则增加 value
原页面指出,等待任务按优先级选择,且计数存在上限。 这两点属于具体实现策略:应进一步核对当前版本的任务选择代码、 计数类型以及溢出处理,不能只根据伪代码推断所有边界行为。
os_sem_post() 返回前执行。
是否发生立即切换,应根据 HRTOS 的调度规则与调用上下文判断。
核心行为语义
Wait / 获取
请求一个可用计数。计数可获取时按实现消耗计数; 否则可能登记等待并暂停当前任务的继续执行。
Post / 释放
通知或释放一个信号量单位。实现可能优先处理等待任务, 也可能在没有等待者时更新计数。
这里描述的是信号量常见的同步模型,并结合了原页面提供的 HRTOS 行为说明。 具体执行顺序、返回时机和错误情况仍应以当前版本实现为准。
关键特性与使用边界
- 计数同步:适用于资源数量管理或记录待处理通知的场景。
- 无互斥所有权语义:信号量与互斥量的设计目的不同,不应将其自动视为共享资源的所有权锁。
- 等待任务管理:当前页面描述的实现使用
wait_mask记录等待关系,具体位图规则以源码为准。 - 优先级相关行为:若实现按优先级选择等待任务,应在文档中明确选择规则和调度边界。
- 计数边界:计数类型及上限决定最大可累积数量,应用应避免无限制地重复释放。
post,而不能在 ISR 中执行会阻塞的 wait。
在将此规则作为正式 API 保证之前,应确认当前版本对中断上下文的具体限制,
包括允许调用的接口、是否可能触发任务切换以及相关临界区处理。
典型应用场景
生产者与消费者
生产者完成数据准备后释放信号量,消费者等待通知后处理数据。
中断通知任务
在实现允许的前提下,由中断路径发出通知,让任务在后续调度中处理工作。
资源池管理
用计数表示可用资源数量,例如固定数量的缓冲区或资源单元。
任务同步触发
通过等待与释放建立任务之间的同步关系,减少主动轮询。
信号量与其他 IPC 机制
- Semaphore:重点是计数、同步和资源数量管理。
- Mutex:重点是共享资源的互斥访问及相应的所有权规则。
- Event:重点是表达事件或条件状态,适合任务按状态进行协作。
- Message Queue:重点是按队列规则缓存并传递有序数据。
- Mailbox:重点是实现所定义的邮箱消息传递语义。
需要表示可用数量或同步次数 → Semaphore 需要保护共享资源 → Mutex 需要表达事件或条件状态 → Event 需要缓存并顺序传递数据 → Message Queue 需要邮箱式消息传递 → Mailbox
以上是按常见设计语义进行的选型参考。实际工程中仍应检查 HRTOS 对应接口的真实能力、 调用约束和资源开销,再决定采用哪种机制。