|
最近逛avrfreaks收到几个好贴。
1. 不链接未调用函数:
用avr studio的project option的工程,在该选项对话窗口的custom options里的[All files]里添加-ffunction-sections,
然后选择[Linker Options],添加-Wl,--gc-sections。重新编译。
用mfile或自己写makefile的,CFLAGS += -ffunction-sections,LDFLAGS += -Wl,--gc-sections。重新编译。
-ffunction-sections:不用此参数时,.o里代码部分只有.text段;使用此参数,则会使每个函数单独成为一段,比如函数func1()成为.text.func1段,但对链接后代码大小没影响。
--gc-sections:这是avr-ld的参数,通过-Wl,<option>由gcc把option里的参数传递给avr-ld。它使得链接器ld链接时删除不用的段。
这样,因为每个函数自成一段(即可以看作函数=段),如果有某个函数未被任何函数/段调用,则ld不会链接它。
2. 用rjmp/rcall替换jmp/call(即省空间,又提高运行速度):
jmp:Words 2 (4 bytes) Cycles: 3, call:Words 2 (4 bytes) Cycles: 4, devices with 16 bit PC
rjmp:Words 1 (2 bytes) Cycles: 2, rcall:Words 1 (2 bytes) Cycles: 3 devices with 16-bit PC
艺芯的avrgcc参数翻译里有个参数-mshort-calls,会强行替换所有的jmp/call为rjmp/rcall,当所选芯片的flash<=8K时,winavr默认开了这个选项。
但当芯片flash大于8K时,默认全用jmp/call。因为rjmp/rcall有8K跳转限制,如果代码有8K外跳转/调用那么链接时会发生错误,无法生成elf、hex。
当然如果你使用-mshort-calls编译时一切正常,那么你的代码里没有8K以上跳转/调用。
如果使用-mshort-calls后有错误,请看下面:
大的代码一般仍有部分跳转/调用在8K以内,如果全用jmp/call,浪费较大,此时可以用这个参数,
用avr studio的project option的工程,在该选项对话窗口的custom options里的[Linker Options],添加-Wl,--relax。
用mfile或自己写makefile的,LDFLAGS += -Wl,--relax。
这样,avr-ld在链接时会计算各个跳转/调用的范围,如果在相对跳转空间内,则用rjmp/rcall替换jmp/call。
注意:有时-Wl,--relax会造成ld运行错误(就是出现向m$报告错误那种对话框),应当加上-Wl,--gc-sections就行了,目前原因不明。
看下我的测试工程(使用了通用的文件,但很多函数没用到):
WinAVR-20070525
-Os
81314 Bytes
-Os -ffunction-sections -Wl,--gc-sections
75142 Bytes
-Os -ffunction-sections -Wl,--gc-sections -Wl,--relax
74806 Bytes
如果掌握了链接脚本,还能进一步手工优化,扩大-Wl,--relax的替换范围,甚至直接用-mshort-calls代替。 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|