os_msgq_recv

所属模块:通信机制 | 类型:消息队列接收函数

API Metadata

函数ID:os_msgq_recv
模块:msgq
类型:message queue receive
嵌套深度:2

函数简介

os_msgq_recv 用于从消息队列中读取数据, 支持阻塞与非阻塞两种模式。

当队列为空时任务可进入等待状态; 当队列有数据时直接读取并触发发送端唤醒。

函数原型

char os_msgq_recv(os_msgq_t *q, u8 obj, u8 *_data, char nonblock);

参数说明

参数 说明
q 消息队列控制块指针
obj 资源ID(用于唤醒等待发送任务)
_data 接收数据存储地址
nonblock 非阻塞标志(1=不阻塞 / 0=阻塞)

返回值

1 - 成功接收数据
0 - 非阻塞模式下未就绪或被唤醒返回
-1 - 等待失败或异常

源码实现

/*------------------------------------------------------------------------ | FILE DESCRIPTION | ------------------------------------------------------------------------*/ /*------------------------------------------------------------------------ | - File name : msgq_recv.c | - Author : 谭舒 | - Update date : 2026-09-19 | - Copyright(C) : 2026 HRTOS. All rights reserved. ------------------------------------------------------------------------*/ /*------------------------------------------------------------------------ | INCLUDES | ------------------------------------------------------------------------*/ #include "hrtos_internal.h" /*------------------------------------------------------------------------ | API FUNCTIONS | ------------------------------------------------------------------------*/ /** * @brief 从消息队列接收一个消息。 * * @param[in] q 消息队列控制块指针。 * @param[in] obj 资源对象编号。 * @param[out] _data 接收数据存储地址。 * @param[in] nonblock 非阻塞模式标志。 * * @return 操作结果。 * @retval 1 消息接收成功。 * @retval 0 非阻塞模式下队列为空。 * @retval 其他 等待操作返回的结果。 * * @note 当消息队列非空时,直接读取队头消息并更新队列状态。 * 当消息队列为空时,非阻塞模式直接返回, * 阻塞模式下当前任务进入消息接收等待状态。 * 消息读取后,当存在等待发送任务时唤醒对应任务。 */ char os_msgq_recv(os_msgq_t *q, u8 obj, u8 *_data, char nonblock) { u8 i; EA = 0; /* ------------------------- * 1. 队列为空 * 当前任务进入等待状态 * ------------------------- */ if(q->count == 0) { EA = 1; /* 非阻塞模式直接返回 */ if(nonblock) { return 0; } /* 队列空 */ i = os_wait(WAIT_MSG_RECV, obj, 0); } /* ------------------------- * 2. 队列非空,直接读取消息 * ------------------------- */ if(q->count > 0) { *_data = q->buf[q->tail]; //读取队头消息 q->tail = (q->tail + 1) % q->_size;//更新读指针 q->count--; //消息数量减1 /* ------------------------- * 队列释放出空闲空间 * 唤醒等待发送的任务 * ------------------------- */ if(OS_RES[obj].wait_mask) { u8 next = OS_INVALID_ID; u8 i; for(i = 0; i < OS_MAX_TASK; i++) { if((OS_RES[obj].wait_mask & ((u16)1 << i)) && (OS_TASK[i].wait_type == WAIT_MSG_SEND)) { next = i; break; } } if(next != OS_INVALID_ID) { wake_task(next, WAIT_SIGNAL); } } EA = 1; return 1; } EA = 1; /* 队列空 */ return i; } /*------------------------------------------------------------------------ | END OF FILE: msgq_recv.c | ------------------------------------------------------------------------*/

使用示例

void recv_task() { u8 data; if(os_msgq_recv(&q, 0, &data, 0)) { // 处理数据 } }

注意事项

该函数是典型生产者-消费者模型实现, 在队列为空时可能进入阻塞状态,由调度器唤醒。

相关推荐