UCOS-III笔记(六)
作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习
擅长领域:驱动开发,嵌入式软件开发,BSP开发
作者主页:一个平凡而乐于分享的小比特的个人主页
文章收录专栏:UCOS-III,本专栏为UCOS-III学习记录
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖
UCOS-III笔记(六)
消息队列
队列是任务到任务、中断到任务的数据交流的一种机制(消息传递)
在OS中如果使用全局变量存在弊端:数据无保护,导致数据不安全,当多个任务同时对该变量操作时,数据易受损


写队列:
OSQPost( )
{// 进入临界区(关中断)写队列实际操作// 退出临界区(开中断)
}
读队列:
OSQPend( )
{// 进入临界区(关中断)读队列实际操作// 退出临界区(开中断)
}
队列:读写队列做好了保护,防止多任务同时访问冲突;我们只需要直接调用API函数即可,简单易用!
特点:
-
数据入队出队方式
队列通常采用“先进先出”(FIFO)的数据存储缓冲机制,即先入队的数据会先从队列中被读取,UCOSIII中也可以配置为“后进先出”LIFO方式
-
数据传输方式
UCOSIII的队列数据是一个“万能指针”,可以指向任何数据,甚至是函数,所以发送方和接收方必须按照约定好的方式去发送和接收消息,这样才能正常解析接收到的消息
-
多任务访问
队列不属于某个任务,任何任务和中断都可以向队列发送消息,但是读取消息只能在任务中,不支持中断读取消息
-
出队阻塞
当任务向一个队列读取消息时,可以指定一个阻塞时间,假设此时当队列没有数据时无法读取。
①若阻塞时间 = 0 :死等,一直等到可以队列有数据可以出队为止;
①若阻塞时间 > 0 :等待设定的阻塞时间,若在该时间内还未接收到数据,超时后直接返回不再等待;
注意:写队列不支持阻塞,读队列支持阻塞
队列相关API函数介绍
队列的主要流程:创建队列 -->写队列 --> 读队列
| 函数 | 描述 |
|---|---|
| OSQCreate() | 创建一个消息队列 |
| OSQDel() | 删除一个消息队列 |
| OSQFlush() | 清空消息队列中的所有消息 |
| OSQPend() | 获取消息队列中的消息 |
| OSQPendAbort() | 终止任务挂起等待消息队列 |
| OSQPost() | 发送消息到消息队列 |
OSQCreate():创建一个消息队列
void OSQCreate( OS_Q* p_q, //指向消息队列结构体的指针CPU_CHAR* p_name, //指向作为消息队列名的 ASCII 字符串的指针OS_MSG_QTY max_qty, //消息队列的大小OS_ERR* p_err //指向接收错误代码变量的指针)
OSQPost():发送消息到消息队列中
void OSQPost( OS_Q* p_q, //指向消息队列结构体的指针void* p_void, //指向消息的指针OS_MSG_SIZE msg_size, //消息的大小,单位: 字节OS_OPT opt, //函数操作选项://OS_OPT_POST_FIFO :将发送的消息保存在队列的末尾 //OS_OPT_POST_LIFO :将发送的消息保存在队列的开头//OS_OPT_POST_ALL :将消息发送给所有等待该消息的任务 //OS_OPT_POST_NO_SCHED :禁止在本函数内执行任务调度//以上的几种类型可以进行组合OS_ERR* p_err //指向接收错误代码变量的指针)
OSQPend():获取消息队列中的消息
void * OSQPend ( OS_Q* p_q, //指向消息队列结构体的指针OS_TICK timeout, //任务挂起等待消息队列的最大允许时间,当为0时,表示将一直等待,直到接收到消息OS_OPT opt, //OS_OPT_PEND_BLOCKING :如果没有任何消息存在的话就阻塞任务//OS_OPT_PEND_NON_BLOCKING :如果消息队列没有任何消息的话任务就直接返回OS_MSG_SIZE* p_msg_size, //指向一个变量用来表示接收到的消息长度(字节数)CPU_TS* p_ts, //指向接收消息队列接收时的时间戳的变量的指针,为NULL,说明用户没有要求时间戳OS_ERR* p_err //指向接收错误代码变量的指针)
