构建

第一步是构建我们的"binary" crate。因为微控制器的架构与您的计算机不同,所以我们必须交叉编译。 在Rust领域进行交叉编译就像向rustc或Cargo传递一个额外的--target标志一样简单。 复杂的部分是弄清楚这个标志的参数:目标的名称

我们已经知道micro:bit v2上的微控制器内部有一个Cortex-M4F处理器,v1上的那个是Cortex-M0。 rustc知道如何交叉编译到Cortex-M架构,并提供了几个不同的目标,涵盖了该架构中的不同处理器系列:

  • thumbv6m-none-eabi,适用于Cortex-M0和Cortex-M1处理器
  • thumbv7m-none-eabi,适用于Cortex-M3处理器
  • thumbv7em-none-eabi,适用于Cortex-M4和Cortex-M处理器
  • thumbv7em-none-eabihf,适用于Cortex-M4F和Cortex-M7F处理器
  • thumbv8m.main-none-eabi,适用于Cortex-M33和Cortex-M35P处理器
  • thumbv8m.main-none-eabihf,适用于Cortex-M33F和Cortex-M35PF处理器

对于micro:bit v2,我们将使用thumbv7em-none-eabihftarget,对于v1,我们将使用thumbv6m-none-eabitarget。 在交叉编译之前,您必须为您的目标下载标准库的预编译版本(实际上是它的简化版本)。这是使用rustup:

# For micro:bit v2
$ rustup target add thumbv7em-none-eabihf
# For micro:bit v1
$ rustup target add thumbv6m-none-eabi

您只需执行上述步骤一次;每当您更新工具链时,rustup都会重新安装新的(rust-std组件)。 因此如果您在验证步骤时已经添加了必要的target,则可以跳过此步骤。

有了rust-std组件,您现在可以使用Cargo交叉编译程序:

# make sure you are in the `src/05-led-roulette` directory

# For micro:bit v2
$ cargo build --features v2 --target thumbv7em-none-eabihf
   Compiling semver-parser v0.7.0
   Compiling typenum v1.12.0
   Compiling cortex-m v0.6.3
   (...)
   Compiling microbit-v2 v0.10.1
    Finished dev [unoptimized + debuginfo] target(s) in 33.67s

# For micro:bit v1
$ cargo build --features v1 --target thumbv6m-none-eabi
   Compiling fixed v1.2.0
   Compiling syn v1.0.39
   Compiling cortex-m v0.6.3
   (...)
   Compiling microbit v0.10.1
	Finished dev [unoptimized + debuginfo] target(s) in 22.73s

注意:一定要编译这个crate而不进行优化。上面提供的Cargo.toml文件和构建命令将确保优化关闭。

好的,现在我们已经生成了一个可执行文件。这个可执行文件不会闪烁任何LED,它只是一个简化版本,我 们将在本章后面进行构建。作为健全性检查,让我们验证生成的可执行文件实际上是ARM二进制文件:

# For micro:bit v2
# equivalent to `readelf -h target/thumbv7em-none-eabihf/debug/led-roulette`
$ cargo readobj --features v2 --target thumbv7em-none-eabihf --bin led-roulette -- --file-headers
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x117
  Start of program headers:          52 (bytes into file)
  Start of section headers:          793112 (bytes into file)
  Flags:                             0x5000400
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         4
  Size of section headers:           40 (bytes)
  Number of section headers:         21
  Section header string table index: 19

# For micro:bit v1
# equivalent to `readelf -h target/thumbv6m-none-eabi/debug/led-roulette`
$ cargo readobj --features v1 --target thumbv6m-none-eabi --bin led-roulette -- --file-headers
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0xC1
  Start of program headers:          52 (bytes into file)
  Start of section headers:          693196 (bytes into file)
  Flags:                             0x5000200
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         4
  Size of section headers:           40 (bytes)
  Number of section headers:         22
  Section header string table index: 20

接下来,我们将把程序嵌入到我们的微控制器中。