将IAR代码移植到avr-gcc:__eeprom替换EEMEM报错求助
问题分析与解决
错误原因
你遇到的section attribute not allowed for 'src'错误,核心原因是EEMEM的用法和IAR的__eeprom完全不同:
- IAR的
__eeprom既可以修饰变量(指定变量存放在EEPROM),也可以修饰指针(表示指针指向EEPROM空间); - 而avr-gcc的
EEMEM本质是__attribute__((section(".eeprom"))),是一个段属性,仅能用于修饰静态存储期的变量(全局变量、static局部变量),用来指定变量的存储位置为EEPROM段。你把它用在函数参数(自动存储期,栈上变量)的指针上,编译器自然会报错——栈上的参数不允许指定存储段。
正确替换方案
1. 替换__eeprom修饰的变量
直接将__eeprom替换为EEMEM,位置可以放在类型后或变量名后:
- IAR代码:
__eeprom UBYTE my_eeprom_var; __eeprom UBYTE my_eeprom_str[] = "test"; - avr-gcc代码:
UBYTE my_eeprom_var EEMEM; UBYTE EEMEM my_eeprom_str[] = "test"; // 两种写法都有效
2. 替换__eeprom修饰的指针(指向EEPROM的指针)
不能用EEMEM修饰指针,需要用avr-gcc的地址空间属性来声明指向EEPROM的指针:
- 直接写法:
// 函数参数中声明指向EEPROM的指针 UBYTE *strcpye(UBYTE *dest, UBYTE __attribute__((address_space(eeprom))) *src); - 简洁宏定义(推荐):
先在头文件中定义宏,统一替换:
然后函数声明简化为:#define EEPROM_PTR(type) type __attribute__((address_space(eeprom))) *UBYTE *strcpye(UBYTE *dest, EEPROM_PTR(UBYTE) src);
3. 额外注意事项
avr是哈佛架构,EEPROM空间和RAM空间是隔离的,不能直接通过指针读写EEPROM内容,必须使用avr-libc提供的eeprom_read_byte()、eeprom_read_word()、eeprom_write_byte()等专用函数来操作EEPROM数据。
内容的提问来源于stack exchange,提问作者atgb
相关产品推荐
相关产品推荐

