我正在使用stm8s
IDE和STVD
编译器在COSMIC
微控制器上开发嵌入式应用程序。
我试图定义一个static bool
变量,以使用它仅执行一次代码片段。出乎意料的是,变量once
没有初始化为FALSE
或0
。虽然我明确初始化了它。这是我的代码段:
uint32_t crc32_buffer(void)
{
static bool once = FALSE;
uint32_t crc = 0;
if(!once)
{
calcTable();
crc = 10;
once = TRUE;
}
return crc;
}
当我尝试检查物理内存位置时,我发现每次进入新的调试会话后(甚至在硬件重新启动控制器之后)并且在运行应用程序本身之前,内存地址0x80
都具有相同的值值0x14
。
如果我修改了代码,以在变量初始化后将FALSE
分配给once
:
once = FALSE;
存储位置已更改为包含0x00
。然后,如果退出此调试会话,然后重新修改代码以删除该行代码并开始新的调试会话,则在运行应用程序之前,我发现内存位置0x80
再次具有0x14
。 / p>
我不明白是什么会阻止编译器将变量初始化为0
。我不明白甚至在运行应用程序之前,什么都可以将0x14
写入内存位置。
如果存储位置0x80
被访问(读/写),但是在到达代码段中的if
语句之前,应用程序并没有停止,我尝试设置断点。
UPDATE-2
正如许多人指出的启动过程,我没有使用默认的启动代码。但是,我正在使用自定义的。
当我使用标准启动代码而不是我使用的自定义代码时,在开始执行0
函数之前,将内存位置设置为main()
。自定义启动代码不是这种情况。
因此,当我定义一个新的static
变量并将其显式初始化为FALSE
时,这种初始化只会在main()
之前的启动代码中进行,对吧?
答案 0 :(得分:3)
如果您阅读this storage duration reference,将会看到静态存储持续时间
对象中存储的值仅在主函数之前初始化一次
因此,必须让启动代码先运行main
才能运行。调用main
函数后,该值应已初始化。
答案 1 :(得分:0)
在运行应用程序之前,我发现内存位置0x80再次具有0x14。
初始化需要代码;重置后的内存状态,之前执行的任何代码都是不确定的。
如果存储位置0x80被访问(读取/写入),我尝试设置一个断点,但是直到到达代码段中的if语句,应用程序才停止。
这听起来像是在那里的初始化。那时变量获得了什么值?可以在首次使用时而不是在运行时启动中初始化局部静态。在我看来,事实上,除了了解静态语义之外,您根本没有任何问题。
例如,如果您在static
声明本身上放置一个断点并运行它,那么我希望您会观察到该断点在首次使用初始化时就被击中一次,此后在随后的使用中不会断点调用该函数。