侧边栏壁纸
博主头像
thinkTV博主等级

喜爱动漫的二刺螈一枚,摩托车云爱好者(快要有车了)。 懂一点技术的在读生物医学工程研究生( •̀ ω •́ )✧,多多指教。

  • 累计撰写 127 篇文章
  • 累计创建 17 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

UCOSIII消息队列

thinkTV
2023-07-18 / 0 评论 / 0 点赞 / 269 阅读 / 756 字 / 正在检测是否收录...

1. 队列简介

队列是任务到任务、中断到任务的数据交流的一种机制(消息传递)

假设有一个全局变量a = 0,现有两个任务都在写这个变量a,数据有受损风险。

图片-1689687680114

全局变量的弊端: 数据无保护,导致数据不安全,当多个任务同时对该变量操作时,数据易受损。

1.1 使用队列的情况

图片-1689688065776

写队列:

OSQPost( )
{
      // 进入临界区(关中断)
       写队列实际操作
      // 退出临界区(开中断)
}

读队列:

OSQPend( )
{
      // 进入临界区(关中断)
       读队列实际操作
      // 退出临界区(开中断)
}
  • 读写队列做好了保护,防止多任务同时访问冲突;
  • 我们只需要直接调用API函数即可,简单易用!
  • 中断不可以调用队列接收函数,但是可以调用队列发送函数(中断可以写但不能读)

1.2 UCOSIII队列特点

数据入队出队方式

队列通常采用“先进先出”(FIFO)的数据存储缓冲机制,即先入队的数据会先从队列中被读取,UCOSIII中也可以配置为“后进先出”LIFO方式;

数据传输方式

UCOSIII的队列数据是一个“万能指针”,可以指向任何数据,甚至是函数,所以发送方和接收方必须按照约定好的方式去发送和接收消息,这样才能正常解析接收到的消息

多任务访问

队列不属于某个任务,任何任务和中断都可以向队列发送消息,但是读取消息只能在任务中,不支持中断读取消息

出队阻塞

当任务向一个队列读取消息时,可以指定一个阻塞时间,假设此时当队列没有数据时无法读取

  • 若阻塞时间 = 0:死等,一直等到可以队列有数据可以出队为止;
  • 若阻塞时间 > 0:等待设定的阻塞时间,若在该时间内还未接收到数据,超时后直接返回不再等待;

注意:入队(发送消息队列)不会阻塞!

2. 队列相关API函数介绍

使用队列的主要流程:创建队列 ->写队列(发送消息到队列) ->读队列(获取消息队列的数据)。

图片-1689689197652

创建消息队列函数

void OSQCreate(	   OS_Q* 			p_q,
		CPU_CHAR* 		p_name,
		OS_MSG_QTY 		max_qty,
		OS_ERR* 			p_err		) 

图片-1689691138921

发送消息到消息队列中函数

void  OSQPost(  	OS_Q*		p_q,
			void* 			p_void,
			OS_MSG_SIZE	msg_size,
			OS_OPT 		opt,
			OS_ERR* 		p_err	) 

图片-1689691190741

获取消息队列中的消息函数

void * OSQPend (	OS_Q* 		p_q,
			OS_TICK 		timeout,
			OS_OPT 		opt,
			OS_MSG_SIZE*	p_msg_size,
			CPU_TS* 		p_ts,
			OS_ERR* 		p_err   ) 

图片-1689691227768

0

评论区