Rust 嵌入的二进制大小

l4z*_*6_z 8 embedded rust

我是 Rust 新手,经过与编译器和借用检查器的多次斗争,我终于快完成了我的第一个项目。但现在我遇到了一个问题,二进制文件变得很大,无法适应微控制器的闪存。

我在 BluePill 上使用带有 64K 闪存的 STM32F103C8。起初,我能够将代码安装到 mc 上,并且我必须一点一点地启用优化等。现在我编译:

[profile.dev]
codegen-units = 1
debug = 0
lto = true
opt-level = "z"
Run Code Online (Sandbox Code Playgroud)

并且能够安装二进制文件。opt-level = "s"确实会生成一个很大的二进制文件。我收到的错误是:rust-lld: error: section '.rodata' will not fit in region 'FLASH': overflowed by 606 bytes

由于我的代码不足 1000 行,并且我想说并不是那么不寻常的依赖关系,这看起来很奇怪。

有一些类似的网站提供了最小化二进制文件的方法。由于这些不适用于嵌入式,因此无论如何都会遵循大多数最小化方法。

我怎样才能最大限度地减少二进制文件的大小并仍然能够对其进行调试?

我的依赖项是:

[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"]
Run Code Online (Sandbox Code Playgroud)

也许存在一个问题,因为我注意到确实cargo build在不同版本中多次编译某些子依赖项。

文件内memory.x

MEMORY
{
  FLASH : ORIGIN = 0x08000000, LENGTH = 64K
  RAM : ORIGIN = 0x20000000, LENGTH = 20K
}
Run Code Online (Sandbox Code Playgroud)

Rustc版本rustc 1.37.0 (eae3437df 2019-08-13)

编辑

Rust Panic 行为被中止。

代码可以在以下位置查看:https ://github.com/DarkPhoeniz/rc-switcher-rust

Séb*_*uld 7

我遇到过类似的问题,也许能够阐明您可以采取哪些措施来减少输出的二进制文件的大小。

您已经发现了其中之一:opt-level = "z"s和之间的区别z是内联约束 - 本质上是编译器认为不值得内联的函数的大小。z将其指定为 25, s75。根据您正在构建的内容,这可能会或可能不会导致尺寸减小(并且它主要影响.rodata.text

panic您可以利用的另一件事是代码上的行为。如果我没记错的话,stm32目标支持unwindabort,并在配置文件unwind上启用dev。我相信您可以理解,就代码大小而言,展开堆栈是一个庞大且成本高昂的过程。因此,panic = "abort"在货物文件中进行设置可能会进一步减少二进制大小。

除此之外,这取决于手动调整,类似的工具cargo-binutils对此可能非常有用。根据您的用例,可能会有一些Debug仅偶尔需要的剩余实现,这绝对是您可以采取的行动。


eff*_*ect 6

缩小二进制文件的其他一些一般技巧:

首先,cargo-bloat实用程序对于确定二进制文件中占用空间的内容非常有用,然后您可以就如何修改代码以缩小其大小做出明智的决定。

其次,通过配置编译器来优化所有依赖项,我取得了巨大的成功,但保留了顶层板条箱未优化以便于调试。您可以通过将以下内容添加到 Cargo.toml 来做到这一点:

# Optimize all dependencies
[profile.dev.package."*"]
opt-level = "z"
Run Code Online (Sandbox Code Playgroud)

如果您想调试特定的依赖项(例如:cortex-m-rt),您可以将其设为未优化,如下所示:

# Don't optimize the `cortex-m-rt` crate
[profile.dev.package.cortex-m-rt]
opt-level = 0

# Optimize all the other dependencies
[profile.dev.package."*"]
opt-level = "z"
Run Code Online (Sandbox Code Playgroud)