os_wait
所属模块:内核调度 | 类型:统一阻塞接口
函数简介
os_wait 是 HRTOS 的统一阻塞接口,
用于将当前任务置为等待状态,并根据不同等待类型进入调度体系。
支持多种等待模式:
延时等待、信号量等待、互斥锁等待、消息队列等待以及事件等待。
函数原型
u8 os_wait(u8 type, u8 obj, u16 tick);
参数说明
| 参数 |
说明 |
| type |
等待类型(WAIT_DELAY / WAIT_SEM / WAIT_MUTEX / WAIT_MSG / WAIT_EVENT) |
| obj |
等待资源ID(仅资源类等待有效) |
| tick |
超时 tick(仅 WAIT_DELAY 或带超时等待使用) |
返回值
WAIT_SIGNAL - 被资源/事件唤醒
WAIT_TIMEOUT - 超时返回
0 - 非法参数或异常路径返回
源码实现
/*------------------------------------------------------------------------
| FILE DESCRIPTION |
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
| - File name : wait.c
| - Author : 谭舒
| - Update date : 2026-09-19
| - Copyright(C) : 2026 HRTOS. All rights reserved.
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
| INCLUDES |
------------------------------------------------------------------------*/
#include "hrtos_internal.h"
/*------------------------------------------------------------------------
| API FUNCTIONS |
------------------------------------------------------------------------*/
/**
* @brief 使当前任务进入指定的等待状态。
*
* @param[in] type 等待类型。
* @param[in] obj 等待对象编号。
* @param[in] tick 最大等待时间,以系统 Tick 数为单位。
*
* @return 等待结果。
* @retval WAIT_TIMEOUT 任务因等待超时被唤醒。
* @retval WAIT_SIGNAL 任务因资源或事件触发被唤醒。
* @retval 0 等待参数无效或当前任务已处于等待状态。
*
* @note 该函数统一处理延时、信号量、互斥锁、消息及事件等等待操作。
* 任务进入等待状态后停止参与正常调度,并由系统在等待条件满足
* 或等待超时后恢复任务运行。
* 延时等待不关联具体资源对象,资源等待则根据 obj 参数关联对应资源。
*/
u8 os_wait(u8 type, u8 obj, u16 tick)
{
u8 tid;
/* 进入临界区 */
EA = 0;
/* 当前任务 ID */
tid = OS_CURRENT_TASK;
if(type == WAIT_DELAY)//是时间
{
if(tick == 0)//时间0,直接返回
{
EA = 1 ;
return WAIT_TIMEOUT;
}
/* -------------------------------------------------
* 高速任务独立处理
* 不进入统一 WAIT 队列
* ------------------------------------------------- */
if(tid >= OS_PROCESS_MAX)
{
if(tid == OS_PROCESS_MAX)
{
OS_KUAI_PROCESS_A = 0;
OS_WAIT_DI2[0] = tick;
OS_SCHED_REASON=1;//调度触发位
EA = 1;
TF0=1;//T0中断
}
else if(tid == OS_PROCESS_MAX + 1)
{
OS_KUAI_PROCESS_B = 0;
OS_WAIT_DI2[1] = tick;
OS_SCHED_REASON=1;//调度触发位
EA = 1;
TF0=1;//T0中断
}
return WAIT_TIMEOUT;
}
/* -------------------------------------------------
* 设置等待信息
* ------------------------------------------------- */
OS_TASK[tid].wait_type = type; /* 等待类型 */
OS_TASK[tid].wait_obj = obj; /* 等待对象 */
OS_TASK[tid].wait_tick = tick; /* 超时 tick */
OS_TASK[tid].wait_flag = 0; /* 等待结果 */
OS_TASK[tid].state = WAIT;
/* 当前任务不可运行 */
OS_PROCESS_OK[tid] &= 0xfe;
OS_SCHED_REASON=1;//调度触发位
/* 退出临界区 */
EA = 1;
TF0=1;//T0中断
return OS_TASK[tid].wait_flag;
}
/* -------------------------------------------------
* 当前任务已经处于等待状态
* 不允许重复进入等待
* ------------------------------------------------- */
if(OS_TASK[tid].wait_type != WAIT_NONE)
{
EA = 1 ;
return 0;
}
if(type != WAIT_DELAY)//不是时间
{
if(obj>=OS_RESOURCE_MAX)//卡槽超范围
{
EA = 1 ;
return 0;
}
}
/* -------------------------------------------------
* 设置等待信息
* ------------------------------------------------- */
OS_TASK[tid].wait_type = type; /* 等待类型 */
OS_TASK[tid].wait_obj = obj; /* 等待对象 */
OS_TASK[tid].wait_tick = tick; /* 超时 tick */
OS_TASK[tid].wait_flag = 0; /* 等待结果 */
/* -------------------------------------------------
* 加入资源等待队列
* -------------------------------------------------
* WAIT_DELAY 属于纯时间等待,
* 不需要进入资源等待队列
* ------------------------------------------------- */
if(type != WAIT_DELAY && obj != OS_INVALID_ID)
{
OS_RES[obj].wait_mask |= ((u16)1 << tid);
OS_RES[obj].wait_cnt++;
}
/* -------------------------------------------------
* 阻塞当前任务
* ------------------------------------------------- */
OS_TASK[tid].state = WAIT;
/* 当前任务不可运行 */
OS_PROCESS_OK[tid] &= 0xfe;
/* -------------------------------------------------
* 触发任务切换
* 当前任务正式进入阻塞状态
* ------------------------------------------------- */
OS_SCHED_REASON=1;//调度触发位
/* 退出临界区 */
EA = 1;
TF0=1;//T0中断
/* -------------------------------------------------
* 被唤醒后返回等待结果
* -------------------------------------------------
* WAIT_TIMEOUT -> 超时
* WAIT_SIGNAL -> 正常唤醒
* ------------------------------------------------- */
return OS_TASK[tid].wait_flag;
}
/*------------------------------------------------------------------------
| END OF FILE: wait.c |
------------------------------------------------------------------------*/
使用示例
void task()
{
os_wait(WAIT_DELAY, 0, 100);
}
注意事项
该函数是 HRTOS 所有阻塞机制的统一入口,
不同 IPC(信号量、互斥锁、消息队列、事件)最终都会映射到该接口。