os_msgq_send
所属模块:通信机制 | 类型:消息队列发送函数
函数简介
os_msgq_send 用于向消息队列写入数据,
支持阻塞与非阻塞模式。
当队列满时任务可进入等待状态;
当队列有空闲空间时立即写入,并唤醒接收任务。
函数原型
char os_msgq_send(os_msgq_t *q, u8 obj, u8 _data, char nonblock);
参数说明
| 参数 |
说明 |
| q |
消息队列控制块指针 |
| obj |
资源ID(用于唤醒等待接收任务) |
| _data |
待发送的数据 |
| nonblock |
非阻塞标志(1=不阻塞 / 0=阻塞) |
返回值
1 - 发送成功
0 - 非阻塞模式下队列已满或未就绪
-1 - 等待失败或异常
源码实现
#include "hrtos_internal.h"
/**
* 消息队列发送
* 支持阻塞 / 非阻塞 + 自动唤醒消费者
*/
char os_msgq_send(os_msgq_t *q, u8 obj, u8 _data, char nonblock)
{
u8 i;
EA = 0;
/* -------------------------
* 队列满 → 进入等待
* ------------------------- */
if(q->count == q->_size)
{
EA = 1;
if(nonblock)
{
return 0;
}
i = os_wait(WAIT_MSG_SEND, obj, 0);
}
/* -------------------------
* 队列未满 → 写入数据
* ------------------------- */
if(q->count < q->_size)
{
q->buf[q->head] = _data;
q->head = (q->head + 1) % q->_size;
q->count++;
/* -------------------------
* 唤醒接收任务
* ------------------------- */
if(OS_RES[obj].wait_mask)
{
u8 next = OS_INVALID_ID;
for(i = 0; i < OS_MAX_TASK; i++)
{
if((OS_RES[obj].wait_mask & ((u16)1 << i)) &&
(OS_TASK[i].wait_type == WAIT_MSG_RECV))
{
next = i;
break;
}
}
if(next != OS_INVALID_ID)
{
wake_task(next, WAIT_SIGNAL);
}
}
EA = 1;
return 1;
}
EA = 1;
return i;
}
使用示例
void producer_task()
{
os_msgq_send(&q, 0, 0xAA, 0);
}
注意事项
该函数是典型生产者-消费者模型实现,
在队列满时可能进入阻塞状态,由调度器唤醒。