FreeRTOS 队列_freertos队列-程序员宅基地

技术标签: c语言  FreeRTOS  单片机  

目录

一、队列的基础知识

1、什么是队列

2、队列的数据存储

3、多任务访问

4、出队阻塞

5、入队阻塞

6、队列操作过程图示

二、队列的操作

1、队列的创建

2、向队列发送消息

3、从队列读取消息

三、队列操作实验

1、在初始化处创建队列

2、在任务处往队列发送消息

3、在另一个任务读取队列消息

四、中断调用FreeRTOS的API函数

1、pxHigherPriorityTaskWoken 参数的作用:

2、实际应用中,中断方式的消息机制要注意以下四个问题:


一、队列的基础知识

1、什么是队列

(1)队列的作用是在任务与任务、任务与中断之间传递消息

(2)队列中可以存储有限的、大小固定的数据项目。

(3)队列所能保存的最大数据项目数量叫做队列的长度,创建队列的时候会指定数据项目的 大小队列的长度

(4)由于队列用来传递消息的,所以也称为消息队列。

2、队列的数据存储

(1)通常队列采用先进先出(FIFO)的存储缓冲机制。

(2)数据发送到队列中就是将要发送的数据拷贝到队列中,这就意味着在队列中存储的是数 据的原始值,而不是原数据的引用(即只传递数据的指针),这个也叫做值传递。

(3)采用值传递的话虽然会导致数据拷贝,会浪费一点时间,但是一旦将消息发送到队列中原始的数据缓冲区就可以删除掉或者覆写,这样的话这些缓冲区就可以被重复的使用。 

(4)数据拷贝也可以使用引用来传递消息,直接往队列中发送指向这个消息的地址指针;当要发送的消息数据太大的时候就可以直接发送消息缓冲区的地址指针,比如在网络应用环境中的数据量往往都很大的,采用数据拷贝的话就不现实。

3、多任务访问

队列不是属于某个特别指定的任务的,任何任务都可以向队列中发送消息,或者从队列中提取消息。

4、出队阻塞

        当任务尝试从一个队列中读取消息的时候可以指定一个阻塞时间,这个阻塞时间就是当任务从队列中读取消息无效的时候任务阻塞的时间。阻塞时间单位是时钟节拍数。阻塞时间会有如下三种情况:

(1)阻塞时间为0:就是不阻塞,当任务没有从队列中获取到消息的话就马上返回任务继续 执行接下来的代码。

(2)阻塞时间为0-portMAX_DELAY:当任务没有从队列中获取到消息的话就进入阻塞态,阻塞 时间指定了任务进入阻塞态的时间,当阻塞时间到了以后还没有接收到数据的话就退出 阻塞态,返回任务接着运行下面的代码,如果在阻塞时间内接收到了数据就立即返回,执 行任务中下面的代码。

(3)阻塞时间为portMAX_DELAY:任务就会一直进入阻塞态等待,直到接收到数据为止。

5、入队阻塞

        入队说的是向队列中发送消息,将消息加入到队列中。和出队阻塞一样,当一个任务向队列发送消息的话也可以设置阻塞时间。比如任务B向消息队列Q发送消息,但是此时队列Q是满的,那肯定是发送失败的。此时任务B就会遇到和上面任务A一样的问题,这两种情况的处理过程是类似的,只不过一个是向队列Q发送消息,一个是从队列Q读取消息而已。

6、队列操作过程图示

(1)创建队列

        任务A要向任务B发送消息,这个消息是x变量的值。首先创建一个队列,并且指定队列的长度每条消息的长度。这里我们创建了一个长度为4 的队列,因为要传递的是x值,而x是个int类型的变量,所以每条消息的长度就是int类型的长度,在STM32中就是4字节,即每条消息是 4 个字节的。

(2)向队列发送第一个消息

        任务A的变量x值为10,将这个值发送到消息队列中。此时队列剩余长度就是3了。前面说了向队列中发送消息是采用拷贝的方式,所以一旦消息发送完成变量x就可以再次被使用,赋其他的值。

(3)向队列发送第二个消息

任务A又向队列发送了一个消息,即新的x的值,这里是20。此时队列剩余长度为 2。

(4)从队列中读取消息

        任务B从队列中读取消息,并将读取到的消息值赋值给y,这样y就等于10了。任务B从队列中读取消息完成以后可以选择清除掉这个消息或者不清除。当选择清除这个消息的话其他任务或中断就不能获取这个消息了,而且队列剩余大小就会加一,变成3。如果不清除的话其他任务或中断也可以获取这个消息,而队列剩余大小依旧是2。

二、队列的操作

1、队列的创建

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

(1)动态创建:队列的内存在函数内部动态分配

QueueHandle_t xQueuecreate(UBaseType_t uxQueueLength, UBaseType_t  uxItemsize );

参数

说明

uxQueueLength

队列长度,最多能存放多少个数据(item)

uxltemSize

每个数据(item)的大小:以字节为单位

返回值

非0:成功,返回句柄,以后使用句柄来操作队列NULL:失败,因为内存不足

(2)静态创建:队列的内存要事先分配好

QueueHandle_t xQueueCreatestatic(UBaseType_t uxQueueLength,

UBaseType_t uxItemsize,uint8_t *pucQueueStorageBuffer,

StaticQueue_t *pxQueueBuffer);

参数

参数

uxQueueLength

队列长度,最多能存放多少个数据(item)

uxltemSize

每个数据(item)的大小:以字节为单位

pucQueueStorageBuffer

如果uxltemSize非0,

pucQueueStorageBuffer必须指向一个pucQueueStorageBufferuint8_t数组,此数组大小至少为"uxQueueLength * uxltemSize"

pxQueueBuffer

必须执行一个StaticQueue_t结构体,用来保存队列的数据结构

返回值

非0:成功,返回句柄,以后使用句柄来操作队列NULL:失败,因为pxQueueBuffer为NULL

2、向队列发送消息

3、从队列读取消息

三、队列操作实验

1、在初始化处创建队列

2、在任务处往队列发送消息

3、在另一个任务读取队列消息

四、中断调用FreeRTOS的API函数

1、pxHigherPriorityTaskWoken 参数的作用:

        这种 xxxxFromISR() 的API会有一个 BaseType_t *pxHigherPriorityTaskWoken 参数,用来判断是否有更高优先级任务被唤醒,再由 ISR 自己决定是否要作任务切换。

        对于队列以及使用队列机制的信号量、互斥量等,在中断服务程序中调用了这些API函数,将任务从阻塞中解除,调度器?判断解除的任务优先级是否大于当前任务的优先级,如果解除的任务优先级更高,会将变量xYieldPending设置为pdTRUE。在下一次系统节拍中断服务函数中,触发一次任务切换。

2、实际应用中,中断方式的消息机制要注意以下四个问题:

(1)中断函数的执行时间越短越好,防止其它低于这个中断优先级的异常不能得到及时响应。

(2)实际应用中,建议不要在中断中实现消息处理,用户可以在中断服务程序里面发送消息通知任务,在任务中实现消息处理,这样可以有效地保证中断服务程序的实时响应。同时此任务也需要设置为高优先级,以便退出中断函数后任务可以得到及时执行。

(3)中断服务程序中一定要调用专用于二值信号量设置函数,即以 FromISR 结尾的函数。

(4)如果 FreeRTOS 工程的中断函数中调用了 FreeRTOS 的二值信号量的 API 函数,退出的时候要检测是否有高优先级任务就绪,如果有就绪的,需要在退出中断后进行任务切换。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Calmer_/article/details/136380911

智能推荐

ai Devin-程序员宅基地

文章浏览阅读345次,点赞5次,收藏5次。近期,全球首位AI程序员Devin的出场,不禁让我想到了一个有趣的问题:AI程序员会不会抢程序员的饭碗呢?先别着急下结论!虽然AI技术在编程领域越来越广泛,但它真的能完全替代我们程序员吗?

Oracle笔记-USRS01.DBF文件过大,解决办法_users01.dbf很大-程序员宅基地

文章浏览阅读2.2k次。在客户那边跑了1年多的程序没有出现问题,在公司弄了个开发环境,隔个几个星期就出一次问题。发现是公司这边缺乏运维人员造成的,说明都是靠开发自己干。一个字累。这次,家里面测试环境突然间异常了,程序还在运行,但反应相当迟钝。最后查了下,搭建Oracle的那台机器只有几百MB的空间了。发现一个USERS01.DBF的文件巨大,差不多30多GB了。因为是家里面的测试环境,这里可以乱搞下。alter database datafile 'C:\contnet\oradata\ORCL\USE._users01.dbf很大

mysql死锁问题_所谓死锁,是指两个或两个以上的进程在执行过程中争夺资源而造成的一种___________-程序员宅基地

文章浏览阅读156次。死锁(Deadlock)所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。 一种情形,此时执行程序中两个..._所谓死锁,是指两个或两个以上的进程在执行过程中争夺资源而造成的一种___________

【PTA:】 Error: class X is public should be declared in a file named X.java_pta 平台 main.java:2: error: class chickenproblem is-程序员宅基地

文章浏览阅读1.8w次,点赞62次,收藏61次。java初学者蜜桃弟弟今天在PTA上写题目,一直出现这个错误。 Error: class X is public should be declared in a file named X.java搜了很多如下的解决办法: Java的类名与文件名必须一致 https://blog.csdn.net/u010892841/article/details/70..._pta 平台 main.java:2: error: class chickenproblem is public, should be decla

【科普】显示器连接线有哪几种都长什么样子_显示器连接线有几种-程序员宅基地

文章浏览阅读1.1w次。显示器连接线有3种 HDMI连接线、VGA连接线、DVI连接线、DP连接线。1、DPDP(DisplayPort)是第一个依赖数据包化数据传输技术的显示通信端口,这种数据包化传输技术可以在以太网、USB和PCI Express等技术中找到。它既可以用于内部显示连接,也可以用于外部的显示连接。DP(DisplayPort)与HDMI接口类似,支持视频和音频同时传输。部分版本支持USB接口、type-C兼容HDMI、DVI旧型号接口,相比HDMI拥有更高的带宽。 DP1.4最高达32.4Gbps的带宽,可_显示器连接线有几种

PyQt中QComBox自定义属性,并能够获得所选内容的复选框_qt combox通过自定义数据获取当前文本-程序员宅基地

文章浏览阅读1.5k次。网上找不到合适的自定义item内容并能够获得复选内容的combox,所以自己写了个,有需要的直接拿去用即可:from PyQt5.QtWidgets import QComboBox, QLineEdit, QListWidget, QCheckBox, QListWidgetItemfrom PyQt5 import QtWidgetsimport sysclass ComboCheck..._qt combox通过自定义数据获取当前文本

随便推点

XML解析之DOM解析_dom解析xml-程序员宅基地

文章浏览阅读2.4k次,点赞3次,收藏19次。xml文件的DOM解析_dom解析xml

STC16f40k128 使用VOFA+进行电机PID参数整定_vofa 电机闭环-程序员宅基地

文章浏览阅读4.9k次,点赞10次,收藏108次。VOFA+是一个串口调试助手,但凭它简单的通信协议、数据可视化以及频域分析,三维打印等优点在众多串口调试助手中脱颖而出。就凭一个打印波形,屁颠屁颠就冲这软件来了。_vofa 电机闭环

NTP注意事项_localhost: timed out, nothing received-程序员宅基地

文章浏览阅读3.1k次。NTP注意事项注意一:首先是关于时区的问题,经度的零点在 Greenwich,因此就有了 GMT(Greenwich Mean Time) 的概念,GMT 以东的快(+),以西的慢(-),比如大陆就是 GMT+8,也就是比 GMT 快 8 h。GMT 为 0 点的时候,大陆已经早上 8 点了。然后还有个国际日期变更线的问题,这个在太平洋上,也就是精读为 180 的那_localhost: timed out, nothing received

BZOJ 2151 种树(可反悔贪心,链表)【BZOJ千题计划】就图一乐_bzoj 链表-程序员宅基地

文章浏览阅读453次。【BZOJ修复计划 #16】BZOJ 2151 种树【国家集训队2011】_bzoj 链表

mybatis源码编译的一些坑_could not compute the year of the last git commit -程序员宅基地

文章浏览阅读822次。  讲道理,如果mybatis和mybatis-parent的版本号一致的话,大概率是不会遇到坑的。但是不排除某些人的自残倾向,非要用不同版本的mybatis和mybatis-parent,这样的话可能会遇到以下这些坑:“cannot resolve plugins xxx”的问题:导致这个问题的原因是没有指定插件的版本号,在pom文件中为相应插件指定version即可,例如:或者干脆注释掉:“Cannot resolve plugin org.apache.maven.plugins:mav_could not compute the year of the last git commit for file

Linux上ftp传输文件怎么改名,Linux Ftp上传文件变更(MD5值变更)-程序员宅基地

文章浏览阅读1.5k次。最近遇到一个很棘手的问题. 问题很简单:一般情况下使用ftp上传就是这个样子:如下脚本:$ vim copy.sh#! /bin/bashremote_path=远程地址if [ -f $1 ]thenftp -i -n <open ftp服务器user 账户名 密码put $1 $remote_path$1quitUPLOADfi这是文本文件内容. vim会默认在文件末尾追加\n$ vim..._ftp linux 重命名文件

推荐文章

热门文章

相关标签