FreeRTOS深入教程(队列内部机制和源码分析)

文章目录

  • 前言
  • 一、队列结构体分析
  • 二、创建队列
  • 三、读写队列源码分析
    • 1.读队列源码分析
    • 2.写队列源码分析
  • 总结


前言

本篇文章主要来为大家分析队列的内部机制和源码实现。

一、队列结构体分析

在FreeRTOS中队列会使用一个结构体来表示:
在这里插入图片描述
在这里插入图片描述
1.int8_t * pcHead 和 int8_t * pcWriteTo:这些指针指向队列存储区的头部和下一个可写入的位置。队列存储区是一个用于存储队列中数据项的缓冲区。

2.union:这个联合体 u 可以是两种不同类型之一:QueuePointers_t 或 SemaphoreData_t,这允许队列结构用于不同的用途,例如队列或信号量。

3.在QueuePointers_t 结构体中包含pcReadFrom指向当前读位置。

4.List_t xTasksWaitingToSend 和 List_t xTasksWaitingToReceive:这些是用于存储等待发送或接收数据的任务的链表。这些链表按任务的优先级排序,以确保高优先级的任务有更高的访问权。

5.volatile UBaseType_t uxMessagesWaiting:这是队列中当前待处理的数据项数量。

6.UBaseType_t uxLength:这是队列的长度,即它可以容纳的数据项数量,不是字节数。

7.UBaseType_t uxItemSize:这是队列中每个数据项的大小。

8.volatile int8_t cRxLock 和 volatile int8_t cTxLock:这些变量用于跟踪队列的锁状态。它们记录队列是否被锁定,并在锁定时记录发送到队列的数据项数量。

9.uint8_t ucStaticallyAllocated:这个变量用于标志队列内存的分配方式。如果设置为 pdTRUE,表示队列的内存是静态分配的,不应尝试释放内存。

10.struct QueueDefinition * pxQueueSetContainer:这个成员仅在配置中启用了队列集(configUSE_QUEUE_SETS为1)时有效。它指向包含此队列的队列集。

二、创建队列

队列由队列头和队列中的每一个元素组成:

故分配内存时需要包含队列头部和全部元素的大小
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三、读写队列源码分析

读写队列主要涉及到 环形缓冲区、链表,共享资源的访问。

1.读队列源码分析

在写队列时首先需要先禁止任务调度,防止一个任务在写队列时,其他任务也来写队列导致出现错误。

taskENTER_CRITICAL();//禁止任务调度

判断当前队列中消息数量是否小于队列的长度

if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )

如果当前队列中消息数量小于队列的长度,那么就证明还可以写入数据。

调用prvCopyDataToQueue函数往队列中写入数据。

xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );

判断是否有任务在等待数据,如果有任务在等待数据,那么将这个任务从等待接收数据链表中移除,并且唤醒这个任务。

                        if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ){if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ){/* The unblocked task has a priority higher than* our own so yield immediately.  Yes it is ok to do* this from within the critical section - the kernel* takes care of that. */queueYIELD_IF_USING_PREEMPTION();}else{mtCOVERAGE_TEST_MARKER();}}

如果队列已满并且没有设置超时时间或者超时时间到了,那么就会返回错误,并且恢复中断,让任务可以重新调度。

                if( xTicksToWait == ( TickType_t ) 0 ){/* The queue was full and no block time is specified (or* the block time has expired) so leave now. */taskEXIT_CRITICAL();/* Return to the original privilege level before exiting* the function. */traceQUEUE_SEND_FAILED( pxQueue );return errQUEUE_FULL;}

如果设置了超时时间,那么会调用vTaskPlaceOnEventList函数将当前任务挂入xTasksWaitingToSend 链表

        if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ){if( prvIsQueueFull( pxQueue ) != pdFALSE ){traceBLOCKING_ON_QUEUE_SEND( pxQueue );vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );

vTaskPlaceOnEventList函数

void vTaskPlaceOnEventList( List_t * const pxEventList,const TickType_t xTicksToWait )
{configASSERT( pxEventList );/* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE* SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. *//* Place the event list item of the TCB in the appropriate event list.* This is placed in the list in priority order so the highest priority task* is the first to be woken by the event.  The queue that contains the event* list is locked, preventing simultaneous access from interrupts. */vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) );prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
}

2.写队列源码分析

读取队列时也是需要禁止任务调度的,防止多个任务一起读取数据

taskENTER_CRITICAL();

首先判断队列中的数据量是否大于0,如果大于0就将队列中的数据读取出来,并且将uxMessagesWaiting减1。

           const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting;/* Is there data in the queue now?  To be running the calling task* must be the highest priority task wanting to access the queue. */if( uxMessagesWaiting > ( UBaseType_t ) 0 ){/* Data available, remove one item. */prvCopyDataFromQueue( pxQueue, pvBuffer );traceQUEUE_RECEIVE( pxQueue );pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1;

读取完数据后判断是否有任务在等待写数据,如果有任务在等待写数据那么就将这个任务从等待写数据链表中移除

                if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ){if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ){queueYIELD_IF_USING_PREEMPTION();}else{mtCOVERAGE_TEST_MARKER();}}else{mtCOVERAGE_TEST_MARKER();}

如果没有设置超时时间,或者是时间到了那么就返回错误并且退出

                if( xTicksToWait == ( TickType_t ) 0 ){/* The queue was empty and no block time is specified (or* the block time has expired) so leave now. */taskEXIT_CRITICAL();traceQUEUE_RECEIVE_FAILED( pxQueue );return errQUEUE_EMPTY;}

如果设置了超时时间那么就将当前读取数据任务挂入链表当中

        if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ){/* The timeout has not expired.  If the queue is still empty place* the task on the list of tasks waiting to receive from the queue. */if( prvIsQueueEmpty( pxQueue ) != pdFALSE ){traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );prvUnlockQueue( pxQueue );if( xTaskResumeAll() == pdFALSE ){portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}}

总结

本篇文章就讲解到这里,大家可以自己对FreeRTOS的源代码进行分析,分析源代码对学习FreeRTOS有重要的意义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/176138.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

V90PN总线伺服梯形加减速速度控制(标准报文1应用)

V90 PN总线伺服速度控制应用可以利用标准报文1和SinaSpeed功能块实现,具体代码介绍请查看下面相关文章链接,这里不再赘述。 速度随动控制 V90伺服PN总线速度随动控制(手摇轮功能)-CSDN博客文章浏览阅读40次。V90PN总线控制相关内容,请参考下面文章链接:博途1200/1500PLC …

使用tensorflow创建自己的量化金融工具

介绍 在充满活力的金融领域,高频交易 (HFT) 已经成为游戏规则的改变者。高频交易能够在几毫秒内执行数千个订单,利用先进的算法和计算技术实时利用微小的价格差异。随着金融市场的不断发展,支持高频交易策略的工具和框架也必须不断发展。在这一背景下,TF Quant Finance (T…

物联网AI MicroPython传感器学习 之 SHT3X温湿度传感器

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 Sensirion SHT3x-DIS湿度和温度传感器基于CMOSens传感器芯片&#xff0c;更加智能、可靠&#xff0c;精度更高。SHT3x-DIS具有增强的信号处理能力、两个独特的用户可选I2C地址&#xff0c;通信…

JavaScript基础知识19——循环结构:while循环

哈喽&#xff0c;你好&#xff0c;我是雷工。 本节学习JavaScript基础语法的循环结构&#xff1a;while循环&#xff0c;以下为学习笔记。 while循环 循环概念&#xff1a;重复执行一些操作&#xff1b; 循环特征&#xff1a;不断地重复&#xff1b; while&#xff1a;在…期间…

监控浏览器页面展示性能的工具

B/S架构&#xff0c;用户都是使用浏览器访问后端服务&#xff0c;产品在开发时需要关注用户的体验&#xff0c;不仅包含交互的友好&#xff0c;性能指标也非常重要。对于后端开发常见的性能指标&#xff0c;可能包含&#xff1a;reponse time&#xff0c;吞吐量等。此外&#x…

【数据结构】顺序表

今天给大家带来的是顺序表相关知识的分享&#xff0c;喜欢的朋友可以三连一波&#xff01;&#xff01;&#xff01; 顺序表 顺序表的基本结构&#xff1a; 顺序表的实现 我们将顺序表的实现分装成函数大概分为下面几类&#xff1a; //初始化 void InitSL(SL* psl); //打印数…

最新waymo数据集 百度网盘

最新waymo数据集介绍 waymo数据集是有史以来最大&#xff0c;最多样化的自动驾驶数据集&#xff0c;包含 传感器数据边界框数据2D视频全景分割标签关键点标签3D语义分割标签2D和3D边界框的关联 是该领域质量最高、规模最大的数据集之一&#xff0c;用于帮助研究界在机器感知…

管理类联考——英语二——阅读篇——题材:心理

文章目录 2013年&#xff0c;Text 3——题材&#xff1a;心理细节题&#xff08;难&#xff09;细节题——排除法细节题细节题观点态度题 2015 年&#xff0c;Text 1——题材&#xff1a;心理细节题细节题推断题词义句意题细节题 2019 年&#xff0c;Text 1——题材&#xff1a…

c语言练习(9周)

输入样例11输出样例7.0980 #include<stdio.h> int main() {int n, i;double s 1,a1;scanf("%d", &n);for (i 2; i < n; i) {a 1 / (1a);s a;}printf("%.4lf", s);return 0; } 题干输入10个整数&#xff0c;分别按输入正序、逆序显示。输…

TSINGSEE青犀AI视频识别技术+危化安全生产智慧监管方案

一、背景分析 石油与化学工业生产过程复杂多样&#xff0c;涉及的物料易燃易爆、有毒有害&#xff0c;生产条件多高温高压、低温负压&#xff0c;现场危险化学品存储量大、危险源集中&#xff0c;重特大安全事故多发。打造基于工业互联网的安全生产新型能力&#xff0c;提高危…

SaaS 出海,如何搭建国际化服务体系?(一)

防噎指南&#xff1a;这可能是你看到的干货含量最高的 SaaS 出海经验分享&#xff0c;请准备好水杯&#xff0c;放肆食用&#xff08;XD。 当越来越多中国 SaaS 企业选择开启「国际化」副本&#xff0c;出海便俨然成为国内 SaaS 的新角斗场。 LigaAI 观察到&#xff0c;出海浪…

【Python 常用脚本及命令系列 9 -- 图片文字识别 EasyOCR使用】

文章目录 1.1 EasyOCR 介绍1.1.1 EasyOCR 安装1.1.2 EasyOCR 使用方法1.1.2.1 EasyOCR 支持的语言种类1.1.2.2 EasyOCR 支持的图像格式 EasyOCR 提高图片文字识别正确率1.3 问题总结 1.1 EasyOCR 介绍 Python中有一个不错的OCR库-EasyOCR&#xff0c;在GitHub已有9700 star。它…

Stable Diffusion系列(一):古早显卡上最新版 WebUI 安装及简单操作

文章目录 Stable Diffusion安装AnimateDiff插件适配sdxl模型适配 Stable Diffusion使用插件安装界面设置基础文生图加入lora的文生图 Stable Diffusion安装 我的情况比较特殊&#xff0c;显卡版本太老&#xff0c;最高也就支持cuda10.2&#xff0c;因此只能安装pytorch1.12.1&…

十八、模型构建器(ModelBuilder)快速提取城市建成区——批量掩膜提取夜光数据、夜光数据转面、面数据融合、要素转Excel(基于参考比较法)

一、前言 前文实现批量投影栅格、转为整型,接下来重点实现批量提取夜光数据,夜光数据转面、夜光数据面数据融合、要素转Excel。将相关结果转为Excel,接下来就是在Excel中进行阈值的确定,阈值确定无法通过批量操作,除非采用其他方式,但是那样的学习成本较高,对于参考比较…

virtual 关键字中 cv限定符的使用

对于如下定义&#xff1a; struct A { virtual int f( ) { return 1; } } a; struct B: A {int f( ) const { return 2; }int f( ) volatile { return 3; }int f( ) const volatile { return 4; } } c; int main(int argc, char *argv[ ]) { A *p&c; return p->f( ); } …

智慧矿山AI算法助力护帮板支护监测,提升安全与效率

在智慧矿山AI算法系列中&#xff0c;护帮板支护监测是保障矿山安全和提高生产效率的重要环节。护帮板作为矿山支护体系中的重要组成部分&#xff0c;在矿山生产中起到了关键的作用。那么&#xff0c;护帮板在哪种状态下是正常打开的呢&#xff1f;本文将对此进行介绍。 护帮板的…

腾讯云双11云服务器大促优惠活动:超多云服务器优惠惊喜不断!

腾讯云双11大促优惠活动已经拉开帷幕&#xff0c;为广大用户带来了一系列的超值优惠。活动时间从现在起一直延续到2023年11月30日23:59:59&#xff0c;让用户有足够的时间去选择和购买心仪的产品。活动入口链接为https://1111.mian100.cn&#xff0c;点击链接即可进入活动页面。…

多输入多输出 | Matlab实现k-means-LSTM(k均值聚类结合长短期记忆神经网络)多输入多输出组合预测

多输入多输出 | Matlab实现k-means-LSTM&#xff08;k均值聚类结合长短期记忆神经网络&#xff09;多输入多输出组合预测 目录 多输入多输出 | Matlab实现k-means-LSTM&#xff08;k均值聚类结合长短期记忆神经网络&#xff09;多输入多输出组合预测预测效果基本描述程序设计参…

smartLink HW-DP新版提供更多扩展功能——用于PROFIBUS和HART系统中物联网集成

Softing工业自动化的smartLink HW-DP网关可独立于控制器访问PROFIBUS DP网络&#xff0c;且新发布的1.30固件版本还提供了更多数据连接和传输的扩展功能。 smartLink HW-DP可无缝集成到PROFIBUS网络中&#xff0c;而不会影响现有设备的运行。该网关还可为新的和现有的PROFIBUS …

【网络安全 --- 任意文件上传漏洞靶场闯关 6-15关】任意文件上传漏洞靶场闯关,让你更深入了解文件上传漏洞以及绕过方式方法,思路技巧

一&#xff0c;工具资源下载 百度网盘资源下载链接地址&#xff1a; 百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan…