当前位置: 首页 > news >正文

uC/OS-III 队列(Queue)操作

队列(Queue)是 uC/OS-III 中用于任务间、任务与中断间数据传递的核心组件,支持异步通信与数据缓冲。本文基于 uC/OS-III 官方规范及工程实践,整理队列的标准操作流程,包括初始化、发送、接收、查询及异常处理,附完整代码示例与最佳实践。

一、队列核心概念与特性

uC/OS-III 的队列是线程安全的 FIFO(先进先出)缓冲区,支持以下关键特性:

  • 多任务访问:多个任务可同时向队列发送数据,多个任务可等待接收数据(按优先级唤醒)。
  • 中断安全:支持从中断服务程序(ISR)中发送数据(需用FromISR接口)。
  • 灵活的数据单元:队列中可存储任意类型数据(以指针形式传递,支持固定 / 可变长度)。
  • 阻塞机制:任务接收数据时可阻塞等待(带超时),无数据时不占用 CPU。

二、队列操作函数与标准写法

1. 队列初始化(创建队列)

功能:在系统启动阶段创建队列,分配内存并初始化元数据(如队列长度、名称)。函数OSQCreate()标准代码

#include "os.h"// 定义队列参数
#define QUEUE_NAME      "DATA_QUEUE"  // 队列名称(调试用)
#define QUEUE_LEN       10            // 队列最大容量(可存储10条消息)
#define MSG_SIZE        sizeof(void *)// 消息大小(以指针为单位,适配任意数据类型)// 全局队列对象(需在初始化后使用)
OS_Q  data_queue;/*** @brief 初始化队列* @return OS_ERR:错误码(OS_ERR_NONE表示成功)*/
OS_ERR queue_init(void) {OS_ERR err;// 创建队列:名称、长度、错误码输出OSQCreate((OS_Q     *)&data_queue,(CPU_CHAR *)QUEUE_NAME,(OS_MSG_QTY)QUEUE_LEN,(OS_ERR   *)&err);// 初始化失败处理(工程中需记录日志或断言)if (err != OS_ERR_NONE) {APP_TRACE_ERROR(("Queue create failed! err: %d\n", err));}return err;
}

关键参数

  • OS_MSG_QTY:队列可容纳的最大消息数(超过则发送失败)。
  • 队列需在OSStart()前初始化,确保任务启动时可用。

2. 发送消息到队列(任务中)

功能:任务向队列发送数据,支持阻塞 / 非阻塞模式,发送成功后消息进入队列尾部。函数OSQPost()标准代码

// 定义待发送的数据结构(示例)
typedef struct {uint8_t  type;   // 数据类型uint32_t value;  // 数据值
} DataMsg_t;/*** @brief 任务中向队列发送消息(非阻塞模式)* @param msg:待发送的数据指针* @return OS_ERR:错误码(OS_ERR_NONE表示成功)*/
OS_ERR queue_send(DataMsg_t *msg) {OS_ERR err;if (msg == NULL) {return OS_ERR_INV_PTR;  // 无效指针检查}// 发送消息:队列、消息指针、消息大小、FIFO模式、错误码OSQPost((OS_Q      *)&data_queue,(void      *)msg,(OS_MSG_SIZE)sizeof(DataMsg_t),  // 实际数据大小(OS_OPT     )OS_OPT_POST_FIFO,    // FIFO顺序(先到先处理)(OS_ERR    *)&err);// 处理发送结果if (err == OS_ERR_Q_FULL) {APP_TRACE_WARN(("Queue is full! Drop msg type: %d\n", msg->type));} else if (err != OS_ERR_NONE) {APP_TRACE_ERROR(("Send failed! err: %d\n", err));}return err;
}

关键选项

  • OS_OPT_POST_FIFO:按发送顺序排队(默认);OS_OPT_POST_LIFO:后发消息优先处理(慎用,可能导致数据无序)。
  • 非阻塞模式下,队列满时返回OS_ERR_Q_FULL,需根据业务决定是否重试或丢弃。

3. 从队列接收消息(任务中)

功能:任务从队列获取消息,支持阻塞等待(带超时),获取成功后消息从队列中移除。函数OSQPend()标准代码

/*** @brief 从队列接收消息(阻塞模式,永久等待)* @param msg:输出参数,接收消息的指针* @param timeout:超时时间(0表示永久等待,单位:系统时钟节拍)* @return OS_ERR:错误码(OS_ERR_NONE表示成功)*/
OS_ERR queue_receive(DataMsg_t **msg, OS_TICK timeout) {OS_ERR err;OS_MSG_SIZE msg_size;  // 接收消息的实际大小(可选)*msg = (DataMsg_t *)OSQPend((OS_Q        *)&data_queue,(OS_TICK     )timeout,(OS_OPT      )OS_OPT_PEND_BLOCKING,  // 阻塞模式(OS_MSG_SIZE *)&msg_size,(CPU_TS      )NULL,                 // 不记录时间戳(OS_ERR      *)&err);// 处理接收结果if (err == OS_ERR_TIMEOUT) {APP_TRACE_INFO(("Receive timeout!\n"));*msg = NULL;  // 超时返回空指针} else if (err != OS_ERR_NONE) {APP_TRACE_ERROR(("Receive failed! err: %d\n", err));*msg = NULL;} else {// 验证消息大小(可选,确保数据完整性)if (msg_size != sizeof(DataMsg_t)) {APP_TRACE_WARN(("Invalid msg size! Expect: %d, Got: %d\n", sizeof(DataMsg_t), msg_size));}}return err;
}

关键说明

  • 阻塞模式(OS_OPT_PEND_BLOCKING)下,无消息时任务进入阻塞态,不占用 CPU;超时后返回OS_ERR_TIMEOUT
  • 消息接收后会从队列中删除,确保不会被重复处理(核心特性)。

4. 中断中发送消息

功能:中断服务程序(ISR)向队列发送消息,需使用中断安全的专用接口。函数OSQPostFromISR()标准代码

/*** @brief 中断中向队列发送消息(ISR专用)* @param msg:待发送的数据指针(需确保在ISR外有效,如全局变量)*/
void queue_send_from_isr(DataMsg_t *msg) {OS_ERR err;if (msg == NULL) return;// 中断中发送消息:接口与任务版类似,但需用FromISROSQPostFromISR((OS_Q      *)&data_queue,(void      *)msg,(OS_MSG_SIZE)sizeof(DataMsg_t),(OS_OPT     )OS_OPT_POST_FIFO,(OS_ERR    *)&err);// 错误处理(ISR中避免复杂操作,仅记录关键错误)if (err == OS_ERR_Q_FULL) {// 队列满:可触发任务处理或丢弃(根据实时性需求)}// 触发任务调度(可选,确保高优先级任务立即执行)OSIntExit();
}

关键注意

  • ISR 中禁止使用阻塞操作,必须用FromISR版本接口(OSQPostFromISR)。
  • 消息缓冲区需为全局 / 静态变量(ISR 中栈内存不可靠)。

5. 队列状态查询

功能:查询队列当前消息数量、剩余容量等状态,用于监控或优化处理逻辑。函数OSQEntries()(消息数量)、OSQQuery()(详细状态)标准代码

/*** @brief 查询队列当前消息数量* @return 消息数量(0表示空队列)*/
OS_MSG_QTY queue_get_count(void) {OS_ERR err;OS_MSG_QTY count = OSQEntries((OS_Q *)&data_queue, (OS_ERR *)&err);if (err != OS_ERR_NONE) {APP_TRACE_ERROR(("Query count failed! err: %d\n", err));return 0;}return count;
}/*** @brief 查询队列详细状态(如最大容量、当前消息数)*/
void queue_query_details(void) {OS_ERR err;OS_Q_DATA q_data;  // 队列详细信息结构体OSQQuery((OS_Q     *)&data_queue,(OS_Q_DATA *)&q_data,(OS_ERR   *)&err);if (err == OS_ERR_NONE) {APP_TRACE_INFO(("Queue details: Name=%s, Max len=%d, Current entries=%d\n",q_data.NamePtr, q_data.MaxEntries, q_data.NbrEntries));}
}

应用场景

  • 批量处理优化:接收任务唤醒后,通过queue_get_count()一次性处理所有消息。
  • 系统监控:若队列消息数持续增长,可能预示消费者处理速度不足(需优化任务优先级或处理逻辑)。

6. 队列删除

功能:不再使用队列时释放资源(需确保无任务等待该队列)。函数OSQDel()标准代码

/*** @brief 删除队列(谨慎使用,需确保无任务依赖)* @return OS_ERR:错误码*/
OS_ERR queue_delete(void) {OS_ERR err;// 删除队列:选项为强制删除(即使有任务等待)OSQDel((OS_Q   *)&data_queue,(OS_OPT )OS_OPT_DEL_ALWAYS,(OS_ERR *)&err);if (err != OS_ERR_NONE) {APP_TRACE_ERROR(("Delete queue failed! err: %d\n", err));}return err;
}

注意

  • 队列删除后不可再使用,需确保所有依赖任务已停止。
  • 嵌入式系统中队列通常伴随系统生命周期,较少需要动态删除。
http://www.dtcms.com/a/415495.html

相关文章:

  • 速度即排名:90分以下=谷歌流量流失?
  • 企业网站空间选择什么网站可以找人做设计
  • 网站建设如何快速增加用户中山企业网站建设公司
  • 工业4.0下的边缘存储设计:数据就地处理,响应更快更安全
  • 做情诗网站私有云 搭建wordpress
  • 上海定制app开发公司杭州seo关键词优化公司
  • Photoshop - Photoshop 根据需要以最佳格式保存照片
  • 11-Redis 集合类型深度指南:从去重特性到集合运算场景落地
  • 【Redis】超级超市的仓库管理系统
  • 个人网站建设模板视频链接生成器在线
  • 网站建设 推广薪资公司网站开发工具
  • 深圳seo网站推广报价电器网站建设策划书
  • 做360网站优化快wordpress5.1下载
  • 深度学习复现:CIFAR-10 数据集任务的实现(测试集)
  • 【Spring 1】Spring IoC:颠覆传统编程的控制反转艺术
  • 如何为网站做面包屑导航网站必须要备案吗
  • AI 动画视频创作:技巧升级与行业未来趋势
  • 数字化转型:概念性名词浅谈(第五十三讲)
  • 制作网站参考案例wordpress推介联盟
  • 当遇到人生低谷期,该怎么度过?别装坚强,熬过去才是真本事
  • 电商网站开发报价单濮阳网站建设陈帅
  • 医联媒体网站建设网站建设网站制作公司
  • Detectron2 - 下一代目标检测与分割算法库
  • CSS过渡效果完全指南
  • 木门行业网站该怎么做封面制作网站
  • AIPyApp - Python 智能执行环境
  • 深度学习中Bootstrap详解
  • 网站关键字优化合同深圳网站制作公司资讯
  • 网络销售型网站有哪些内容百度推广培训机构
  • html制作一个个人主页网站wordpress首页调用指定文章