编译优化

发布日期:2011-11-6 13:17:54

编译优化只调用使用到的函数

CFLAGS += -ffunction-sectionsLDFLAGS += -Wl, -gc-sections, --relax

参考: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就行了,目前原因不明。