Roleta LED

Certo, vamos começar construindo a seguinte aplicação:

Vou fornecer a você uma API de alto nível para implementar este aplicativo, mas não se preocupe, faremos coisas de baixo nível posteriormente. O objetivo principal deste capítulo é familiarizar-se com o processo de flashing e depuração.

O código inicial está no diretório src do repositório do livro. Dentro desse diretório, existem mais diretórios com nomes de cada capítulo deste livro. A maioria desses diretórios são projetos iniciais de Cargo.

Agora, vá para o diretório src/05-led-roulette. Verifique o arquivo src/main.rs:

#![deny(unsafe_code)]
#![no_main]
#![no_std]

use cortex_m_rt::entry;
use microbit as _;
use panic_halt as _;

#[entry]
fn main() -> ! {
    let _y;
    let x = 42;
    _y = x;

    // loop infinito; apenas para não sairmos deste stack frame
    loop {}
}

Programas para microcontroladores são diferentes de programas convencionais em dois aspectos: #![no_std] e #![no_main].

O atributo no_std indica que este programa não usará o crate std, que pressupõe a existência de um sistema operacional subjacente. Em vez disso, o programa usará o crate core, que é um subconjunto do std que pode ser executado em sistemas bare metal (ou seja, sistemas sem abstrações de sistema operacional, como arquivos e sockets).

O atributo no_main indica que este programa não usará a interface main padrão, que é adequada para aplicativos de linha de comando que recebem argumentos. Em vez do main padrão, utilizaremos o atributo entry do crate [cortex-m-rt] para definir um ponto de entrada customizado. Neste programa, nomeamos o ponto de entrada como "main", mas poderíamos ter usado qualquer outro nome. A função de ponto de entrada deve ter a assinatura fn() -> !, indicando que a função não pode retornar -- isso significa que o programa nunca termina.

Se você for um observador cuidadoso, também notará que existe um diretório .cargo no projeto Cargo. Esse diretório contém um arquivo de configuração do Cargo (.cargo/config) que ajusta o processo de linking para adaptar o layout de memória do programa aos requisitos do dispositivo alvo. Esse processo de linking modificado é um requisito do crate cortex-m-rt.

Além disso, há também um arquivo Embed.toml.

[default.general]
# chip = "nrf52833_xxAA" # para micro:bit V2, descomente essa linha
# chip = "nrf51822_xxAA" # para micro:bit V1, descomente essa linha

[default.reset]
halt_afterwards = true

[default.rtt]
enabled = false

[default.gdb]
enabled = true

Este arquivo informa ao cargo-embed que:

  • Estamos trabalhando com um nrf52833 ou nrf51822. Você terá que remover novamente os comentários do chip que estiver usando, assim como fez no capítulo 3.
  • Desejamos interromper o chip depois de gravá-lo para que nosso programa não salte instantaneamente para o loop.
  • Queremos desabilitar o RTT, que é um protocolo que permite ao chip enviar texto para um depurador. Na verdade, você já viu o RTT em ação: ele foi o protocolo que enviou "Hello World" no capítulo 3.
  • Desejamos habilitar o GDB, pois isso será necessário para o procedimento de depuração.

Certo, vamos começar construindo este programa.