FLASH 中什么用得更多space?静态变量或全局变量
What uses up more space in FLASH? static variable or global variable
正如标题所说,在 FLASH 中(例如在 STM32 µC 中)什么用得更多 space?在函数内声明一个全局变量还是声明一个静态变量?或者它们是否相等 space?据我了解,这两个变量在程序的整个运行期间都可用。只是他们的范围不同。
您可以使用 0 初始化的全局变量和静态变量。这些通常不占用闪存,因为它们放置在程序启动时分配和清零的内存位置,而不是来自闪存。
您也可以用值初始化变量。在这种情况下,它们被放置在初始化数据段中,因此根据数据类型的大小从闪存中占用space。
函数内的静态变量也可以用代码初始化。该初始化必须在运行时发生,但只能发生一次,因此它实际上会生成更多代码,几乎在任何情况下都会比数据大小多 space (不一定,至少如果你初始化一个大的具有函数 return 值的足够结构)。您也可以对非常量全局变量做几乎相同的事情,您只需要将它们保留为 0 初始化并将赋值(例如)放在 main()
的开头,它采用相同的 space因为代码对函数作用域静态变量的初始化需要在别处进行。
结论,全局和函数范围的静态变量占用相同数量的space。
以上假定 "global variable" 在嵌入式上下文中,或作为文件范围的静态变量。如果在可动态链接的可执行文件中导出全局符号,则该符号的重定位信息将占用可执行二进制文件中的一些 space。但是,我认为给定的示例系统不支持或使用可重定位的可执行文件。
"available throughout the whole runtime"的正式术语是静态存储时长。在文件范围 ("global") 声明的变量以及在 static
声明的所有变量都具有静态存储持续时间。
因此范围和存储持续时间之间存在关系:范围可以决定变量的存储持续时间。但是范围和内存使用之间没有关系。
一个变量占用多少space只取决于该变量类型有多大。范围和存储期限与它无关。
在大多数 compilers/linkers 中,变量最终出现在 flash 中通常需要两件事:
- 必须声明为
const
,并且
- 必须有静态存储时长
如果不满足这些条件,变量将不会在 flash/nvm 中结束,无论它在哪个范围内声明。
As the title says, what uses up more space in FLASH (in an STM32 µC for example)? Declaring a global variable or declaring a static variable inside a function? Or do they take equal space?
使用 arm-none-eabi-gcc 作为 STM32 build 的参考,根本不使用任何 flash space。
未声明的全局变量和静态变量 const
如果需要启动初始化则进入 .data
部分,否则进入 .bss
部分。这两个段都由您的链接描述文件放入 SRAM。如果您使用的是 C++,那么静态 C++ 类 最终会出现在 .bss
.
如果你确实声明了它们 const
那么它们将被放入 .rodata
部分,如果你查阅你的链接描述文件,你应该会发现它们位于 [=16= 的一个小节中] 这是在闪存中。闪存通常比 SRAM 更丰富,因此请尽可能使用 const
。
最后,优化器可以出现并完全重新安排它认为合适的任何内容,包括消除存储以支持内联。
正如标题所说,在 FLASH 中(例如在 STM32 µC 中)什么用得更多 space?在函数内声明一个全局变量还是声明一个静态变量?或者它们是否相等 space?据我了解,这两个变量在程序的整个运行期间都可用。只是他们的范围不同。
您可以使用 0 初始化的全局变量和静态变量。这些通常不占用闪存,因为它们放置在程序启动时分配和清零的内存位置,而不是来自闪存。
您也可以用值初始化变量。在这种情况下,它们被放置在初始化数据段中,因此根据数据类型的大小从闪存中占用space。
函数内的静态变量也可以用代码初始化。该初始化必须在运行时发生,但只能发生一次,因此它实际上会生成更多代码,几乎在任何情况下都会比数据大小多 space (不一定,至少如果你初始化一个大的具有函数 return 值的足够结构)。您也可以对非常量全局变量做几乎相同的事情,您只需要将它们保留为 0 初始化并将赋值(例如)放在 main()
的开头,它采用相同的 space因为代码对函数作用域静态变量的初始化需要在别处进行。
结论,全局和函数范围的静态变量占用相同数量的space。
以上假定 "global variable" 在嵌入式上下文中,或作为文件范围的静态变量。如果在可动态链接的可执行文件中导出全局符号,则该符号的重定位信息将占用可执行二进制文件中的一些 space。但是,我认为给定的示例系统不支持或使用可重定位的可执行文件。
"available throughout the whole runtime"的正式术语是静态存储时长。在文件范围 ("global") 声明的变量以及在 static
声明的所有变量都具有静态存储持续时间。
因此范围和存储持续时间之间存在关系:范围可以决定变量的存储持续时间。但是范围和内存使用之间没有关系。
一个变量占用多少space只取决于该变量类型有多大。范围和存储期限与它无关。
在大多数 compilers/linkers 中,变量最终出现在 flash 中通常需要两件事:
- 必须声明为
const
,并且 - 必须有静态存储时长
如果不满足这些条件,变量将不会在 flash/nvm 中结束,无论它在哪个范围内声明。
As the title says, what uses up more space in FLASH (in an STM32 µC for example)? Declaring a global variable or declaring a static variable inside a function? Or do they take equal space?
使用 arm-none-eabi-gcc 作为 STM32 build 的参考,根本不使用任何 flash space。
未声明的全局变量和静态变量 const
如果需要启动初始化则进入 .data
部分,否则进入 .bss
部分。这两个段都由您的链接描述文件放入 SRAM。如果您使用的是 C++,那么静态 C++ 类 最终会出现在 .bss
.
如果你确实声明了它们 const
那么它们将被放入 .rodata
部分,如果你查阅你的链接描述文件,你应该会发现它们位于 [=16= 的一个小节中] 这是在闪存中。闪存通常比 SRAM 更丰富,因此请尽可能使用 const
。
最后,优化器可以出现并完全重新安排它认为合适的任何内容,包括消除存储以支持内联。