Для электронщиков и радиолюбителей

Создание собственного протокола связи с использованием PIO и DMA на Raspberry Pi Pico

Создание собственного протокола связи с использованием PIO и DMA на Raspberry Pi Pico

Большинство микроконтроллерных проектов живут в рамках готовых протоколов: UART, SPI, I²C, CAN. Это удобно — до тех пор, пока требования проекта не выходят за их ограничения.

Raspberry Pi Pico (RP2040 / Pico 2) интересен тем, что позволяет создавать собственные протоколы связи на уровне железа, не прибегая к FPGA. Ключевые инструменты здесь — PIO и DMA.

Разберём, как выглядит архитектура кастомного протокола, какие задачи берёт на себя PIO, а какие — DMA, и почему Pico в этом плане уникален.


Почему стандартных протоколов бывает недостаточно

Типичные причины:

  • нестандартный тайминг;
  • асимметричные скорости TX/RX;
  • специфическая кодировка (Manchester, PWM, NRZ, bi-phase);
  • необычная длина пакетов;
  • жёсткие требования к джиттеру;
  • «грязная» физическая среда (длинные линии, помехи).

В таких случаях разработчики обычно:

  • городят сложную логику на CPU;
  • используют CPLD/FPGA;
  • или жертвуют надёжностью.

PIO предлагает четвёртый путь.


Что такое PIO в контексте протоколов

PIO — это:

  • отдельная мини-машина состояний;
  • собственный набор инструкций;
  • независимый тактовый домен;
  • FIFO для обмена с CPU/DMA.

Важный момент:
PIO работает детерминированно, в отличие от CPU с прерываниями.

Что PIO делает идеально:

  • формирует точные временные диаграммы;
  • синхронизируется по входным фронтам;
  • реализует битовые кодировки;
  • отслеживает старт/стоп условия.

Роль DMA в протоколе

DMA превращает PIO из «умного GPIO» в полноценный коммуникационный блок.

Связка выглядит так:

CPU → DMA → PIO TX FIFO → линия → PIO RX FIFO → DMA → RAM

CPU:

  • формирует пакеты;
  • анализирует полученные данные;
  • занимается логикой протокола.

PIO:

  • кодирует / декодирует биты;
  • обеспечивает тайминги;
  • работает в реальном времени.

DMA:

  • переносит данные без участия CPU;
  • гарантирует непрерывность потока.

Архитектура собственного протокола

Рассмотрим абстрактный, но реалистичный пример:
однопроводный half-duplex протокол с нестандартным таймингом.

Структура пакета

[PREAMBLE][SYNC][LEN][DATA...][CRC]

Передача (TX): как это выглядит

Задачи PIO:

  • выставлять уровень линии;
  • выдерживать длительности импульсов;
  • сериализовать данные.

Пример концептуального PIO-кода (упрощённо):

.pull block        ; ждём байт из FIFO
.out x, 8          ; загружаем байт
set y, 7
bitloop:
    out pins, 1    ; выводим бит
    nop [T_HIGH]
    nop [T_LOW]
    jmp y-- bitloop

PIO не знает, что передаёт — только как.


Приём (RX): зеркальная логика

Задачи PIO:

  • ловить фронты;
  • измерять длительность импульсов;
  • восстанавливать биты;
  • складывать байты в FIFO.
wait 0 pin 0
wait 1 pin 0
set y, 7
bitloop:
    in pins, 1
    jmp y-- bitloop
.push block

Важно:
PIO можно синхронизировать по внешнему сигналу, а не по внутреннему таймеру — это делает приём устойчивым к джиттеру.


DMA: непрерывный поток данных

Передача

  • DMA читает буфер пакета из RAM;
  • пишет в TX FIFO PIO;
  • CPU свободен.

Приём

  • DMA читает RX FIFO;
  • пишет в кольцевой буфер;
  • CPU обрабатывает данные пакетами.

Ключевая идея:

PIO не блокируется ожиданием CPU.


Ring buffer и потоковый режим

Для реальных протоколов почти всегда нужен кольцевой буфер:

DMA → RAM[ring buffer] → CPU

Преимущества:

  • нет потерь данных;
  • можно обрабатывать пакеты асинхронно;
  • легко масштабировать скорость.

DMA можно настроить:

  • на циклический режим;
  • с прерыванием по половине буфера;
  • с двойной буферизацией (ping-pong).

Тайминги и скорость

Реальные возможности (RP2040):

  • тактирование PIO: до десятков МГц;
  • скорость линий: 1–10 Мбит/с (реалистично);
  • джиттер: ≈ 0;
  • CPU load: минимальный.

Ограничения:

  • 32 инструкции PIO на state machine;
  • простая арифметика;
  • нет сложной логики — она на CPU.

Где такой подход реально оправдан

Промышленные протоколы

  • DMX512
  • DShot
  • нестандартные RS-485 форматы

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

  • адресные LED
  • серво-протоколы
  • собственные шины управления

Связь между микроконтроллерами

  • быстрые point-to-point каналы
  • синхронные линии
  • дешёвая альтернатива FPGA

Где PIO — плохой выбор

— сложная криптография
— протоколы с плавающей структурой
— большие таблицы состояний
— динамическое ветвление

PIO — это детерминированный автомат, а не CPU.


Итог

Raspberry Pi Pico позволяет делать то, что раньше требовало FPGA:

  • реализовать собственный протокол;
  • обеспечить жёсткие тайминги;
  • полностью разгрузить CPU;
  • получить надёжный, воспроизводимый канал связи.

PIO + DMA — это аппаратный коммуникационный движок, замаскированный под микроконтроллер.

Именно в таких задачах Pico перестаёт быть «хоббийной платой» и становится серьёзным инженерным инструментом.