【问题标题】:Static variable doesn't initialize to given value静态变量未初始化为给定值
【发布时间】:2020-06-23 12:10:55
【问题描述】:

我有一个静态“init”变量在启动时运行一次函数,(RTOS),但它似乎初始化为一个随机值。如果我删除 static 标签,一切都会很好。 (除了它每次传递都运行 init 函数的明显问题。) 谁能提供更多关于为什么这不起作用或更好的方法来实现这一点?

示例代码:

void ManageStructures()
{
    // Variable declarations/definitions
    static uint8_t StructInitialized;
    // Have also tried "static uint8_t StructInitialized = 0", neither worked

    // Function prototypes
    void InitStruct();

    if (!StructInitialized)
    {
        StructInitialized= 1;
        InitStruct();
    }
    Test = StructInitialized;

编辑:对于信息不足,我深表歉意。这是针对一家公司的,我正努力遵守我们的公共信息政策。该MCU是使用“Ac6 STM32 MCU GCC”工具链的STM32F7系列。我不精通编译器操作,因此可能需要更长时间才能找到编译器或 makefile 相关问题的答案。

edit:很明显,这是编译器或链接器脚本的问题,而不是我的代码。话虽如此,但在找到问题的根源之前,我还需要了解更多关于工具链、链接器脚本和编译器的知识。一旦我熟悉到足以提供有价值的反馈或自己回答这个问题,我会回到这个问题。谢谢大家的反馈和指导!

【问题讨论】:

  • 该代码可以在标准环境中运行。您的 RTOS 在启动时可能无法正确初始化程序的相关数据部分(例如,在处理低级 RTOS 或裸机编程时忘记将 .bss 部分归零是一个常见问题),从而使您的静态变量带有任何垃圾在记忆中的那个位置。另一个问题可能是您的程序+rtos 的内存映射不正确。
  • 但它似乎初始化为随机值。应该是0,否则你的编译器坏了
  • @ChristianGibbons 为什么不呢?
  • 除了已经提到的特定编译器问题之外,还有另一个可能的原因。静态变量都存储在数据段的某处(如果未初始化或初始化为 0,则在 BSS 中)。如果您的变量放置在数组附近并且被错误地访问(超出范围),则可能会发生您的变量以某种方式被覆盖。
  • ... 这就是为什么我们通常希望使用 minimal reproducible example 来引用。没有理由明显显示代码片段表现出所描述的行为,但我们没有足够的信息来评估程序整体具有 UB 的可能性。

标签: c embedded static-variables variable-initialization


【解决方案1】:

嵌入式系统通常使用“最小启动”代码运行,这意味着它们在启动期间从不初始化 .bss.data。这意味着如果您编写类似static int foo = 42; 的内容,代码将编译但永远不会设置变量。

这不是标准的 C 编译器,因此通常在创建项目时,您可以从 IDE 中选择“最小”或“标准”启动。

这可能存在于随您的工具链而不是 RTOS 交付的所谓“CRT”(C 运行时)中。如果您从程序实际开始的位置(重置向量)而不是从 main() 开始的位置单步执行程序,您将能够准确地看到 CRT 做什么和不做什么。

不幸的是,调试器经常使用“笨拙模式”,因为现在嵌入式系统程序员默认情况下被认为是完全无能的。这意味着它们会在 main() 处静默插入断点并运行到该点。为了调试 CRT,您可能必须“取消哑巴”您的调试器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 2011-08-22
    • 2010-12-22
    • 1970-01-01
    相关资源
    最近更新 更多