Какова длина последовательного буфера в Linux?

Мой вопрос касается <termios.h>. Насколько я понимаю, существуют два буфера для чтения чего-либо через UART - аппаратный буфер, в котором хранятся полученные байты, и программный буфер, куда мы загружаем то, что было сохранено в аппаратном буфере. Этот программный буфер - второй аргумент в read(uart_channel, BUFFER, length), насколько я понимаю.

Объясните, пожалуйста: какой длины аппаратный буфер? Могу ли я контролировать его продолжительность? Для меня критически важно прочитать 12 самых последних байтов, отправленных устройством через UART - как я могу в этом убедиться?


person space_voyager    schedule 26.05.2015    source источник
comment
Буфер, который вы предоставляете read(), является буфером вашего приложения, куда будут записаны любые доступные последовательные данные. Это уровень приложения, поэтому, конечно, он не является частью буферизации драйвера. Фактическая аппаратная буферизация (FIFO), конечно, будет зависеть от оборудования, и вы не говорите, что используете. Также есть буфер в ядре, мне не удалось выяснить его размер (и можно ли его изменить).   -  person unwind    schedule 26.05.2015
comment
@unwind Я использую модель Raspberry Pi 1 B +. Нет возможности очистить аппаратный буфер в терминале?   -  person space_voyager    schedule 26.05.2015
comment
Большинство uC, которые я видел, имеют аппаратный FIFO, который можно настроить на прерывание, скажем, через [1,2,4,8,16] байтов. Если вам действительно нужен доступ к байтам как можно скорее, тогда вам нужно установить FIFO 'length' равным 1. Конечно, ваш драйвер должен сделать это при инициализации UART.   -  person Martin James    schedule 26.05.2015


Ответы (2)


Однажды у меня была похожая ситуация, и я создал поток, который продолжал читать UART (блокируя read), и я использовал FIFO между потоками.

Если вы не можете использовать потоки, вы можете просто использовать select.

person Etienne Bagnoud    schedule 26.05.2015
comment
Спасибо за предложение. Чтобы уточнить, я использую модель Raspberry Pi 1 B +. На самом деле у меня есть pthread, который читает uart, но он также выполняет фильтрацию, и поэтому рискует прочитать uart только после того, как он уже был заполнен дополнительными значениями. Я уже использую блокирующее чтение (VTIME = 0, VMIN = 12). Есть ли способ просто очистить аппаратный буфер? - person space_voyager; 26.05.2015
comment
Так сделайте фильтрацию в другом потоке. Можешь попробовать tcflush, должно работать. - person Etienne Bagnoud; 26.05.2015
comment
@space_voyager Я уже использую блокирующее чтение (VTIME = 0, VMIN = 12) - это своеобразный неканонический режим, который часто приводит к проблемам с синхронизацией. Скорее всего, вы задаете вопрос XY. Т.е. вы задаете неправильный вопрос. - person sawdust; 26.05.2015

Большинство uC, которые я видел, имеют аппаратный FIFO, который можно настроить на прерывание, скажем, после [1,2,4,8,16] байтов. Если FIFO остается «частично заполненным» на некоторое количество, кратное символьному интервалу для текущей настроенной скорости передачи данных, UART все равно прерывается. Если вам действительно нужен доступ к байтам как можно скорее, тогда вам нужно установить FIFO 'length' равным 1. Конечно, ваш драйвер должен сделать это при инициализации UART.

В противном случае, я думаю, вы могли бы опросить его :(

person Martin James    schedule 26.05.2015