当前位置:首页 > 内存 > 正文

freertos 任务内存分配

  • 内存
  • 2024-07-04 20:33:22
  • 8985

一、freertos任务切换需要多少个时钟周期

时间为1ms。每次创建作业、队列和信号量时,FreeRTOS都需要分配一定数量的RAM。虽然函数malloc()和free()可以用来申请内存和释放,但这两个函数有以下缺点:它们并不是在所有嵌入式系统中都可用,它们占用空间,在任何程序中都可以使用。以人性的方式为此,除了malloc()和free()函数之外,FreeRTOS还提供了另外两种内存分配策略。


二、FreeRTOS原理与实现

FreeRTOS的核心技术之一是任务调度机制,它利用了可剥夺内核中的优先级调度。一旦高优先级任务就绪,就可以利用低优先级任务的CPU资源,提高系统的实时能力。时间响应能力。与μC/OS-II不同,FreeRTOS不限制任务数量,并且支持优先级和循环调度。它使用双向链表而不是任务就绪列表,并定义了xList结构和xLIST_ITEM结构。每个任务对应一个任务控制块(TCB),其中包含任务堆栈、优先级、链表节点等信息。


FreeRTOS任务调度是通过链表数组xReadyTasksLists实现的。当一个任务需要进入就绪状态时,需要将TCB的xGenericListItem插入到相应优先级的链表中。按照优先级从高到低的顺序安排先搜索非空链表,优先级高的任务会先执行。当存在多个高优先级任务时,采用循环调度算法。由于pxIndex指针的存在,任务在优先级n下切换所需的时间是一个时钟周期。


为了提高效率,FreeRTOS使用ucTopReadyPriority来跟踪当前的最高优先级。当创建新任务且其优先级高于当前最高优先级时,ucTopReadyPriority会更新。该策略减少了寻道时间并缩短了核心关闭时间。FreeRTOS还实现了创建、删除和暂停任务等功能。任务删除采用两步策略来减少内核关闭时间。


FreeRTOS的时间管理是通过vTaskDelay函数实现的。通过计算当前时钟节拍总数加上延迟值,然后将任务控制块插入延迟链表来计算任务延迟。与μC/OS-II相比,FreeRTOS的加法方法使得时间管理更少地依赖于任务数量,提高了执行速度。


在内存分配策略上,FreeRTOS提供了大内存简单分区和链表分配两种方式供用户选择。链表分配方式可以动态管理内存,但可能会造成内存碎片,并且需要固定的内存申请和释放大小。相比μC/OS-II的分区管理,FreeRTOS在内存利用率上可能稍差一些。


虽然FreeRTOS具有良好的可移植性并支持多种处理器,但其功能和服务比μC/OS-II更加有限,并且需要额外的GUI、TCP/IP协议栈和文件支持。这既是FreeRTOS的优点,也是缺点。用户需要根据自己的需要选合适的操作系统。


高级资讯

在嵌入式领域,嵌入式实时操作系统的使用越来越频繁。采用嵌入式实时操作系统(RTOS)可以更加合理有效地利用CPU资源,简化应用软件设计,缩短系统开发时间,更好地保证系统的实时性和可靠性。


三、FreeRTOS队列

参考及感谢zhzht19861011:FreeRTOS队列分析
队列是任务之间的主要通信方式,可以在任务之间、中断与任务之间传递信息。
最常见的是,队列用于具有线程保护的FIFO(先进先出)缓冲区。

发送到队列的消息是通过复制实现的,也就是说队列中存储的数据是原始数据,而不是对原始数据的引用。

API函数允许设置阻塞时间。

队列的基本使用:

创建队列API函数xQueueCreate(),但实际上这是一个宏,只是声明为函数。实际实现的函数是xQueueGenericCreate()。我们将此函数称为全局队列创建函数。

ucQueueType参数仅用于视觉跟踪和调试。
首先调用prvAllocateQueueMemory函数为队列结构和队列元素分配存储空间。结构和队列项在存储中是连续的。

分配成功后初始化成员,然后调用xQueueGenericReset()函数初始化剩余的结构体成员。
假设我们申请了3个队列项,每个队列项占用4个字节的存储空间(即uxLength=3,uxItemSize=4),那么初始化后的队列内存如。

放置队列项也称为传递(发送),分为带中断保护的等待操作和不带中断保护的等待操作。每个实例分为两个操作:从队列尾加入和从队列头部加入。有一种特殊情况,即从队列尾部加入,覆盖加入,即自动完成队列中最旧的元素。当队列已满时覆盖它。

该函数用于队列操作,不应该在中断服务程序中使用。

pcWriteTo指针指向的位置,加上update指针指向的位置,队列项计数器增加1;第三种情况是从头入队时,将数据复制到指针pxQueue->From指向的位置,更新指针指向的位置,队列项计数器加1。如果是覆盖队列,队列项计数器的值也会被修改。

队列结构中有两个与队列锁相关的成员:xRxLock和xTxLock。当这两个变量在队列中时(宏,定义为-1),表示队列没有被锁定;当队列中这两个变量为LOCKED_UNMODIFIED(宏,定义为0)时,表示队列被锁定。