1

我有一个静态“init”变量可以在启动时运行一次函数(RTOS),但它似乎初始化为一个随机值。如果我删除静态标签,一切都会很好。(除了它每次通过都运行 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 相关问题的答案。

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

4

1 回答 1

7

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

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

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

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

于 2020-03-11T13:56:42.503 回答