最近在做STM32F103C8T6的小项目,发现了一个挺让人头疼的问题。程序编好以后,烧录软件显示的hex文件有128KB,可STM32F103C8T6的Flash容量只有64KB,这就好比想用64KB的箱子装128KB的东西,感觉怎么都装不下。心里开始犯嘀咕:这个程序是不是写得太臃肿了?难道是我哪里弄错了?带着这些疑问,我决定打开Keil编译报告,好好看看里面到底藏着什么秘密。 编译报告里最关键的是这四行数字:Code、RO-data、RW-data和ZI-data。这四块数据各有各的职责:Code里装的是程序执行时的机器码;RO-data存的是只读数据,比如全局常量和字符串;RW-data放的是已经初始化好的读写变量;ZI-data则是那些定义了但还没赋值的读写变量。把这几块数据加起来,就是程序真正要写到Flash里的“肉体重”。算下来大概是56.48KB,跟烧录软件显示的128KB相差甚远。这说明烧录软件显示的其实是镜像文件的大小,里面包含了很多用于调试的额外信息。 打开Windows资源管理器或者看Keil的进度条时看到的128KB,实际上是编译后整个镜像的大小。这个镜像不仅有能执行的Code、RO-data和RW-data,还包含了调试信息、符号表、段描述符等辅助内容。有些时候编译器还会自动插入一些填充字节(Padding)来补齐空间。所以这个hex文件里既有真正能执行的程序部分,也有用于辅助调试的信息部分。单片机真正运行的只有前者那部分。 只要算出Code、RO-data和RW-data这三块加起来的实际写入大小,就能解决那个灵魂拷问了:56.48KB的可执行代码完全可以塞进64KB的Flash里。烧录软件显示的128KB只是整个镜像的大小,并不是实际要写入Flash的大小。 STM32F103C8T6的64KB Flash在功能复杂的项目面前确实有点紧张了。如果只是想暂时挤一挤空间,可以用压缩算法把RO段缩小到极限,把大数组拆分成多段按需加载,或者把能放在RAM里的数据就放在RAM里利用64KB的RAM做缓存。 如果功能点实在太多怎么都不够用了,换芯片可能是最直接的办法。STM32F1系列里往上走还有128KB、256KB甚至512KB Flash的型号,根据预算和需求选一个就好。 下次再遇到“hex文件远大于Flash容量”这种情况时千万别慌——先看一下编译报告算一下实际写入大小;再看看烧录进度条确认哪些是辅助信息;最后对照芯片手册确认剩余空间足够就行。掌握这三步就能把单片机从“容量焦虑”中解放出来专心做逻辑算法了。