【原创】IAR下通过去掉printf函数来减小Flash占用空间
1赞较早的时候我曾写过一篇Codewarrior10.6下通过配置ewl_noio库来减小Flash空间的文章(可以通过百度或者Google搜一下关键词查找一下,AET新版网页把网站内搜索功能去掉了的确不大方便),最近又有用户遇到类似的问题(这个俺也比较理解,有时候为了成本和项目需求综合考虑,不得不选用小Flash的MCU,我们苦逼的攻城狮们为了缩减Flash的空间打开各种优化,一个字节字节的裁剪),不过它使用的是IAR开发环境,这个…该咋办捏,下面我简单讲讲这个问题。
实际上刚听到这个问题时,我还是觉着这个问题比较好解决的,毕竟之前有了类似的经验,应该还是比较好定位问题的。这里我以飞思卡尔ARM Cortex-M0+ KL05 8kB flash MCU为例,我们打开KL05的官方sample code(KL05_SC),随便找到一个样例工程(这里我打开KL05-SC\klxx-sc-baremetal\build\iar\platinum路径下的工程),这是一个简单的UART收发测试工程,我们先对整个工程编译查看一下生成的Image文件大小,为方便查看image大小,我常用的方式是配置下IAR使之编译完之后生成.bin纯二进制文件(所见即所得,文件大小及占用Flash大小,不像S19文件或者hex文件有些额外的解码信息),IAR下的配置如下图:
在上述配置完毕,重新编译整个工程后可以直接在相应的输出文件下看到生成的.bin文件,右键属性可以看到这个简单的工程所占用的大小如下图,不看不知道一看果然吓一跳,这么个简单的测试工程就直接占用了大约7kB的代码空间,这如果是直接使用KL05 8KBFlash的芯片岂不是只有1k左右可用的空间了?对此攻城狮们表示压力很大(这里应该加一个QQ聊天中狂流汗的表情,呵呵)…
遇到问题不要怕,接下来考验咱们攻城狮们耐心和细心的时候到了,静下心来好好检查下代码(建议从启动代码开始走一遍MCU从上电开始的工作流程),这一检查不要紧,一查就发现问题了,我们在KL05的启动代码部分start.c中发现不对了(来自之前搞定Codewarrior编译大小时的经验,即打印函数是很占空间的),我们在启动代码中发现了两个函数outSRS()和cpu_identify()里面大量调用了printf打印函数,这样子问题就来了,调用了这么多printf函数不占用空间才怪来(本身printf的函数实现就比较复杂,而程序里却重复调用了这么多)。
为了测试这里的问题,我们简单的注释掉上述这两个函数(这两个函数对系统本身没有大用,只是打印些MCU状态)然后再重新编译工程得到新的.bin文件,这次再查看该文件的属性如下图所示,效果立竿见影啊有木有,一下子瘦身了将近3kB大小的空间,攻城狮们顿时痛哭流涕,之前勒紧裤腰带过日子,现在直接翻身做土豪了的赶脚啊,哈哈,老板再也不用担心我的晓习了。当然,我们不能止步于此啊,继续搜索整个工程把所有的printf函数都给去掉,最大程度的优化整个工程。
说到这里可能会有人问到,如果都屏蔽掉printf函数不用的话我们在调试打印是怎么办?这的确是比较现实的问题,我们总不能都在调试环境下通过IDE自带的变量跟踪功能查看吧。不过我们作为充满屌丝气息的码农工程师们,学会变通是非常重要的,printf用不了了,我们直接使用UART的发送字符或字符串函数不就行了嘛,虽然功能没有printf函数那么强大,但是为了伟大的事业(咳咳,降低成本)牺牲这点也不算什么了,哈哈。
今儿就不多啰嗦啥了,有点晚了,洗漱睡觉去了,未完待续~