【FreeRTOS】队列集实验-改进程序框架(思路)


0 前言

学习视频:
【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS(FreeRTOS教程 基于STM32,以实际项目为导向)】 【精准空降到 00:34】 https://www.bilibili.com/video/BV1Jw411i7Fz/?p=32&share_source=copy_web&vd_source=8af85e60c2df9af1f0fd23935753a933&t=34


参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》


1 队列集

1.1 创建队列集

函数原型如下:

QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength )
参数说明
uxQueueLength队列集长度,最多能存放多少个数据(队列句柄)
返回值非0:成功,返回句柄,以后使用句柄来操作队列NULL:失败,因为内存不足

1.2 把队列加入队列集

函数原型如下:

BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,

                QueueSetHandle_t xQueueSet );
参数说明
xQueueOrSemaphore队列句柄,这个队列要加入队列集
xQueueSet队列集句柄
返回值pdTRUE:成功pdFALSE:失败

1.3 读取队列集

函数原型如下:

QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
                        TickType_t const xTicksToWait );
参数说明
xQueueSet队列集句柄
xTicksToWait如果队列集空则无法读出数据,可以让任务进入阻塞状态,xTicksToWait表示阻塞的最大时间(Tick Count)。如果被设为0,无法读出数据时函数会立刻返回;如果被设为portMAX_DELAY,则会一直阻塞直到有数据可写
返回值NULL:失败,队列句柄:成功

2 程序框架思路

2.1思路

来源:https://rtos.100ask.net/zh/FreeRTOS/DShanMCU-F103/chapter11.html#_11-5-%E9%98%9F%E5%88%97%E9%9B%86

在这里插入图片描述

假设有2个输入设备:红外遥控器、旋转编码器,它们的驱动程序应该专注于“产生硬件数据”,不应该跟“业务有任何联系”。比如:红外遥控器驱动程序里,它只应该把键值记录下来、写入某个队列,它不应该把键值转换为游戏的控制键。在红外遥控器的驱动程序里,不应该有游戏相关的代码,这样,切换使用场景时,这个驱动程序还可以继续使用。

把红外遥控器的按键转换为游戏的控制键,应该在游戏的任务里实现。

假设我们增加一个MPU6050的输入,那就需要创建一个MPU6050的数据解析任务,每增加一个设备,就要增加这样的一个任务,如果很多设备,那就是很多任务,栈会不够用!怎么解决呢?

在这里插入图片描述

支持多个输入设备时,我们需要实现一个“InputTask”,它读取各个设备的队列,得到数据后再分别转换为游戏的控制键。

在这里插入图片描述
这样操作好处就是,不管有多少设备,都只需要一个InputTask任务来读取队列,去处理数据

InputTask如何及时读取到多个队列的数据?要使用队列集。

  • 轮询
  • 队列集

2.2 轮询

在这里插入图片描述
读队列1,如果有数据就处理,读队列2,如果有数据就处理,读队列3,如果有数据就处理。
问题就来了!

当我读取队列1的时候,能否指定超时时间?
不可以指定超时时间,只能为0!
假设读取队列1时候没有数据,超时时间指定为30min,30min后没有数据,超时退出,才能读取队列2,队列3----这样导致读取队列2,队列3的时间被推迟,不够及时,使这个任务不断运行,一直没有阻塞状态极大浪费CPU资源

2.3 队列集

队列集的本质也是队列,只不过里面存放的是队列句柄。使用过程如下:

  • 创建队列A,它的长度是n1
  • 创建队列B,它的长度是n2
  • 创建队列集S,它的长度是“n1+n2
  • 把队列A、B加入队列集S
  • 这样,写队列A的时候,会顺便把队列A的句柄写入队列集S
  • 这样,写队列B的时候,会顺便把队列B的句柄写入队列集S
  • InputTask先读取队列集S,它的返回值是一个队列句柄,这样就可以知道哪个队列有有数据了;然后InputTask再读取这个队列句柄得到数据

在这里插入图片描述

有了这个队列集,我们在InputTask中的任务就简单了:

  1. 读队列集,得到队列句柄
  2. 读句柄,得到数据
  3. 处理数据,写入挡球板队列

思路就清晰明了了
在这里插入图片描述

3 示例: 使用队列集改善程序框架

本节代码为:15_queueset_game。

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北国无红豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值