Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Периферия

Прежде чем переходить к следующей части, давайте кратко разберёмся, что такое периферия.

Во встраиваемых системах периферия — это аппаратные компоненты, которые расширяют возможности микроконтроллера (MCU). Они позволяют MCU взаимодействовать с внешним миром: обрабатывать входы и выходы, выполнять обмен данными, работать со временем и многое другое.

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

Разгрузка (offloading)

Offloading — это делегирование отдельных задач аппаратной периферии вместо того, чтобы выполнять их программно на ЦП. Это повышает производительность, снижает энергопотребление и позволяет выполнять операции параллельно. Например:

  • UART может отправлять и принимать данные в фоновом режиме с помощью DMA (Direct Memory Access), пока ЦП продолжает обрабатывать другую логику.
  • Таймер можно настроить так, чтобы он генерировал точные задержки или периодические прерывания без участия ЦП.
  • Контроллер ШИМ может непрерывно управлять мотором, не требуя от ЦП постоянно переключать выводы.

Offloading — ключевой принцип проектирования встраиваемых систем, позволяющий эффективно использовать ограниченную вычислительную мощность.

Распространённые типы периферии

Ниже перечислены наиболее распространённые типы периферии во встраиваемых системах:

ПериферияОписание
GPIO (General Purpose Input/Output)Цифровые выводы, которые можно настроить как входы или выходы для взаимодействия с внешними устройствами, такими как кнопки, светодиоды и датчики.
UART (Universal Asynchronous Receiver/Transmitter)Интерфейс последовательной связи для отправки и приёма данных между устройствами; часто используется для отладки и подключения модулей, например Bluetooth.
SPI (Serial Peripheral Interface)Высокоскоростной синхронный протокол для подключения микроконтроллера к периферии, например SD-картам, дисплеям и датчикам, по архитектуре «ведущий–ведомый» (master-slave).
I2C (Inter-Integrated Circuit)Двухпроводной протокол последовательной связи для подключения низкоскоростных устройств, таких как датчики и микросхемы памяти, к микроконтроллеру.
ADC (Analog-to-Digital Converter)Преобразует аналоговые сигналы от датчиков или других источников в цифровые значения, которые может обработать микроконтроллер.
PWM (Pulse Width Modulation)Формирует сигналы, которыми можно управлять подачей мощности; обычно используется для регулировки яркости светодиодов, управления скоростью мотора и работы сервоприводов.
TimerИспользуется для генерации задержек, измерения временных интервалов, подсчёта событий или запуска действий в заданное время.
RTC (Real-Time Clock)Отслеживает текущее время и дату даже при выключенном питании системы; обычно питается от батареи.

Периферия в Rust

Во встраиваемом Rust периферия используется по модели singleton. Одна из главных целей Rust — безопасность, и это касается и работы с железом. Чтобы никакие две части программы случайно не управляли одной и той же периферией одновременно, Rust обеспечивает эксклюзивное владение через этот подход.

Паттерн Singleton

Паттерн singleton гарантирует, что во всей программе существует только один экземпляр каждой периферии. Это позволяет избежать распространённых ошибок, когда несколько фрагментов кода одновременно пытаются изменить один и тот же аппаратный ресурс.

В esp-hal периферия тоже предоставляется в виде singleton. Но мы не будем вызывать Peripherals::take() напрямую. Вместо этого используем функцию esp_hal::init(config). Она выполняет базовую настройку системы и внутри вызывает Peripherals::take() за нас. Так мы получаем доступ ко всей периферии в безопасном и готовом к использованию виде.