Встроенные системы на Rust Знакомьтесь, Embassy — ваш новый любимый фреймворк

16 Jun, 2026
9,406
🔱 1,523
👥 50

Знакомая ситуация? Вы с головой погружены в разработку для микроконтроллеров. Вокруг вас — C/C++, где каждый указатель — потенциальный источник головной боли, а отладка багов, связанных с гонками данных или переполнением стека, отнимает часы, а то и дни. Или, может быть, вы пытаетесь жонглировать задачами в какой-нибудь RTOS, которая, кажется, весит больше, чем ваш весь проект? Что, если я скажу, что есть способ писать надежный, производительный и при этом приятный код для встроенных систем?

Позвольте представить вам Embassy — фреймворк, который переворачивает представление о разработке на микроконтроллерах, привнося в этот мир всю мощь и безопасность языка Rust в связке с асинхронным программированием (async/await). Это не просто очередная библиотека; это целая философия, направленная на то, чтобы сделать embedded-разработку быстрее, безопаснее и, что немаловажно, энергоэффективнее.

Зачем Rust в мире микроконтроллеров? И при чем тут async?

Rust уже давно зарекомендовал себя как язык для системного программирования, где важны производительность и безопасность. Отсутствие сборщика мусора, нулевые накладные расходы и строгая система типов, которая отлавливает множество ошибок ещё на этапе компиляции, делают его идеальным кандидатом для embedded. Но Embassy выводит это на новый уровень, используя async/await.

Async/Await: Многозадачность без компромиссов

Забудьте о классических RTOS с переключением контекста и выделением стека для каждой задачи. В Embassy async/await позволяет реализовать кооперативную многозадачность, где задачи компилируются в оптимизированные конечные автоматы. Что это даёт?

  • Эффективность: Никаких накладных расходов на переключение контекста, как в традиционных RTOS. Это означает более быстрый и компактный код.
  • Один стек: Все асинхронные задачи могут использовать один стек, что значительно упрощает управление памятью и избавляет от необходимости подбирать размер стека для каждой задачи.
  • Низкое энергопотребление: Исполнитель async задач автоматически переводит микроконтроллер в спящий режим, когда нет активной работы, пробуждаясь только по прерываниям. Идеально для устройств, работающих от батареек годами.

Это позволяет писать сложную логику, которая кажется линейной, но на самом деле эффективно управляет несколькими процессами одновременно. Например, мигать светодиодом и одновременно ждать нажатия кнопки, не блокируя выполнение других задач:

Реклама
use defmt::info; use embassy_executor::Spawner; use embassy_time::{Duration, Timer}; use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull}; use embassy_nrf::{Peri, Peripherals}; // Объявляем асинхронные задачи #[embassy_executor::task] async fn blink(pin: Peri<'static, AnyPin>) { let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); loop { // Управление временем доступно глобально, не нужно возиться с аппаратными таймерами. led.set_high(); Timer::after_millis(150).await; led.set_low(); Timer::after_millis(150).await; } } // Функция main сама по себе является асинхронной задачей #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_nrf::init(Default::default()); // Запущенные задачи выполняются в фоновом режиме, конкурентно. spawner.spawn(blink(p.P0_13.into()).unwrap()); let mut button = Input::new(p.P0_11, Pull::Up); loop { // Асинхронно ждем событий GPIO, позволяя другим задачам // выполняться или ядру уходить в сон. button.wait_for_low().await; info!("Button pressed!"); button.wait_for_high().await; info!("Button released!"); } }

"Батарейки в комплекте": Что ещё предлагает Embassy?

Embassy — это не только про async. Это целая экосистема, которая предоставляет все необходимые инструменты для полноценной embedded-разработки.

Аппаратные абстракции (HAL)

Забудьте о прямом манипулировании регистрами! Embassy предлагает набор Hardware Abstraction Layers (HAL) для самых популярных микроконтроллеров, которые предоставляют безопасные и идиоматичные Rust API:

  • embassy-stm32 для всех семейств STM32.
  • embassy-nrf для Nordic Semiconductor nRF52, nRF53, nRF54 и nRF91.
  • embassy-rp для Raspberry Pi RP2040 и RP23xx.
  • embassy-mspm0 для Texas Instruments MSPM0.
  • Поддержка Espressif ESP32 через esp-rs/esp-hal.
  • И даже CH32V (RISC-V), Microchip PolarFire SoC и Puya Semiconductor PY32.

Это означает, что вы можете начать работать с периферией практически сразу, не тратя время на изучение даташитов на низком уровне.

Универсальное управление временем

С embassy_time вы получаете глобально доступные типы Instant, Duration и Timer, которые никогда не переполняются. Больше никаких хитрых расчетов и борьбы с аппаратными таймерами.

Готовность к реальному времени и низкому энергопотреблению

Как я уже упоминал, исполнитель Embassy умеет автоматически переводить ядро в сон. Но что, если у вас есть критичные по времени задачи? Embassy позволяет создавать несколько исполнителей с разными приоритетами, чтобы высокоприоритетные задачи могли вытеснять низкоприоритетные. Это даёт вам гибкость RTOS, но без её накладных расходов.

Сетевой стек embassy-net

Для IoT-устройств сетевые возможности критически важны. embassy-net предоставляет обширный функционал, включая Ethernet, IP, TCP, UDP, ICMP и DHCP. async здесь просто незаменим, значительно упрощая управление таймаутами и одновременное обслуживание нескольких сетевых соединений.

Беспроводные протоколы

Embassy не оставляет вас без связи:

  • Bluetooth Low Energy (BLE): Поддержка BLE 4.x и 5.x через trouble (для nRF52, nrf54, rp2040, esp32), nrf-softdevice для nRF52 и embassy-stm32-wpan для STM32WB.
  • LoRa: Проект lora-rs предоставляет асинхронный стек LoRa и LoRaWAN, прекрасно работающий с Embassy.

USB и безопасный бутлоадер

  • embassy-usb реализует полноценный USB-стек для устройств, позволяя легко создавать USB Serial (CDC ACM) или USB HID устройства.
  • embassy-boot — это легковесный бутлоадер, который обеспечивает безопасное обновление прошивки с защитой от сбоев питания, возможностью пробных загрузок и откатов.

Практическое применение: Где Embassy покажет себя?

Embassy идеально подходит для широкого круга проектов, где важны:

  • Надежность и безопасность: Благодаря Rust, количество ошибок, связанных с памятью и параллелизмом, снижается в разы.
  • Энергоэффективность: Для устройств с батарейным питанием, где каждый миллиампер на счету.
  • Производительность: Когда нужно выжать максимум из микроконтроллера, но без сложностей ручного управления.
  • Быстрая разработка: "Батарейки в комплекте" и высокоуровневые HAL'ы значительно ускоряют процесс.
  • Сложная логика: async/await позволяет элегантно управлять множеством одновременных процессов, будь то сетевые соединения, взаимодействие с датчиками или пользовательский интерфейс.

Это могут быть устройства умного дома, промышленные датчики, носимые гаджеты, медицинское оборудование или что-то совершенно новое, где вы хотите привнести современный подход к разработке.

Стоит ли попробовать?

Если вы уже работаете с Rust или только присматриваетесь к нему для embedded, Embassy — это, на мой взгляд, один из самых перспективных и зрелых фреймворков. Он предоставляет мощную, но при этом интуитивно понятную основу для создания сложных, надежных и энергоэффективных встроенных систем.

Забудьте о страхе перед низкоуровневым программированием и бесконечной отладкой. Embassy позволяет сосредоточиться на бизнес-логике вашего устройства, а не на борьбе с железом. Дайте ему шанс — и, возможно, вы больше никогда не захотите возвращаться к старым методам. Начните с документации и примеров, чтобы увидеть, как легко можно оживить ваш микроконтроллер с помощью Rust и Embassy!

🍪 Мы используем файлы cookie и сервис аналитики Яндекс.Метрика, чтобы сайт работал лучше. Продолжая пользоваться devtrends.ru, вы соглашаетесь с обработкой данных согласно Политике конфиденциальности.