FIFO (буфер «первым пришёл — первым ушёл»)
Периферия микроконтроллера и программа работают в разном темпе: UART принимает байт, когда он приходит, а программа читает, когда освободится. Между ними ставят FIFO — небольшую очередь, которая копит данные и выдаёт их в том же порядке.
Обновлено Редакция GAW
FIFO (first in, first out — «первым пришёл, первым ушёл») — аппаратная очередь фиксированной глубины. Данные выходят из неё в том порядке, в каком вошли. В микроконтроллерах FIFO ставят между периферией и процессором, чтобы они не ждали друг друга.
FIFO в разных микроконтроллерах
| Где | Ширина × глубина |
|---|---|
| UART RP2040, передача | 8 бит × 32 |
| UART RP2040, приём | 12 бит × 32 — байт и 4 бита ошибок |
| Автомат PIO RP2040 | 4 слова в каждую сторону или 8 в одну |
| Межъядерный FIFO SIO RP2040 | 32 бита × 8 в каждую сторону |
| Приёмник USART ATmega328P | 2 уровня |
Как с ним работают
- По порогу. Прерывание приходит, когда 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.
Источники
- 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 слов в каждую сторону
- Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet Complete (DS40002061B) — приёмный буфер USART — двухуровневый FIFO, меняющий состояние при каждом обращении, поэтому к нему нельзя применять команды чтения-модификации-записи SBI и CBI; при выключении приёмника FIFO очищается и непрочитанные данные теряются
Нашли ошибку?