Настройка для встраиваемой разработки
Посмотрим на первую программу, которую будем собирать. Откройте файл examples/init.rs:
#![deny(unsafe_code)]
#![no_main]
#![no_std]
use cortex_m::asm;
use cortex_m_rt::entry;
use microbit as _;
use panic_halt as _;
#[entry]
fn main() -> ! {
#[allow(clippy::needless_late_init)]
let _y;
let x = 42;
_y = x;
// бесконечный цикл, чтобы не покидать этот стековый фрейм
loop {
asm::nop();
}
}
Программы для микроконтроллеров отличаются от обычных программ в двух аспектах: #![no_std] и #![no_main].
Атрибут no_std означает, что программа не будет использовать крейт std, который предполагает наличие операционной системы; вместо этого программа будет использовать крейт core — подмножество std, которое может работать на bare-metal системах (то есть на системах без абстракций ОС вроде файлов и сокетов).
Атрибут no_main означает, что программа не использует стандартный интерфейс main, рассчитанный на консольные приложения, которые получают аргументы. Вместо стандартного main мы используем атрибут entry из крейта cortex-m-rt, чтобы определить собственную точку входа. В этой программе точку входа назвали main, но можно было выбрать любое другое имя. Функция точки входа должна иметь сигнатуру fn() -> !; этот тип показывает, что функция не может вернуть управление. Это значит, что программа никогда не завершается возвратом из main: если компилятор обнаружит такую возможность, он откажется собирать программу.
Если вы внимательны, то заметите и скрытый каталог .cargo в проекте Cargo. В нём лежит файл конфигурации Cargo .cargo/config.toml.
[build]
target = "thumbv7em-none-eabihf"
[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip nRF52833_xxAA"
rustflags = [
"-C", "linker=rust-lld",
]
Этот файл настраивает процесс компоновки, подгоняя раскладку памяти программы под требования целевого устройства. Изменённый процесс линковки — требование крейта cortex-m-rt. Файл .cargo/config.toml также сообщает Cargo, как собирать и запускать код на нашем MB2.
Здесь также есть файл Embed.toml:
[default.general]
chip = "nrf52833_xxAA"
[default.reset]
halt_afterwards = true
[default.rtt]
enabled = false
[default.gdb]
enabled = true
Этот файл сообщает cargo-embed, что:
- Мы работаем с NRF52833.
- После прошивки чип нужно остановить, чтобы программа остановилась до
main. - Нужно отключить RTT. RTT — протокол, который позволяет чипу отправлять текст отладчику. Вы уже видели RTT в действии: именно по этому протоколу в главе 3 выводилась строка «Hello World».
- Нужно включить GDB. Это понадобится для отладки.
Теперь, когда мы разобрались, что происходит, начнём со сборки этой программы.