2

单击板上或 Kiel 上的重置按钮后,有什么方法可以保留一些 ram 值或全局变量

我正在使用 STM32L152ZE

4

3 回答 3

5

免责声明:我是根据在其他芯片和工具链上做这种事情的经验来回答这个问题的。我不知道基尔或那个特定的部分。

取决于重置按钮的作用。

如果它直接在 MCU 上触发外部复位中断,您可能会在复位时保留所有 RAM 值,并且仅使用 C 运行时初始化将全局变量归零/重新初始化。要验证这一点,请查看数据表中有关复位、RAM 和可能的待机/低功耗模式的部分以了解详细信息。大多数现代 MCU 都为每个主题提供了一个完整的顶级部分。

如果它是一个完整的电源重置(因为所有为芯片供电的电压都被完全移除),那么所有的赌注都被取消了。如果是这样的话,我认为唯一的选择是片上 EEPROM。

您必须查看原理图和/或检查复位状态寄存器以获得明确的答案。

所以让我们假设它的重置确实允许您保留 RAM - 如果是这种情况,那么典型的步骤是......

  1. 将一个特殊的部分(或部分?)添加到您的链接器指令文件中,该文件不是由 C 运行时 init 初始化的。

  2. 使用#pragma围绕/关联变量定义的语句来控制它的去向(即调用该特殊部分)。

  3. 在启动时,检查复位原因代码寄存器以了解 RAM 是否包含有效数据。

假设它们是两个单独编译的程序,您将需要做出类似的规定以防止引导加载程序也接触 RAM。

作为创建特殊部分的替代方案,Kiel可能会提供一个 C 运行时启动代码版本,它不会隐式地将任何全局变量“归零”,而是仅使用初始值初始化全局变量。这通常可用作缩短启动时间的一种方法。不过,您必须深入研究编译器手册(或者只需编写自己的 C 运行时初始化代码)才能做到这一点......

于 2015-04-08T12:33:26.273 回答
2

STM32L152ZE 包括一个 16 KB 的 EEPROM 和 128 字节的备份寄存器。

EEPROM 就是这样,它不会遇到 STM32 写入自己的闪存的问题,它会在写入和擦除块时停止总线,因此代码执行会停止。

备份寄存器与设备的其余部分(连同 RTC)位于一个单独的电源域上,只要该域保持电源,就可以保留数据。有一种保护机制需要特定的顺序来读取和写入这些寄存器。

如果它只是在您感兴趣的复位中幸存下来,那么我相信只要通过复位保持电源(即不是通过电源循环复位),那么 SRAM 就会保持不变。但是默认情况下,Keil 项目配置为在启动时将所有 IRAM 段初始化为零;您可以将项目设置中的一个部分保留为“no-init”部分,并使用变量__attribute__扩展来显式实例化该部分或特定地址的变量。

于 2015-04-08T20:48:00.063 回答
1

如果您使用的是 Keil IDE 而不是使用您自己的链接器配置文件,那么它非常简单。在“目标的选项 - 目标”中有一个读/写内存区域部分,在这里您定义一个新区域,所有未初始化的变量都将放置在其中。例如 start- 0x20000000 和大小 0x20 如果您的 RAM 从 0x20000000 开始并且您希望在重置后保留前 32 个字节,请选中“NoInit”框。然后在“目标选项 - 链接器”中,确保选择“使用目标对话框中的内存布局”选项,以便自动生成链接器 SCT 文件。

现在最后一步是将变量放入 0x20000000 到 0x20000020 区域。您在项目的单个文件中声明所有未初始化的变量。现在右键单击项目窗口中的文件名并选择选项“选项文件 "xxx.c" " 并在内存分配中为 ZI 数据选择 0x20000000 到 0x20000020 区域。(希望您的未初始化变量在声明期间未在代码中分配任何值)

于 2017-03-02T11:47:03.057 回答