在 SRAM 中保留 space 用于 SRAM 衰减实验(C;AVR atmega644p;Atmel Studio 7)

Reserving space in SRAM for SRAM decay experiment (C ; AVR atmega644p ; Atmel Studio 7)

我希望在 atmega644p 上进行一些实验,以评估电源周期之间 SRAM 的衰减量。我的方法是将SRAM中的字节数设置为0xFF,然后当mcu上电时,统计这些字节中剩余1的个数。

为此,我需要读取和写入 1 的数组 to/from SRAM 中的已知内存地址。到目前为止,我有代码使用设置为 0x1000 的指针将值写入特定地址,然后在加电时我开始从该地址读取数组。但是,我需要一种方法来保证这部分 SRAM 内存(比如 0x100 + 64 字节)在读取之前不会分配给其他 variables/overwritten。

我在网上查看了分配内存段的可能性 - 我不知道在这种情况下这是否是一个好的解决方案,我什至不太确定如何去做。谁能建议一种巧妙的方法来解决这个问题?

如有任何问题请提问。

感谢您的帮助。

您需要通过在链接器文件中为它保留 space 来在 RAM 中创建一个自定义区域。重要的是它被标记为“no init”或类似的,否则 .bss 初始化和类似的可能会在调用 main() 之前发生在它上面。如何做到这一点是 linker-specific。

然而,为此编写软件似乎不必要地麻烦。只需使用 in-circuit 调试器:

  • 确保您使用的调试器不为目标供电。
  • 下载一个完全没有 RAM 的程序到闪存中。通过检查地图文件来确认这一点。
  • 通过调试器将整个 RAM 设置为 0xFF。
  • 断开电源,同时保持 in-circuit 调试器连接。
  • 等待 x 个时间单位。
  • 加电,在调试器中点击 MCU 复位,内存转储整个 RAM。

任何 half-decent 工具链都应该能够为您执行此操作。

如果您正在使用 AVR/GNU,那么当 C 应用程序启动时,它会清除整个内存并根据需要初始化全局变量。

为避免这种情况,您可以使用选项 -nostartfiles -nodefaultlibs -nostdlib

配置链接器以排除所有启动文件

如果您使用的是 Atmel Studio,您可以这样配置它:

之后你可以将你的main标记为初始化代码:

int main(void) __attribute__((naked, section(".init9")));

现在您将拥有不执行任何初始化的“裸”代码。 这意味着您至少需要初始化堆栈指针并清除寄存器 r1(avr-gcc 假定它包含零):

int main(void) {
    asm volatile (
        "clr r1\n" // load zero into r1
        "cli" // clear I flag  
    );
    SPL = (uint8_t)RAMEND;
    SPH = (uint8_t)(RAMEND >> 8);


    ... // here goes your code

    for(;;); // do not leave main()!
}

在此之后,您将拥有所有未初始化的全局变量。例如,您可以声明一个全局数组并在启动时检查其内容。