我对Rust还是陌生的,在与编译器和借位检查器进行了许多斗争之后,我终于完成了我的第一个项目。但是现在我有一个问题,即二进制文件变得很大以适合微控制器的闪存。
我正在BluePill上使用具有64K闪存的STM32F103C8。最初,我能够将代码安装在mc上,并且必须逐一启用优化等功能。现在,我编译为:
[profile.dev]
codegen-units = 1
debug = 0
lto = true
opt-level = "z"
并且能够适合二进制文件。 opt-level = "s"
确实会生成一个大二进制文件。我得到的错误是:rust-lld: error: section '.rodata' will not fit in region 'FLASH': overflowed by 606 bytes
由于我的代码不足1000行,所以我说不是那么不寻常的依赖关系,这似乎很奇怪。
[有一些类似this的站点,它们提供了最小化二进制文件的方法。由于这些不是用于嵌入式的,因此无论如何都遵循了最小化的大多数方法。
我如何能够最小化二进制文件的大小并仍然能够对其进行调试?
我的依赖项是:
[dependencies]
cortex-m = "*"
panic-halt = "*"
embedded-hal = "*"
[dependencies.cortex-m-rtfm]
version = "0.4.3"
features = ["timer-queue"]
[dependencies.stm32f1]
version = "*"
features = ["stm32f103", "rt"]
[dependencies.stm32f1xx-hal]
version = "0.4.0"
features = ["stm32f103", "rt"]
也许有一个问题,因为我注意到cargo build
在不同版本中确实多次编译了一些子依赖项。
memory.x
文件内:
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}
Rustc版本rustc 1.37.0 (eae3437df 2019-08-13)
编辑
锈恐慌行为是中止。
该代码可在以下位置查看:https://github.com/DarkPhoeniz/rc-switcher-rust
我也遇到了类似的问题,也许可以阐明减少输出二进制文件大小的方法。
您已经发现其中之一:opt-level = "z"
。 s
和z
之间的区别是内联约束-本质上是编译器认为不值得进行内联的函数的大小。 z
将其指定为25,s
75。根据您要构建的内容,此大小可能会或可能不会因此而减小(并且会影响.rodata
和.text
主要)。
您可以玩的另一件事是代码上panic
上的行为。如果我没记错的话,stm32
目标同时支持unwind
和abort
,并且在unwind
配置文件中启用了dev
。正如您确定的那样,就代码大小而言,展开堆栈是一个庞大且昂贵的过程。因此,在货物文件中设置panic = "abort"
可能会进一步减小二进制文件的大小。
[除此之外,这取决于手动调整,例如cargo-binutils
之类的工具可能对此非常有用。根据您的用例,可能会偶尔需要一些剩余的cargo-binutils
实现,这绝对是您可以采取的措施。