1.FreeRTOS简介
2.FreeRTOS系列教程(六):如何使用队列集
3.FreeRTOS:消息队列的队列队列应用场景
4.正点原子FreeRTOS——内存管理
5.FreeRTOS-内存管理总结
6.Freertos(4)----信号量
FreeRTOS简介
FreeRTOS,一个专为小型嵌入式系统设计的源码源码迷你操作系统内核,它的队列队列存在旨在提供基础的系统功能。它的源码源码核心特性包括任务管理、精准的队列队列时间管理、信号量机制、源码源码服饰箱包商城源码下载消息队列服务以及内存和记录功能,队列队列这些使得它在资源有限的源码源码小型系统中展现出强大的适应性。[1] 由于实时操作系统对系统资源,队列队列特别是源码源码RAM的需求,像μC/OS-II、队列队列embOS和salvo这样的源码源码RTOS能够在小容量RAM的单片机上运行,而FreeRTOS就是队列队列其中之一。相比于商业的源码源码μC/OS-II和embOS,FreeRTOS的队列队列一大亮点是其开源的性质,用户可以自由获取和使用源代码。此外,它还具有高度的可移植性和可裁剪性,开发者可以根据项目需求灵活定制和移植到各种类型的单片机上。目前,FreeRTOS的最新版本为7.4.0,这表明其持续更新和优化,以满足不断变化的嵌入式系统需求。扩展资料
在嵌入式领域中,嵌入式实时操作系统正得到越来越广泛的应用。采用嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,更好地保证系统的实时性和可靠性。FreeRTOS系列教程(六):如何使用队列集
本文主要探讨FreeRTOS中的队列集功能,如何在多任务环境下实现高效的消息传递和信号处理。队列集允许任务同时等待多个队列或信号量,解决单一资源等待可能导致的阻塞问题。
在传统的FreeRTOS实现中,任务只能逐一处理消息队列或信号量。例如,任务A需要接收消息并获取信号量,如果消息队列无数据,信号量未释放,任务A会阻塞。队列集的flash 图片 源码引入则提供了解决方案:创建一个队列集,任务A不断从队列集中获取消息,根据句柄类型(队列或信号量)执行相应操作,这样就能确保任务在收到任何类型的事件时都能立即响应,避免了阻塞。
队列集的使用涉及几个关键API函数,如xQueueCreateSet()用于创建队列集,xQueueAddToSet()和xQueueRemoveFromSet()用于添加和删除队列,xQueueSelectFromSet()用于从队列集中获取消息。通过这些函数,可以灵活地管理任务之间的通信。
接下来,我们通过一个实验展示了队列集的应用。创建三个任务,任务1优先级最高,用于接收队列集中的消息。实验结果显示,任务能及时响应队列或信号量的变化,无论消息队列还是二值信号量,都能使任务从阻塞状态恢复。
总结来说,队列集是FreeRTOS中提升任务协作效率的重要工具,它扩展了任务的并发处理能力,降低了阻塞风险。如果你对队列集的使用还有疑问,欢迎在评论区交流。感谢你的关注与支持,如果你需要相关源码或学习资料,可关注微信公众号:硬件电子与嵌入式小栈,获取更多信息和资源。
FreeRTOS:消息队列的应用场景
FreeRTOS消息队列在发送不定长消息的场合中广泛应用,特别是任务间的信息交换。作为FreeRTOS的主要任务间通讯手段,消息队列不仅能用于任务与任务之间,还能在中断与任务间传递信息。
对于大型消息,将其地址作为消息进行发送和接收。发送到队列的消息通过拷贝方式实现,队列存储原始数据,而非数据引用。
发送消息时,若队列允许入队,喝水app源码发送任务即可成功。当队列空间不足时,系统依据用户设定的阻塞时间将任务阻塞。若超时仍无法入队,发送任务将收到错误码,解除阻塞状态。
若多个任务因消息队列阻塞,这些任务将按优先级排序,优先级高的任务优先访问队列。当队列消息耗尽,读取消息的任务被阻塞,直至队列有消息可用或超时。等待期间,若其他任务向队列写入消息,被阻塞任务有机会读取并解除阻塞。
综上所述,FreeRTOS消息队列提供灵活可靠的信息传递方式,适用于嵌入式系统、实时控制和多任务处理等多种场景。
正点原子FreeRTOS——内存管理
FreeRTOS内存管理简介
在使用FreeRTOS创建任务、队列、信号量等对象时,一般提供两种方法:动态方法创建和静态方法创建。动态方法创建自动从FreeRTOS管理的内存堆中申请创建对象所需的内存,并在对象删除后,将这块内存释放回FreeRTOS管理的内存堆。静态方法创建则需要自行提供内存空间,这些任务、队列被删除后,这些内存空间也没有其他用途。动态方式更灵活,但FreeRTOS提供多种动态内存管理算法,可根据不同嵌入式系统需求选择。
FreeRTOS内存管理算法
正点原子的例程中,均使用heap_4内存管理算法。heap_1算法只实现了pvPortMalloc,没有实现vPortFree,只能申请内存,无法释放内存。如果工程中创建的任务、队列、.xml文件源码信号量等无需删除,可以使用heap_1算法。heap_1实现最简单,管理的内存堆是一个数组,申请内存时从数组中分出合适大小的内存。heap_2使用最适应算法,并支持释放内存,但无法将相邻空闲内存块合并成一个大的空闲内存块,会产生内存碎片。heap_4使用首次适应算法,支持内存申请、释放,并能将空闲且相邻的内存进行合并,减少内存碎片。heap_5在heap_4的基础上实现了管理多个非连续内存区域的能力,适用于内存地址不连续的场景。
FreeRTOS内存管理相关API
FreeRTOS内存管理实验旨在学习如何使用FreeRTOS内存管理,观察申请和释放过程中内存大小的变化情况。实验包括创建task1、按键扫描、KEY0申请内存、KEY1释放内存,并打印剩余内存信息。heap4.c讲解内存的结构体,包含指针和无符号整数两个成员。内存堆初始化prvHeapInit()通过宏configTOTAL_HEAP_SIZE获取FreeRTOS管理的内存总大小,获取给FreeRTOS管理的数组首地址,进行对齐操作,并初始化管理的数组。合并空闲内存prvInsertBlockIntoFreeList()用于将空闲内存插入空闲列表,合并相邻空闲内存,并将空闲地址由低到高排列。申请内存pvPortMalloc()和释放内存vPortFree()提供了内存的申请和释放功能,分别用于动态分配和释放内存。
FreeRTOS-内存管理总结
FreeRTOS 内存管理涵盖动态与静态方法,通过创建任务、队列、信号量等操作实现。动态内存管理时,FreeRTOS 内核会根据需求动态申请内存,反之,代码笔记源码静态方法则由用户预先指定内存分配。
FreeRTOS 提供了五种内存分配策略,每个策略通过特定的 .c 文件实现,分别为 heap_1.c、heap_2.c、heap_3.c、heap_4.c 和 heap_5.c。每种策略各有特点,满足不同应用需求。
在 heap_1.c 中,适用于那些创建完成后不再删除的任务、信号量和队列应用,内存分配过程简单且效率高,但不适用于动态内存需求变化的应用。
heap_2.c 适用于频繁创建和删除任务、队列、信号量的应用,但需注意可能出现内存碎片问题,尤其在分配和释放内存大小随机的情况下。
heap_3.c 则封装了标准 C 库的 malloc 和 free 函数,提供线程安全的内存管理,适用于需要动态内存管理的应用,但可能增加代码复杂度。
heap_4.c 与 heap_2.c 相比,优化了内存碎片管理,能够合并碎片为大内存块,适用于频繁动态分配内存的应用,同时提供了内存管理的额外工具,如 xPortGetFreeHeapSize 和 xPortGetMinimumEverFreeHeapSize。
heap_5.c 同样采用合并算法,但允许内存堆跨越多个不连续的内存段,为应用提供了更大的灵活性,特别是在需要同时使用内部 RAM 和外部 SRAM 或 SDRAM 时。
总结而言,FreeRTOS 的内存管理策略提供了从简单到复杂、从静态到动态的多种选择,适应不同应用场景的需求,实现高效、灵活的内存资源管理。
Freertos(4)----信号量
Freertos中的二值信号量是一种用于任务间或任务与中断间同步的基本工具。它与互斥信号量类似,但不具备优先级继承机制。二值信号量的特点在于其队列仅有一项,意味着队列要么为空,要么已满,任务只需判断队列状态,无需关注具体消息内容。
以温湿度传感器为例,如果采集数据和刷新屏幕的周期不同步,可能会浪费CPU资源。通过使用二值信号量,传感器数据采集完成后才会触发屏幕刷新,确保数据的准确性并节省CPU资源。在操作中,任务会根据信号量队列状态进入阻塞或非阻塞状态。
Freertos通过在发送信号量时立即返回,避免了发送端和接收端的同步问题。创建二值信号量时,API与创建队列类似,只是设置消息数量为1,大小为0,类型为二值信号量队列。
计数信号量则更注重资源管理,允许多个任务访问,但限制任务总数。当超过限制时,后续任务会阻塞,直到有任务释放资源。这种机制就像多个人上厕所的比喻,确保了资源访问的有序性。
互斥信号量则提供了互斥和优先级继承特性,确保临界资源的独占访问,避免优先级翻转问题。在源码中,创建、释放和获取互斥信号量的过程同样体现了简化设计的理念。
递归互斥信号量允许任务多次获取并释放,但必须是成对操作,且同样具有优先级继承机制。递归互斥信号量的API和源码实现同样遵循这一原则。
正点原子FreeRTOS——软件定时器
定时器是计算机系统中用于在指定时间后触发事件的组件。它们有硬件和软件两种形式。硬件定时器通常内置在芯片中,精度较高,能够自动触发中断,但受硬件资源限制。软件定时器则是在软件层面实现的,具有较高灵活性和可配置性。下面我们将详细介绍软件定时器的概念、特点、使用方式以及一些相关API。
软件定时器通常具有如下优点:可裁剪性、单次与周期性可选。裁剪性意味着软件定时器的配置与使用可以根据具体需求灵活调整。单次与周期性定时器允许用户选择是在特定时间执行一次操作(单次定时器)还是在每次定时周期到达时重复执行(周期定时器)。
FreeRTOS软件定时器具有以下特点:一是可配置性,通过设置宏`configUSE_TIMERS`为1来启用软件定时器功能;二是可以是单次或周期性定时器。然而,需要注意的是,软件定时器的超时回调函数由软件定时器服务任务执行,因此在回调函数内不能使用可能引起任务阻塞的API函数。
软件定时器服务任务在`vTaskStartScheduler()`函数调用时创建,负责管理所有软件定时器。FreeRTOS提供了软件定时器相关API,它们将命令(即操作请求)写入命令队列。用户不可直接访问该队列,只能通过API执行操作。
在配置软件定时器时,用户需注意软件定时器的超时回调函数是在软件定时器服务任务中执行的,因此服务任务必须处理所有定时器任务。
软件定时器的状态包括休眠态与运行态。在休眠态,定时器未运行,定时超时回调函数不会执行;而当达到指定时间时,定时器进入运行态,此时回调函数会被调用。
FreeRTOS软件定时器提供两种类型:单次定时器和周期定时器。单次定时器在超时后仅执行一次回调函数,不会自动重启;而周期定时器在超时后会自动重启,持续执行回调函数。
软件定时器结构体包含关键信息,如定时器句柄、周期、回调函数以及状态。通过这些信息,可以实现定时器的创建、开启、停止、复位与周期时间的更改。
在FreeRTOS中创建软件定时器使用`xTimerCreate`API,开启定时器使用`xTimerStart`,停止定时器使用`xTimerStop`,复位定时器使用`xTimerReset`,更改周期时间则使用`xTimerChangePeriod`。
软件定时器实验旨在通过实际操作学习相关API的使用。实验通常涉及创建任务、设置定时器、以及在任务中执行定时器的开启与停止操作。在实验中,首先需要在配置文件中启用软件定时器功能,确保定时器任务的优先级足够高以确保及时执行。创建任务时,会自动创建两个列表(当前运行列表与溢出列表)以及命令队列。在创建完定时器后,系统会检查是否超时。对于周期定时器,系统会在超时后从当前列表移除,再重新插入列表;单次定时器则将其状态置零。随后,执行超时回调函数。若无超时,系统将检查是否有定时器挂载在溢出列表中,并根据情况进入等待接收命令的阻塞状态。最终,系统会接收并执行用户定义的命令。
正点原子FreeRTOS——队列
队列是任务之间数据交流的机制,允许存储固定数量的数据。每个数据称为队列项目,队列容量称为队列长度。创建队列时,需指定长度和项目大小。FreeRTOS队列具有三种等待模式,无等待、限时等待与死等待。入队与出队操作有阻塞与非阻塞之分。
队列结构体包含队列长度、项目大小与队列项目数组,实现数据存储。FreeRTOS提供多种队列类型,动态分配内存或用户自定义内存。队列相关API包括创建、写入与读取操作。
写入消息API允许将数据放入队列,包括不同写入位置与中断专用函数。读取消息API则包含读取并删除队列项目或仅读取队列项目两种。
实验中,通过创建不同任务实现队列功能,包括按键输入、数据传输与访问。任务间通过队列进行数据传递,实现数据的接收与处理。
所有队列操作均包含临界区管理,确保数据访问的安全性。创建队列API执行底层创建函数,写入数据API调用底层写入函数,读取队列API在进入临界区前执行。
FreeRTOS源码探析之——消息队列
消息队列是FreeRTOS中的一种关键数据结构,用于实现进程间通信。其运作机制首先由FreeRTOS分配内存空间给消息队列,并初始化为空,此时队列可用。任务或中断服务程序可以给消息队列发送消息,发送紧急消息时,消息将直接放置于队头,确保接收者能优先处理。这种机制保证了紧急消息的优先级。
为了防止消息队列被并发读写时的混乱,FreeRTOS提供了阻塞机制,确保操作的进程能够顺利完成,不受其他进程干扰。接收消息时,若队列为空,进程可选择等待,直到消息到达。在发送消息时,只有队列允许入队时,发送才成功,避免了队列溢出。优先级较高的进程将优先访问消息队列,这通过任务优先级排序实现。
消息队列控制块包含了队列的管理信息,如消息存储位置、头尾指针、消息大小和队列长度等。这些信息在创建队列时即被初始化,并且无法改变。每个消息队列与消息空间共享同一段连续内存,只有在队列被删除时,这段内存才会被释放。消息队列长度在创建时指定,决定了消息空间总数。
FreeRTOS通过xQueueGenericCreate()函数创建消息队列,该函数首先分配内存,然后初始化队列。初始化过程涉及队列长度和消息大小等参数的设置,并通过xQueueGenericReset()函数进行队列复位。
队列复位时,vListInitialise()函数构建了列表结构,这是消息队列内部的组织形式。列表结构体定义了节点类型,而vListInitialise函数初始化了列表,为消息队列的使用做好准备。
发送消息时,xQueueSend()或其底层实现xQueueGenericSend()函数根据参数选择发送位置。默认情况下,消息会发送至队尾。接收消息则通过xQueueReceive()或xQueueGenericReceive()函数实现,参数通常包括队列句柄和接收的消息指针。
消息队列的发送和接收过程中,若队列已满或为空,可能会触发任务切换,以避免阻塞进程。这种机制确保了消息队列在进程间通信中的高效和有序,是FreeRTOS系统中实现进程间协作的关键组件。