Construindo

O primeiro passo é construir o nosso crate "binário". Como o microcontrolador possui uma arquitetura diferente do seu computador, precisaremos fazer uma compilação cruzada. A compilação cruzada no mundo do Rust é tão simples quanto passar uma flag --target extra para o rustc ou Cargo. A parte complicada é descobrir o argumento dessa flag: o nome do alvo.

Como já sabemos, o microcontrolador do micro:bit v2 possui um processador Cortex-M4F, enquanto o do v1 possui um Cortex-M0. O rustc sabe como fazer a compilação cruzada para a arquitetura Cortex-M e fornece vários alvos diferentes que abrangem as diferentes famílias de processadores dentro dessa arquitetura:

  • thumbv6m-none-eabi, para os processadores Cortex-M0 e Cortex-M1
  • thumbv7m-none-eabi, para o processador Cortex-M3
  • thumbv7em-none-eabi, para os processadores Cortex-M4 e Cortex-M7
  • thumbv7em-none-eabihf, para os processadores Cortex-M4F e Cortex-M7F
  • thumbv8m.main-none-eabi, para os processadores Cortex-M33 e Cortex-M35P
  • thumbv8m.main-none-eabihf, para os processadores Cortex-M33F e Cortex-M35PF

Para o micro:bit v2, utilizaremos o alvo thumbv7em-none-eabihf, enquanto para o v1, utilizaremos thumbv6m-none-eabi. Antes de fazer a compilação cruzada, você precisa baixar uma versão pré-compilada da biblioteca padrão (na verdade, uma versão reduzida) para o seu alvo. Isso é feito usando o rustup:

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

Você só precisa realizar o passo acima uma vez; o rustup irá reinstalar uma nova biblioteca padrão (componente rust-std) sempre que você atualizar seu toolchain. Portanto, você pode pular esta etapa se já tiver adicionado o alvo necessário ao verificar sua configuração.

Com o componente rust-std instalado, agora você pode fazer a compilação cruzada do programa usando o Cargo:

# Certifique-se de que você está no diretório `src/05-led-roulette`

# Para 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

# Para 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

NOTA Certifique-se de compilar este crate sem otimizações. O arquivo Cargo.toml fornecido e o comando de compilação acima garantirão que as otimizações estejam desativadas.

OK, agora produzimos um executável. Este executável não piscará nenhum LED, é apenas uma versão simplificada na qual iremos trabalhar mais adiante neste capítulo. Como uma verificação de integridade, vamos verificar se o executável produzido é realmente um binário ARM:

# Para micro:bit v2
# Equivalente a `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

# Para micro:bit v1
# Equivalente a `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

Em seguida, vamos gravar o programa em nosso microcontrolador.