【问题标题】:Value of variables are changed unexpectedly变量的值被意外更改
【发布时间】:2021-10-17 22:19:32
【问题描述】:

我正在 GHS 环境中编写嵌入式代码,我遇到了一个以前从未遇到过的奇怪问题。除了在运行时初始化的常量之外的所有全局变量都设置为数据类型的最大值。例如:

我定义了一个全局变量:

静态 uint8 Dcm_Cbk_Gu8_FirstReqAfterReset = 1;

但是,无论初始值是多少,变量的值始终设置为 255。我确信该变量尚未在代码中的任何地方使用。如果数据类型为uint16,则该值应始终为 65535,直到在运行时更改。好吧,它发生在所有全局变量上,不管数据类型是什么。

请注意,如果变量被全局声明并在运行时初始化,则不会发生这种情况,但这种方式违反了编码约定。

实际上,一切都在另一个环境中运行良好(由 make 构建)但是当我合并代码(*.c,*h)并将整个链接器文件移动到不同的环境(由 Scon 结构构建)时,我得到了问题。使用的MCU是合唱10M(SPC58NH92)。

任何人都知道原因,你能扩大我的知识吗?谢谢!

【问题讨论】:

  • 看起来你没有加载器来初始化你的数据段(我已经在这样的环境中运行过)或者你的链接器部分设置不正确。但是,我希望看到随机数据,而不是所有 0xFF——这与未初始化的闪存比 RAM 更一致。
  • 您的链接器文件是否会意外地将您的 .data 段指向闪存中的地址?然后加载程序无法成功设置值,未写入的闪存(几乎总是)全为 0xFF。
  • 也许可以提供更多信息——也许是您的链接器定义文件?什么处理器? (顺便说一句,当我使用 GreenHills 时,iirc,我有一个没有初始化 .data 段的加载器环境)
  • 谢谢!但我无法显示我的链接器定义文件,因为它归企业所有,我从客户那里获得了文件。实际上,一切都在另一个环境中运行良好(由 make 构建),但是当我合并代码(*.c,*h)并将整个链接器文件移动到不同的环境(由 Scon 结构构建)时,我遇到了问题。使用的MCU是合唱10M(SPC58NH92)。
  • 我已经解决了这个问题,这是因为汇编启动代码不正确。我将我的启动代码与其他代码进行了比较,然后添加了 asm(".globl _start")、asm(".global __start") 和 asm(".align 4")。现在效果很好。但老实说,我不明白这些 asm 命令,为什么它们应该在那里。无论如何,非常感谢您的帮助!

标签: memory initialization embedded greenhills


【解决方案1】:

由于问题中的信息有限,很难给出明确的答案。不过我可以告诉你它对我来说是什么样的。

初始化的全局或静态变量组成 .data 部分。这些值应存储在只读内存中(通常在 .text 中),并应在程序启动例程期间复制到 .data 段中。

如果启动例程中没有适当的代码来复制这些值,它们将被取消初始化。所以,检查你是否有这样的代码。 (我确实在 GreenHills 环境中工作,我们没有编译器提供此类代码。我们可以选择自己编写或不使用 .data 段并在 main 开头初始化所有内容)。

但是,这不太可能是您的全部问题。您可能有也可能没有正确的启动代码。如果您的内存段设置正确但缺少启动代码,我希望在 RAM 中看到随机值。在我看来,一致的 0xFF 是以下两种情况之一:

  1. 将所有 RAM 预初始化为 0xFF 的启动代码,以及在此之前加载(并被覆盖)或根本不加载的值
  2. 您的链接器文件设置不正确,位于闪存而不是 RAM 中的 .data 段(未初始化的闪存通常都是 0xFF,这就是您所看到的。

我认为第二种可能性更大,但我既不知道硬件的内存映射,也不知道链接器定义文件中的设置。您必须自己检查。

【讨论】:

    猜你喜欢
    • 2014-10-21
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多