Терминология Rust Embedded
Прежде чем приступить к программированию micro:bit, быстро познакомимся с библиотеками и терминологией, которые будут важны во всех следующих главах.
Уровни абстракции
Для любого полностью поддерживаемого микроконтроллера или платы с микроконтроллером вы обычно услышите такие термины для обозначения уровней абстракции:
Peripheral Access Crate (PAC)
Задача PAC — предоставить относительно безопасный прямой интерфейс к периферии чипа, позволяя настроить каждый бит так, как вам нужно (разумеется, в том числе и неправильно). Обычно с PAC приходится работать, только если верхние уровни не удовлетворяют вашим потребностям или если вы разрабатываете для них код более высокого уровня. Неудивительно, что PAC, который мы (по большей части неявно) будем использовать, — это PAC для nRF52.
Hardware Abstraction Layer (HAL)
Задача HAL — надстроиться над PAC чипа и предоставить абстракцию, которой действительно удобно пользоваться тому, кто не знает всех особенностей этого чипа. Обычно HAL скрывает целую периферию за отдельными структурами, с помощью которых, например, можно передавать данные через периферийное устройство. Мы будем использовать nrf52-hal.
Board Support Crate (BSP)
(В не-Rust окружении это обычно называют Board Support Package — отсюда и аббревиатура.)
Задача BSP — абстрагировать сразу всю плату (например, micro:bit). Это значит, что он должен предоставлять абстракции и для работы с микроконтроллером, и для датчиков, светодиодов и прочих компонентов, которые могут быть на плате. Довольно часто (особенно для самодельных плат) готового BSP не существует. Вместо этого вы будете работать с HAL для чипа и либо сами писать драйверы для датчиков, либо искать их на crates.io. К счастью, для micro:bit есть BSP, поэтому мы будем использовать его поверх нашего HAL.
Объединение уровней
Далее рассмотрим очень важную часть программного обеспечения в экосистеме Rust Embedded: embedded-hal. Как следует из названия, она относится ко второму уровню абстракции, с которым мы уже познакомились: к HAL. Идея embedded-hal — предоставить набор трейтов, описывающих поведение, которое обычно общее для всех реализаций конкретной периферии во всех HAL. Например, почти всегда нужны функции, которые включают и выключают вывод (скажем, чтобы зажечь и погасить светодиод на плате).
embedded-hal позволяет написать драйвер для какого-либо устройства, например датчика температуры, который можно использовать на любом чипе, для которого существует реализация трейтов embedded-hal. Этого добиваются, написав драйвер так, чтобы он опирался только на трейты embedded-hal. Такие драйверы называют не зависящими от платформы (platform-agnostic). К счастью для нас, драйверы, которые мы будем брать с crates.io, почти все не зависят от платформы.
Дополнительные материалы
Если хотите узнать больше об этих уровнях абстракции, Франц Скарман (он же TheZoq2) выступил с докладом на эту тему на конференции Oxidize 2020: An Overview of the Embedded Rust Ecosystem.