[英]Getting the lower 16 bits of a pointer compile time in GCC
我正在做一个嵌入式项目。 我正在尝试使用GNU链接器来布局存储在外部eeprom中的一些变量。 我通过将eeprom变量分配给
int __attribute__ ((section (".eeprom"))) eeprom_var1;
我还将为eeprom定义初始化变量,例如:
int __attribute__ ((section (".eeprom"))) eeprom_var2 = 0x42;
当时的想法是; 在eeprom初始化时,已初始化的变量被正在运行的应用程序从.text节中的某处复制到eeprom,就像初始化data节一样。 显然,eeprom变量无法读取/写入,但必须通过以下函数进行访问:
eeprom_read(data, &eeprom_var,sizeof(eeprom_var)).
到现在为止还挺好,
现在,我想使用另一个变量的指针初始化eeprom变量:
unsigned long long __attribute__ ((section (".eeprom"))) eeprom_var1 = 0x42;
unsigned short __attribute__ ((section (".eeprom"))) eeprom_var2 = (unsigned short )&eeprom_var1;
请注意 ,eeprom使用16位地址空间
但这给出了以下错误
foo.c:4:1: error: initializer element is not constant
unsigned short __attribute__ ((section (".eeprom"))) eeprom_var2 = (unsigned short )&eeprom_var1;
^
这是因为将强制类型转换为(无符号短整数)作为初始化操作进行读取,这在C语言中是不允许的。但是在C ++中,上述表达式可以。
谁能想到解决以上错误的方法?
/安德斯
const type
。 type* const
(指向非常量数据的常量指针)或const type* const
(指向常量数据的常量指针)。 这似乎是您问题的真正根源。 当然,一旦将它们声明为const,就不应丢弃const-ness。
另外,如果是片上eeprom,是否有不能直接访问存储单元的原因? 在大多数系统上,您都可以执行此操作,尽管访问时间可能比等效地访问RAM变量要慢。
附带说明一下,强制转换为uint16_t
(或无符号短uint16_t
)只会在小端字节序机器上给您16个最低有效位。 该代码不可移植到大字节序。 可移植代码为((uint32_t)pointer >> 16)
。
在C ++中,上面的表达式是可以的。
初始化已被C ++编译器接受,但在运行时执行(请参阅Spurious错误:初始化器元素在加载时不可计算 ),这可能不是您想要的。
谁能想到解决以上错误的方法?
即使绕过了这个错误,例如
__asm__(".section .eeprom,\"aw\"\n"
".globl eeprom_var2\n"
"eeprom_var2: .short eeprom_var1");
extern unsigned short eeprom_var2;
链接器退出并显示错误:
…: relocation truncated to fit: R_386_16 against symbol `eeprom_var1' defined in .eeprom section in /tmp/…
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.