在GCC中获取指针的低16位编译时间

时间:2014-12-08 09:31:40

标签: c gcc linker embedded eeprom

我正在从事嵌入式项目。我试图使用GNU链接器来布局存储在外部eeprom中的一些变量。我这样做是通过使用

分配eeprom变量
int __attribute__ ((section (".eeprom")))  eeprom_var1;

我还将为eeprom定义初始化变量,例如:

int __attribute__ ((section (".eeprom")))  eeprom_var2 = 0x42;

然后就是这个想法;在初始化eeprom时,正在运行的应用程序将初始化变量从.text部分的某个地方复制到eeprom,就像初始化数据部分一样。显然,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;

^

这是因为转换为(unsigned short)作为初始化程序读取操作,C中不允许使用。在C ++中,上面的表达式是正确的。

任何人都可以想办法解决上面的错误吗?

/安德斯

2 个答案:

答案 0 :(得分:0)

  • 将变量放入片上eeprom时,它们总是需要const type类型。
  • 在片上eeprom中放置指针时,它们总是需要类型type* const(指向非常量数据的常量指针)或const type* const(常量数据的常量指针)。

这似乎是您问题的真正根源。当然,一旦它们被宣布为常量,你就不应该抛弃常量。

另外,如果它是片上eeprom,是否有理由不能直接访问存储单元?在大多数系统上,您可以执行此操作,但访问时间可能比对RAM变量的等效访问速度慢。

作为旁注,转换为uint16_t(或无符号短整数)只会在小端机器上提供16个最低有效位。代码不能移植到big endian。可移植代码为((uint32_t)pointer >> 16)

答案 1 :(得分:0)

  

但是在C ++中,上面的表达式还可以。

C ++编译器接受初始化,但是在运行时执行(参见Spurious error: initializer element is not computable at load time),这可能不是你想要的。

  

任何人都可以想办法解决上面的错误吗?

即使在解决了这个错误之后,e。 G。与

__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/…