工作随笔--------FreeRTOS分配堆栈空间大小

本文介绍了如何在资源受限的MCU上使用FreeRTOS系统时,合理配置堆栈空间,包括动态内存分配的原理,以及如何通过API如xPortGetFreeHeapSize和uxTaskGetStackHighWaterMark监控并调整heap和任务栈的大小,以确保内存的有效管理和任务的正常运行。
摘要由CSDN通过智能技术生成

FreeRTOS分配堆栈空间大小

一直想做个总结,今天再次遇到这个有点点纠结的问题,做个随笔:
运行freertos系统的大部分都是资源有限的MCU,所以对于ram我们都要考虑尽量的节省,避免资源浪费,从而也可以针对项目选择性价比更好的mcu。
在这里插入图片描述
首先要配置freertos的堆(heap)空间,创建任务我们还需要为每个任务分配栈(stack)空间,那么针对freertos的堆栈空间到底该如何确定?

freertos从V9版本以后同时支持静态内存和动态内存分配方式。静态内存分配在编译时候就会对freertos的内核对象分配ram空间。动态分配都是在程序运行起来以后从堆空间上分配的。这里我们也只讨论动态内存分配,动态内存分配的好处是可以在删除对象的时候释放掉内存的空间。从而保证ram的可持续利用!

假设在freertos的配置选项中已经配置使用动态内存分配方式。如上图所示,其他比如任务或者队列或者用户使用 pvPortMalloc() 分配的空间都从heap堆上面划分。所以我相信你不会做把任务栈分配的比heap堆还大的傻事!

好了,这个关系搞清楚,那么又该如何定heap的空间大小呢,可以先进行一个粗略的计算,假设任务1分配2kbytes栈,任务2分配3kbytes栈,队列大概占1k,用户malloc大概2k,这么算一共就是8k。那么在资源有限的情况下可以先把heap空间分个15k。

heap堆空间分配
因为程序运行起来实际占用heap的空间不好计算那么准,那么我们可以借助freertos的API来准确的得出空闲的heap空间和用的最对时候的空闲值。这两个API如下:

xPortGetFreeHeapSize()

这个函数可以获取调用时堆中空闲内存的大小,以字节为单位。使用它可以优化堆的大小。需要注意,当使用heap_3时是不能调用这个函数的。

xPortGetMinimumEverFreeHeapSize()

此函数返回FreeRTOS应用程序开始运行之后曾经存在的最小的未被分配的存储空间的字节数。它的返回值指示了应用程序离将要耗尽堆空间的接近程度。需要注意xPortGetMinimumEverFreeHeapSize()只在使用heap_4或者heap_5时生效。

在随便一个任务运行过程中,我们可以把这两个函数的返回值打印出来,比如分别为4200和3000,那么我们就清晰的知道了heap在分配出去最多的时候还剩余3000bytes空闲的,那么我们就可以把heap空间优化减小3000bytes。但是实际过程中请大方一点,不要算的那么死,给freertos留下一点喘息的的机会。

运用上面两个函数的例子:

printf(“xPortGetFreeHeapSize = %d\r\n”, xPortGetFreeHeapSize());
printf(“xPortGetMinimumEverFreeHeapSize = %d\r\n”,xPortGetMinimumEverFreeHeapSize());

stack栈空间分配
堆空间的大小还容易估算一点,但是任务栈空间具体占用多少想计算出来可是复杂很多的。比如任务运行过程中函数调用的圧栈,局部变量等都存在任务的栈空间上,所以我们一开始也只能尽量分配个大一点的值,之后再来调整。那么得出任务栈空间具体还有多少剩余也是有API可以调用的:

unsigned portBASE_TYPE uxTaskGetStackHighWaterMark(xTaskHandle xTask )

参数名
xTask 被查询任务的句柄,如果传入 NULL 句柄,则是自己任务的栈剩余
返回值
返回从任务启动栈空间具有的最小剩余量这个值越是接近 0,说明这个任务快溢出了。

但是该API使用是有配置开关的,在FreeRTOS.h中把 INCLUDE_uxTaskGetStackHighWaterMark 配置为1打开开关

比如我们在一个任务中如下调用:

printf(" the min free stack size is %d \r\n",(int32_t)uxTaskGetStackHighWaterMark(NULL));

就可以打印出来该任务自启动起来最小剩余栈空间大小。然后我们就可以计算出最大使用的大小,一般可以再乘以1.5左右作为最终分配的值。需要注意的是该函数不像前面两个返回的是bytes,而返回的以字为单位,真实的bytes需要乘以4.

所以总体的原则就是:先分大再调小最终把它确定好。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Freertos堆栈和启动文件堆栈是两个不同的概念。在Freertos堆栈是用来保存任务的上下文信息的内存区域,用于任务切换时保存和恢复任务的执行状态。而启动文件堆栈是用来为整个程序提供内存空间的,包括全局变量、静态变量等。 在Freertos,堆的大小可以通过在FreeRTOSConfig.h文件设置configTOTAL_HEAP_SIZE来指定。这个值决定了Freertos可以使用的堆的总大小。根据经验,堆的大小应该设置得足够大,以满足任务的内存需求。 而启动文件堆栈大小Freertos的堆大小没有直接关系。启动文件堆栈大小是用来为整个程序提供内存空间的,包括全局变量、静态变量等。在使用Freertos时,启动文件堆栈大小可以根据以下公式来设置:启动文件的heap_size = mcu运行时的ram空间 - RW-Data - ZI-Data - Freertos设置的堆大小。 总结起来,Freertos堆栈和启动文件堆栈是两个不同的概念,它们的大小设置是独立的。在使用Freertos时,需要根据任务的内存需求来设置Freertos的堆大小,并根据公式来设置启动文件堆栈大小,以确保程序的正常运行。 #### 引用[.reference_title] - *1* *2* *3* [stm32以及freertos 堆栈解析](https://blog.csdn.net/sinat_36568888/article/details/124320985)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值