在RAM初始化之前使用#defined值

Éti*_*nne 6 c arm linker-scripts c-preprocessor

我正在编写ARM CPU的启动代码.没有内部RAM,但是有1GB的DDRAM连接到CPU,在初始化之前无法直接访问.代码存储在闪存中,初始化RAM,然后将自身和数据段复制到RAM并继续执行.我的计划是:

#define REG_BASE_BOOTUP 0xD0000000
#define INTER_REGS_BASE REG_BASE_BOOTUP

#define SDRAM_FTDLL_REG_DEFAULT_LEFT            0x887000

#define DRAM_BASE               0x0
#define SDRAM_FTDLL_CONFIG_LEFT_REG (DRAM_BASE+ 0x1484)
... //a lot of registers

void sdram_init() __attribute__((section(".text_sdram_init")));

void ram_init()
{
  static volatile unsigned int* const sdram_ftdll_config_left_reg = (unsigned int*)(INTER_REGS_BASE + SDRAM_FTDLL_CONFIG_LEFT_REG);
  ... //a lot of registers assignments

  *sdram_ftdll_config_left_reg = SDRAM_FTDLL_REG_DEFAULT_LEFT;
}
Run Code Online (Sandbox Code Playgroud)

目前我的程序工作不正常,因为寄存器值最终被链接到RAM,并且在程序尝试访问它们时,只有闪存可用.

我怎么能改变我的链接器脚本或我的程序,以便这些值在闪存中的地址?有没有办法在文本段中包含这些值?

实际上,当它们在文件范围内声明时,那些定义的值是全局数据还是静态数据?

编辑:

目标文件与以下链接描述文件链接:

MEMORY 
{                                                                                                             
RAM (rw)    : ORIGIN = 0x00001000, LENGTH = 12M-4K                                
ROM (rx)    : ORIGIN = 0x007f1000, LENGTH = 60K
VECTOR (rx) : ORIGIN = 0x007f0000, LENGTH = 4K   
}
SECTIONS
{
    .startup :
    {
    KEEP((.text.vectors))
    sdram_init.o(.sdram_init)
    } > VECTOR
...
}
Run Code Online (Sandbox Code Playgroud)

从寄存器分配中反汇编:

  *sdram_ftdll_config_left_reg = SDRAM_FTDLL_REG_DEFAULT_LEFT;
  7f0068:       e59f3204        ldr     r3, [pc, #516]  ; 7f0274 <sdram_init+0x254>
  7f006c:       e5932000        ldr     r2, [r3]
  7f0070:       e59f3200        ldr     r3, [pc, #512]  ; 7f0278 <sdram_init+0x258>
  7f0074:       e5823000        str     r3, [r2]
  ...
  7f0274:       007f2304        .word   0x007f2304
  7f0278:       00887000        .word   0x00887000
Run Code Online (Sandbox Code Playgroud)

小智 4

直接回答你的问题——#defined值不会存储在程序的任何地方(除了可能在调试部分)。宏在编译时展开,就像您在函数中键入它们一样,如下所示:

*((unsigned int *) 0xd0010000) = 0x800f800f;
Run Code Online (Sandbox Code Playgroud)

这些值最终会出现在文本段中,作为编译代码的一部分。

更有可能的是,您还做错了其他事情。在我的脑海中,我的第一个猜测是您的堆栈未正确初始化,或者位于尚不可用的内存区域中。

  • 没关系——编译器仍然会假设堆栈已初始化,并且最终可能会尝试使用它。如果您不相信我,请尝试反汇编编译后的文件。 (2认同)
  • @Étienne 你的错误实际上正如我在消息的最后一条评论中所描述的那样(回复*duskwuff*);您已使用定义分配了一个静态变量指针。我还认为你不会有堆栈问题,因为“gcc”处理 ARM 叶函数的方式,但无论如何这是一个好点,因为它是一个定时炸弹。 (2认同)