Перейти к содержанию

FIFO (буфер «первым пришёл — первым ушёл»)

Периферия микроконтроллера и программа работают в разном темпе: UART принимает байт, когда он приходит, а программа читает, когда освободится. Между ними ставят FIFO — небольшую очередь, которая копит данные и выдаёт их в том же порядке.

Обновлено Редакция GAW

FIFO (first in, first out — «первым пришёл, первым ушёл») — аппаратная очередь фиксированной глубины. Данные выходят из неё в том порядке, в каком вошли. В микроконтроллерах FIFO ставят между периферией и процессором, чтобы они не ждали друг друга.

FIFO в разных микроконтроллерах

ГдеШирина × глубина
UART RP2040, передача8 бит × 32
UART RP2040, приём12 бит × 32 — байт и 4 бита ошибок
Автомат PIO RP20404 слова в каждую сторону или 8 в одну
Межъядерный FIFO SIO RP204032 бита × 8 в каждую сторону
Приёмник USART ATmega328P2 уровня

Как с ним работают

  • По порогу. Прерывание приходит, когда FIFO заполнен до заданного уровня, и программа забирает данные пачкой; у UART RP2040 тот же порог управляет сигналом RTS. Как устроены прерывания, объясняет термин «Прерывание».
  • Через DMA. FIFO запрашивает DMA, когда появились данные или место, и передача идёт без участия процессора — так работают FIFO автоматов PIO.
  • Без FIFO. У UART RP2040 очередь можно отключить, и она станет однобайтовым регистром — тогда каждый символ надо забирать сразу.

Тонкости

Чтение из FIFO меняет его состояние, поэтому Microchip запрещает применять к приёмному регистру USART ATmega328P команды чтения-модификации-записи SBI и CBI. При выключении приёмника FIFO очищается, и непрочитанные данные теряются. Как устроен сам последовательный порт, рассказывает статья об интерфейсе UART.

Частые вопросы

Что значит глубина FIFO?

Сколько элементов очередь вмещает, пока программа их не заберёт. У UART RP2040 — 32 символа в каждую сторону, у приёмника USART ATmega328P — всего два. Чем глубже FIFO, тем дольше программа может не отвлекаться на периферию без потери данных.

Зачем FIFO, если есть прерывания?

Прерывание на каждый байт отнимает время и может опоздать. FIFO копит данные, а прерывание по порогу — например, когда очередь заполнена наполовину, — позволяет забирать их пачкой. RP2040 задаёт такие пороги регистром UARTIFLS.

Как FIFO работает с DMA?

FIFO выдаёт контроллеру DMA запрос, когда в нём появились данные или освободилось место. DMA сам перекладывает данные между FIFO и памятью, и программа может настроить передачу на килобайты без своего участия — так в RP2040 работают FIFO автоматов PIO.

Источники

  1. Raspberry Pi. RP2040 Datasheet (build 2025-02-20, 3184e62) — разд. 4.2.2.4–4.2.2.5: FIFO передачи UART — 8 бит × 32 ячейки, приёма — 12 бит × 32 (данные и биты ошибок), обе можно отключить, и они станут однобайтовым регистром; пороги прерываний и сигнала RTS задаёт регистр UARTIFLS; разд. 3.2.3.5: у каждого автомата PIO по FIFO на 4 слова в каждую сторону, при передаче в одну сторону их объединяют в 8 слов; FIFO выдают запросы DREQ для DMA; разд. 2.3.1.4: межъядерные FIFO SIO — 32 бита × 8 слов в каждую сторону
  2. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet Complete (DS40002061B) — приёмный буфер USART — двухуровневый FIFO, меняющий состояние при каждом обращении, поэтому к нему нельзя применять команды чтения-модификации-записи SBI и CBI; при выключении приёмника FIFO очищается и непрочитанные данные теряются

Нашли ошибку?