Arduino的Serial.print(F(""))问题

本文探讨了Arduino项目的内存(SRAM)占用问题,通过对比关闭DEBUG_PRINT功能前后的内存使用情况,发现调试打印字符串显著增加了SRAM占用。文章进一步分析了Arduino可执行文件的内存分布,并介绍了解决方案——使用F()宏将字符串存放在FLASH而非SRAM中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    好久之前在编写项目产品的Arduino库代码时发现内存(SRAM)占用偏高,想了想我也没在类内定义多少成员变量啊,也没啥大的数组啥的,后来关闭DEBUG_PRINT功能后,内存占用一下子下来了,才一拍脑袋是调试打印的字符串占用了大量的SRAM,于是就探究了一下Arduino可执行文件的内存分布问题。

    和普通程序一样,Arduino的代码编译完成后也是分为code段、data段、bss段、noinit段,从最后编译输出窗口看,可以笼统的看做是代码段和数据段(包含全局变量和堆栈空间的占用),但是程序本身的大小是code段+data段,这就是占用FLASH的大小,而占用SRAM的就是data段+bss段+noinit段。


    再列出avr单片机的程序编译输出信息(与本文程序不是同一程序):

AVR Memory Usage
----------------
Device: atmega16

Program:   14362 bytes (87.7% Full)
(.text + .data + .bootloader)

Data:        635 bytes (62.0% Full)
(.data + .bss + .noinit)

    再上一张SRAM的内存分布图:




    回归主题,当我程序中的所有代码直接DEBUG_PRINTLN("")时


产生的程序文件大小是:


    当我把所有代码都写成这样:


输出的可执行文件大小:


可以得到的结论:添加 F() 相当于为字符串常量定义了PROGMEM属性,常量字符串仍然存储在FLASH中,但是程序运行时不会再将常量字符串从FLASH中copy到SRAM中,而是直接读取FLASH中的字符串,这样一来就节约了SRAM,但是代码运行速度就下降了。

    细心的童鞋会看到节约的SRAM大小并不是完全等于增加的FLASH大小,这是因为重复的字符串被FLASH只存储了一份,Arduino做的还是很人性化的,其他的类似xxduino库就没这么机智了,比如今天正在研究的WiFiduino(基于ESP8266模组做的 一个类似Arduino框架,用户可以像操作Arduino一样操作ESP8266,内含丰富的网络操作API):



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值