我正在研究一个几乎无法容纳64k微控制器存储器的项目。而且我认为可能是时候考虑使用不同的编译器来选择哪种编译器可以更积极地减小程序的大小。
我请您注意一下。
为了进行测试,我在Cube MX中创建了一个项目,其中包括USB_DEVICE和Mass Storage Class。这些是用于测试的相当大的库。
生成的main.c看起来像这样:
int main()
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
}
定义USBD_DEBUG_LEVEL设置为0,以便USB堆栈调试消息不需要printf
包括的编译器:
- IAR EWARM 8.32.1
- arm-none-eab-gcc 7-2018-q2-update(STM32 Cube IDE 1.4.2)
- ARMCC v5.06更新7(Keil uVision 5.32环境)
- ARMCC v6.14.1(Keil uVision 5.32环境)
IAR设置:
- 优化尺寸
- 运行时库NORMAL
- 无低级IO(禁用printf)
- 启用链接器优化:内联小例程,合并重复的部分
GCC设置:
- 简化的运行时库--specs = nano.specs
- 优化大小-Os
- 将函数放在自己的部分中--ffunction-sections
- 将数据放在自己的部分--ffdata-sections
- 丢弃未使用的部分-Wl,--gc-sections
Armcc5设置:
- 使用micro lib
- 使用跨模块优化
- 优化-O3
- 每个函数一个ELF节--split_sections
Armcc6设置:
- 使用micro lib
- 优化图像尺寸-Oz
- 每个函数一个ELF节--split_sections
海湾合作委员会 | armcc5 | IAR | armcc6 | |
固件大小 | 14036 | 13548 | 12997 | 12984 |
UPD
IAR具有多文件编译选项。如果您将其打开,则IAR会大幅度前进。固件减少到12,746字节。
如您所见,armcc6比IAR稍好。其次是armcc5,落后4%,而gcc落后领先者8%。
应当注意,KEIL选项“使用跨模块优化”显着增加了编译时间,但并没有几乎减少代码大小。