os_sem_post
所属模块:同步机制 | 类型:信号量释放函数
函数简介
os_sem_post 用于释放信号量资源,
当存在等待任务时会直接唤醒最高优先级任务,
否则将资源计数进行累加。
该机制实现了“资源直交付模型”,
即优先满足等待任务,而不是累积信号量。
函数原型
char os_sem_post(char sid);
参数说明
| 参数 |
说明 |
| sid |
信号量ID(0 ~ OS_RESOURCE_MAX-1) |
返回值
1 - 成功唤醒等待任务
0 - 无等待任务,资源累加
-1 - 参数非法
源码实现
/*------------------------------------------------------------------------
| FILE DESCRIPTION |
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
| - File name : semaphore_post.c
| - Author : 谭舒
| - Update date : 2026-09-19
| - Copyright(C) : 2026 HRTOS. All rights reserved.
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
| INCLUDES |
------------------------------------------------------------------------*/
#include "hrtos_internal.h"
/*------------------------------------------------------------------------
| API FUNCTIONS |
------------------------------------------------------------------------*/
/**
* @brief 释放指定的信号量资源。
*
* @param[in] sid 信号量资源槽位编号。
*
* @return 操作结果。
* @retval 1 成功释放信号量,并唤醒一个等待任务。
* @retval 0 信号量释放成功,当前无任务等待。
* @retval -1 信号量资源槽位编号无效。
*
* @note 当存在等待任务时,直接唤醒一个等待任务,不增加信号量计数。
* 当不存在等待任务时,信号量计数增加 1,最大计数值为 255。
* 被唤醒任务按照当前优先级选择。
*/
char os_sem_post(char sid)
{
OS_RESOURCE *s;
char next ;
char i;
char best_prio ;
/* -------------------------------------------------
* 参数检查
* ------------------------------------------------- */
if(sid < 0 || sid >= OS_RESOURCE_MAX)
{
return -1;
}
/* 进入临界区 */
EA = 0;
best_prio = -1;
next = OS_INVALID_ID;
s = &OS_RES[sid];
/* -------------------------------------------------
* 若存在等待任务:
* 优先唤醒任务,而不是增加信号量计数
* ------------------------------------------------- */
if(s->wait_mask)
{
/* -------------------------------------------------
* 查找最高优先级等待任务
* ------------------------------------------------- */
for(i = 0; i < OS_PROCESS_MAX; i++)
{
if(s->wait_mask & ((u16)1 << i))
{
if(OS_TASK[i].cur_prio > best_prio)
{
best_prio = OS_TASK[i].cur_prio;
next = i;
}
}
}
/* 唤醒任务 */
if(next != OS_INVALID_ID)
{
wake_task(next, WAIT_SIGNAL);
}
EA = 1;
return 1;
}
/* -------------------------------------------------
* 无等待任务:
* 信号量资源累加
* ------------------------------------------------- */
if(OS_RES[sid].value < 255)
{
s->value++;
}
EA = 1;
return 0;
}
/*------------------------------------------------------------------------
| END OF FILE: semaphore_post.c |
------------------------------------------------------------------------*/
使用示例
void task()
{
os_sem_post(0);
}
注意事项
信号量释放遵循“优先唤醒等待任务”的原则,
不保证 value 一定累加(取决于是否存在等待任务)。