这些属性不兼容吗?地址属性似乎被忽略,没有发出警告(-Wall)。
(仅供参考,EEMEM 在 eeprom.h 中定义为:
#define EEMEM __attribute__((section(".eeprom")))
。)
使用如下声明:
uint8_t storedFlags EEMEM __attribute__((address (100)));
(对于所有其他变量也类似)导致变量按照链接器喜欢的任何顺序放置,忽略我的属性。属性的顺序没有区别。
我知道首选方法(创建部分并将其位置传递给链接器)。我暂时只是想把它们扔到一边,因为我正在积极开发并在 EEPROM 中添加和删除分配;我宁愿事情不要在其他构建中移动,这样我就不必每次都从默认值重新编程 EEPROM。最糟糕的是,我确信我以前确实这样做过,并且成功了。版本差异?巧合的任务? (我有 GCC 3.4 和 8.1,不确定该项目使用了什么;我在这个项目中使用 8.1。)
address属性的文档指出:
具有地址属性的变量用于寻址可能位于 io 地址范围之外的内存映射外设。
查看AVR 内存空间,显示 I/O 地址属于 SRAM 数据内存空间。
这解释了为什么您的构造不能按预期工作,因为 EEMEM 和 address 属性映射到冲突的内存部分。
编辑:使用 avr-gcc 3.6.2 进行测试表明节属性覆盖了地址属性(没有警告)。使用 eeprom_read_byte 从 EEPROM 读取数据,以下示例由 avr-gcc 正确编译(正确是因为地址 0x0123 被传递给 eeprom_read_byte 函数):
#include <avr/eeprom.h>
uint8_t __attribute__((address (0x0123))) storedFlags;
int main(void){
if (eeprom_read_byte(&storedFlags) == 1){
return 1;
}
}
Edit2:在 avr-gcc 11.1 上测试,也生成正确的指令。
这些属性的组合没有任何意义。您要么在第
.eeprom
部分中有一个物体,要么在某个固定位置。请注意,属性address
和朋友不会分配任何内存!
属性
address
所做的就是定义一个符号,类似于-Wl,--defsym,storedFlags=0x100
的效果。
在EEPROM中分配数据时,可以
EEMEM
标记所有变量。链接器将根据链接器脚本中 .eeprom
部分的位置来定位对象。一个例子:
#include <avr/eeprom.h>
#define storedFlags_ADDRESS 0x100
uint8_t get_storedFlags (void)
{
return eeprom_read_byte ((void*) storedFlags_ADDRESS);
}