首页 > 系统相关 >如何确保不使用动态内存

如何确保不使用动态内存

时间:2022-12-18 08:55:06浏览次数:76  
标签:脚本 sbrk startup 如何 确保 动态内存 使用 链接

  在许多嵌入式应用程序中,内存分配必须是静态的,而不是动态的。意味着在应用程序中不应使用对malloc()或free()等内容的调用,因为它们可能会在运行时失败(内存不足、堆碎片)。

  但是,当与第三方库甚至 C/C++ 标准库链接时,如何确保不使用动态内存?对于C++对象或对 printf()的简单调用,也可能会出现此问题,该调用需要在内部分配一些动态内存。

1、零堆大小?

  一种简单(而且相当幼稚)的方法是将堆大小设置为零。大多数链接器脚本或链接器环境都能够将堆大小设置为零,如下所示:

  但是,这无济于事,因为大多数链接器脚本只使用堆栈空间和变量 (bss) 之间的可用空间: 因此,将堆大小设置为零只是假设保留为零,但库的 _sbrk()将继续使用动态内存,可能会崩溃到堆栈空间。

  底线:大多数链接器脚本堆大小设置为零将无济于事。它甚至增加了堆崩溃到堆栈中的可能性,因为链接器假定堆的使用量为零。但它不会阻止使用堆。

2、堆在链接器文件中

  这可以从下面显示的链接器文件中看出:

  若要确保不使用堆,最简单的方法是简单地删除上述链接器文件中的 .heap 分配。检查链接器文件中是否有“堆”或类似内容,并确保没有为其分配内存。特别是确保没有使用符号“__prvHeapStart”或“__prvHeapLimit”,因为它们通常是newlib/newlib-nano库动态内存分配所必需的。

3、链接器自由标记脚本

  恩智浦MCUXpresso IDE等某些环境正在使用自动生成的链接器文件。但是,如果您了解它使用的FreeMarker脚本,则很容易处理此问题。脚本位于

<MCUXpresso IDE Installation Path>\ide\Wizards\linker

  所以我可以使用修改后的 FreeMarker 脚本轻松禁用 .heap:

4、__sbrk()

  删除堆及其符号后,malloc()的任何用法都应该给出一个链接器错误,类似于这个错误:

Invoking: MCU Linker
arm-none-eabi-gcc -nostdlib -Xlinker -Map="AEMBS_tinyK22_HS22.map" -Xlinker --gc-sections -Xlinker -print-memory-usage -Xlinker --sort-section=alignment -Xlinker --cref -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -T "AEMBS_tinyK22_HS22_Debug.ld" -o "AEMBS_tinyK22_HS22.axf" ./utilities/fsl_assert.o ...  ./McuLib/FreeRTOS/FreeRTOShooks.o   
arm-none-eabi/bin/ld.exe: arm-none-eabi/lib/thumb/v7e-m+fp/hard\libcr_newlib_semihost.a(_cr_sbrk.o): in function `_sbrk':
_cr_sbrk.c:(.text._sbrk+0x38): undefined reference to `_pvHeapStart'

5、链接器交叉引用

  如果不清楚使用内存分配或导致错误的原因,可以使用链接器交叉引用。为此,必须将 GNU 链接器 –cref 选项添加到链接器选项中:

  这会在链接器 .map 文件中生成如下所示的信息:

Cross Reference Table

Symbol                                            File
ADC0_DriverIRQHandler                             ./startup/startup_mk22f51212.o
ADC0_IRQHandler                                   ./startup/startup_mk22f51212.o
ADC16_ClearStatusFlags                            ./drivers/fsl_adc16.o
ADC16_Deinit                                      ./drivers/fsl_adc16.o
...
main                                              ./source/main.o
                                                  ./startup/startup_mk22f51212.o
malloc                                            arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-malloc.o)
                                                  arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-rand.o)
                                                  ./drivers/fsl_common.o
mcgConfig_BOARD_BootClockRUN                      ./board/clock_config.o

  这给出了使用 malloc()之类的模块列表。

6、图像信息

  找出依赖关系的另一种方法是在 Eclipse/MCUXpresso 中使用“图像信息”视图,请参阅在构建后操作中列出具有 GNU 大小实用程序的所有文件的代码和数据大小:

7、免费实时操作系统静态内存分配

  更多旁注:默认情况下,FreeRTOS 使用自己的动态堆分配。但是可以静态方式运行 RTOS(无动态内存分配),请参阅带静态内存分配的 FreeRTOS V9.0.0。

8、总结

  许多应用程序不需要动态内存分配和使用。为了防止使用 malloc()和 free(),最好删除链接器文件中的任何堆定义,以导致链接器错误。那么 GNU 链接器交叉引用表或图像信息可能非常有用。

9、链接

  • 使用 FreeMarker 脚本的示例:教程:将 BLE+NRF Kinetis Design Studio Project 移植到 MCUXpresso IDE
  • 带有 FreeMarker 脚本的引导加载程序:将引导加载程序应用程序与 Eclipse 和 FreeMarker 脚本链接起来
  • 自由标记脚本:https://freemarker.apache.org/

欢迎关注:

标签:脚本,sbrk,startup,如何,确保,动态内存,使用,链接
From: https://www.cnblogs.com/foxclever/p/16989958.html

相关文章

  • 编译固件如何加入自定义配置
    编译固件如何加入自定义配置来源 https://forum.gl-inet.cn/forum.php?mod=viewthread&tid=143参考https://github.com/JiaY-shi/build-gl.inet参考  https://githu......
  • 如何反编译Java文件?
    ​反编译Java文件就是将编译好的.class文件反编译为.java文件,我们可以利用IDEA来轻松实现反编译。一.找到我们的.class文件1.打开项目结构2.在模块下选择想要的输......
  • 智慧树视频课件课程下载工具,如何在电脑端下载智慧树视频课件PDF,PPT到本地
    一.安装智慧树下载器1.获取学无止下载器https://www.xuewuzhi.cn/zhihuishu_downloader2.下载安装后,然后点击桌面快捷方式运行即可。注意:杀毒软件可能会阻止外部exe文......
  • .NET Core应用如何通过SSL访问MongoDB?
    大家好,我是Edison。最近有一个ASP.NETCore通过SSL证书访问MongoDB的需求,但是在网上发现资料很少,于是调查了一番,做了如下的笔记,希望对你有用。背景在实际场景中,开发环境......
  • FAQ:说一说一条查询语句是如何执行的?
    一条SQL语句内部执行流程是怎样的?1select*fromuserwhereid=1;1.客户端发送SQL语句到服务器,先要通过连接器连接到数据库,在完成TCP握手之后,验证用户名和密码。......
  • 如何可视化bert的注意力权重
    参考链接:bertvizgithub使用指南:BERT可视化工具bertviz体验一些bert中存在的模式解析:解构BERT:可视化注意力的内部运作,最强NLP模型BERT可视化学习代码(保存成html)fro......
  • 新手应该如何学习 PHP 语言?
    新手应该如何学习PHP语言?tenniswill人要有梦想!这个问题我应该比较适合回答。先说说我学习php前的情况:我不是计算机专业,学PHP的时候大学里上的C语......
  • Microsoft 365 开发:如何通过Powershell批量创建Site Collection
    Blog链接:​​​https://blog.51cto.com/13969817​​作为SPOOnlineadmin,很多时候面临来自各个部门的业务请求批量新建SiteCollection的需求,如果手动在在Microsoft365管......
  • KB0004.如何进行DoraCloud版本升级?
     升级过程为:1).现有版本,进入维护模式,导出系统数据。  2).记录现当前版本DoraCloudVM的IP地址,子网掩码、网关、DNS信息,将VM关机。3).安装新版本DoraCloud,在向导的......
  • vue3项目,记录我是如何用1h实现产品预估1天工作量的界面需求
    最近在编写前端界面,硬是一人一周时间加班加点写完了一个项目的前端界面(一级菜单有12个页面+一个控制台大屏,二三级界面有N个),之前预估前端界面的编写需要一个月,我是自己......