Почему в UART RX FIFO предусмотрены прерывания FIFO на одну четверть, на половину, на три четверти? Каковы их варианты использования?
Я реализую декодер протокола, который получает байты через UART микроконтроллера. ISR берет байты от периферийного устройства UART и помещает его в кольцевой буфер. Основной цикл читает из кольцевого буфера и запускает конечный автомат для его декодирования.
UART внутренне имеет 32-байтовый приемный FIFO и обеспечивает прерывания, когда этот FIFO заполнен на четверть, наполовину, на три четверти и полностью. Как мне определить, какое из этих прерываний должно активировать мой ISR? В чем заключается компромисс?
Примечание. Протокол включает 32-байтовые пакеты (фиксированной длины), отправляемые каждые 10 мс.
2 ответа
Это зависит от многих вещей, в первую очередь от максимальной поддерживаемой скорости передачи данных и от того, сколько времени требуется приложению для выполнения других задач.
Традиционные кольцевые буферы работают на основе байтовых прерываний. Но, конечно, всегда приятно уменьшать количество прерываний. Вероятно, не имеет большого значения, как часто вы позволяете этому срабатывать.
Гораздо важнее реализовать схему двойного буфера. Конечно, вы не должны запускать декодирование конечного автомата прямо из единственного кольцевого буфера. Это превратится в кошмарное состояние гонки.
Ваша основная программа должна включить семафор / отключить прерывание UART, затем скопировать весь буфер и разрешить прерывание. В идеале буферное копирование выполняется путем изменения указателя, а не распечатки. Код, выполняющий это, должен быть протестирован, чтобы он работал быстрее 1/ бод * 10 секунд. Где 10: 1 начало, 8 данных, 1 остановка, при условии, что UART равен 8-N-1.
Если доступно, используйте DMA поверх программных кольцевых буферов.
Учитывая протокол на основе пакетов и UART, который прерывается, когда получено более одного байта, подумайте, что произойдет, если будет получен последний байт пакета, но этого последнего байта недостаточно, чтобы заполнить FIFO за порогом и запустить прерывание. Ваше приложение просто не собирается получать этот неполный пакет, пока какой-нибудь последующий пакет не будет получен и FIFO наконец не заполнится достаточно? Что, если другой конец ожидает ответа и никогда не отправляет другой пакет? Или ваше приложение должно опрашивать UART для проверки оставшихся байтов, оставшихся в UART FIFO? Это кажется слишком сложным, чтобы использовать как прерывание, так и опрос полученных байтов.
С реализованными мною пакетными протоколами драйвер UART не полагается на UIF FIFO и настраивает UART на прерывание, когда доступен один байт. Таким образом, драйвер получает уведомление для каждого байта, и нет никакого шанса, что последний байт пакета останется в FIFO UART.
FIFO UART может быть удобен для потоковых протоколов (таких как аудио или видео данные). Когда драйвер получает поток данных, всегда будут входящие данные, чтобы продолжать заполнять FIFO. Драйвер может полагаться на FIFO UART для буферизации некоторых данных. Драйвер может быть более эффективным, обрабатывая несколько байтов на прерывание и уменьшая частоту прерываний.
Вы можете рассмотреть возможность использования UART FIFO, поскольку ваши пакеты имеют фиксированную длину. Но подумайте, как драйвер восстановится, если один байт будет сброшен из-за шума или чего-то еще. Я думаю, что все же лучше не полагаться на FIFO для пакетных протоколов, независимо от того, являются ли пакеты фиксированной длины.