avr-gcc 13.3.0针对ATmega4809的.rodata段常量字符串问题咨询
问题解答
1. 强制所有const字符串存入.data段的方法
有几种可行的实现方式:
- 编译选项控制:在编译命令中添加
-fno-const-data-in-rodata参数,该选项会让avr-gcc默认将所有const修饰的数据(包括字符串)分配到.data段(RAM),而非.rodata段(Flash)。 - 链接器脚本修改:若需要更精细的内存控制,可以修改AVR的链接器脚本,将
.rodata段合并到.data段的地址范围内,让链接器自动把const字符串放到RAM区域。 - 全局编译属性设置:在代码开头添加如下指令,全局生效修改,无需在编译命令中单独加参数:
代码结尾再用#pragma GCC push_options #pragma GCC optimize ("-fno-const-data-in-rodata")#pragma GCC pop_options恢复默认编译规则。
2. 是否属于avr-gcc 13.3.0的bug?
首先,avr-gcc将const字符串存入.rodata(Flash)是符合C标准的默认行为——const数据通常会被放置在只读存储区。但问题的核心在于:访问.rodata时编译器没有生成正确的Flash读取指令。AVR架构中,Flash的读取需要使用LPM(Load Program Memory)类指令,直接用访问RAM的方式读取会得到错误值。
如果你的编译命令已经正确指定了-mmcu=atmega4809(确保编译器针对目标MCU优化),但仍然出现直接访问.rodata数据错误的情况,这大概率是avr-gcc 13.3.0的bug。正常情况下,编译器应该自动识别.rodata的存储位置,并生成对应的Flash读取代码,而非直接使用RAM访问指令。
当然也不排除链接器脚本配置错误、启动代码未正确初始化相关寄存器的可能,但你已经通过强制放入.data段验证了代码逻辑本身没问题,所以更倾向于是编译器的问题,可以尝试升级到avr-gcc后续版本,或者向官方issue tracker提交问题反馈。
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

