2025年阻塞队列(阻塞队列在内存还是外存)

阻塞队列(阻塞队列在内存还是外存)队列 queue 可以用于 任务到任务 任务到中断 中断到任务 直接传输信息 本章涉及如下内容 11 1 队列的特性 1 1 1 常规操作 队列的简化操如入下图所示 从此图可知 也可以强制写队列头部 覆盖头部数据 更详细的操作入下图所示 11 1 2 传输数据的两种方法

大家好,我是讯享网,很高兴认识大家。



队列(queue)可以用于"任务到任务"、"任务到中断"、"中断到任务"直接传输信息。

本章涉及如下内容:

    11.1 队列的特性

    1.1.1 常规操作

    队列的简化操如入下图所示,从此图可知:

      也可以强制写队列头部:覆盖头部数据

      更详细的操作入下图所示:

      11.1.2 传输数据的两种方法

      使用队列传输数据时有两种方法:

        FreeRTOS使用拷贝值的方法,这更简单:

          #

          11.1.3 队列的阻塞访问

          只要知道队列的句柄,谁都可以读、写该队列。任务、ISR都可读、写队列。可以多个任务读写队列。

          任务读写队列时,简单地说:如果读写不成功,则阻塞;可以指定超时时间。口语化地说,就是可以定个闹钟:如果能读写了就马上进入就绪态,否则就阻塞直到超时。

          某个任务读队列时,如果队列没有数据,则该任务可以进入阻塞状态:还可以指定阻塞的时间。如果队列有数据了,则该阻塞的任务会变为就绪态。如果一直都没有数据,则时间到之后它也会进入就绪态。

          既然读取队列的任务个数没有限制,那么当多个任务读取空队列时,这些任务都会进入阻塞状态:有多个任务在等待同一个队列的数据。当队列中有数据时,哪个任务会进入就绪态?

            跟读队列类似,一个任务要写队列时,如果队列满了,该任务也可以进入阻塞状态:还可以指定阻塞的时间。如果队列有空间了,则该阻塞的任务会变为就绪态。如果一直都没有空间,则时间到之后它也会进入就绪态。

            既然写队列的任务个数没有限制,那么当多个任务写"满队列"时,这些任务都会进入阻塞状态:有多个任务在等待同一个队列的空间。当队列中有空间时,哪个任务会进入就绪态?

              11.2 队列函数

              使用队列的流程:创建队列、写队列、读队列、删除队列。

              11.2.1 创建

              队列的创建有两种方法:动态分配内存、静态分配内存,

                函数原型如下:

                  函数原型如下:

                  示例代码:

                  11.2.2 复位

                  队列刚被创建时,里面没有数据;使用过程中可以调用 xQueueReset() 把队列恢复为初始状态,此函数原型为:

                  11.2.3 删除


                  讯享网

                  删除队列的函数为 vQueueDelete() ,只能删除使用动态方法创建的队列,它会释放内存。原型如下:

                  11.2.4 写队列

                  可以把数据写到队列头部,也可以写到尾部,这些函数有两个版本:在任务中使用、在ISR中使用。函数原型如下:

                  这些函数用到的参数是类似的,统一说明如下:

                  11.2.5 读队列

                  使用 xQueueReceive() 函数读队列,读到一个数据后,队列中该数据会被移除。这个函数有两个版本:在任务中使用、在ISR中使用。函数原型如下:

                  参数说明如下:

                  11.2.6 查询

                  可以查询队列中有多少个数据、有多少空余空间。函数原型如下:

                  11.2.7 覆盖/偷看

                  当队列长度为1时,可以使用 xQueueOverwrite() 或 xQueueOverwriteFromISR() 来覆盖数据。

                  注意,队列长度必须为1。当队列满时,这些函数会覆盖里面的数据,这也以为着这些函数不会被阻塞。

                  函数原型如下:

                  如果想让队列中的数据供多方读取,也就是说读取时不要移除数据,要留给后来人。那么可以使用"窥视",也就是xQueuePeek()或xQueuePeekFromISR()。这些函数会从队列中复制出数据,但是不移除数据。这也意味着,如果队列中没有数据,那么"偷看"时会导致阻塞;一旦队列中有数据,以后每次"偷看"都会成功。

                  函数原型如下:

                  11.3 示例: 队列的基本使用

                  本节代码为:13_queue_game。以前使用环形缓冲区传输红外遥控器的数据,本程序改为使用队列。

                  11.3.1 程序框架

                  01_game_template使用轮询的方式从环形缓冲区读取红外遥控器的键值,13_queue_game把环形缓冲区改为队列。

                  13_queue_game程序的框架如下:

                  game1_task:游戏的主要逻辑判断,每次循环就移动一下球,判断球是否跟边沿、砖块、挡球板相碰,进而调整球的移动方向、消减砖块、统计分数。

                  platform_task:挡球板任务,根据遥控器左右移动挡球板。

                  IRReceiver_IRQ_Callback解析出遥控器键值后,写队列g_xQueuePlatform。

                  第15行是原来的代码,它使用轮询的方式读取遥控键值,效率很低。

                  第16行开始改为读取队列,如果没有数据,挡球板任务阻塞,在第16行的函数里不出来;当IRReceiver_IRQ_Callback中断回调函数把数据写入队列后,挡球板任务马上被唤醒,从第16行的函数里出来,继续执行后续代码。

                  11.3.3 上机实验

                  烧录程序后,使用红外遥控器的左、右按键移动挡球板。

                  11.4 示例: 使用队列实现多设备输入

                  本节代码为:14_queue_game_multi_input。

                  11.5 队列集

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

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

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

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

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

                    11.5.1 创建队列集

                    函数原型如下:

                    car1_task、car2_task、car3_task:创建自己的队列,并注册给devicesirdadev_irda.c;读取队列,根据遥控器键值移动汽车。

                    IRReceiver_IRQ_Callback解析出遥控器键值后,写多个队列。

                    11.7.3 上机实验

                    烧录程序后,使用红外遥控器的1、2、3按键分别移动三辆汽车。

                    小讯
                    上一篇 2025-05-06 09:14
                    下一篇 2025-05-14 14:29

                    相关推荐

                    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
                    如需转载请保留出处:https://51itzy.com/kjqy/140230.html