256 - аппаратный, но скорость большая, надо большой буфер, в несколько Кб, чтобы пользовательская программа раз в тик могла без потерь получить все принятое.
Тест (нашел какой-то прототип и доработал):
//const int MAXDATASIZE = 512;
const int MAXDATASIZE = 16*2*2*2*2;
Выложил https://cloud.mail.ru/public/oQpa/19Wx4jKmK
Тест посл.канала сделан на основе теста SPI в linux-custom/tools/spi, поэтому запуск как для теста SPI, через скрипт ts1.
Пример:
#
# ./ts1
Я экспериментировал с драйвером, стало хуже - 19 байт только правильных идет, максимум было 128. Здесь - послано 256, принято 19, они выведены. Отправляется счетчик 0...127,
поскольку было подозрение, что спецсимволы обрабатываются, но потом сделал raw.
Далее сравнение - что д.б. и что в массиве, смысла в этом нет, но сначала заложил, потом не стал менять.
Спасибо, завтра попробую, но чисто навскидку - у вас блокирующий режим, соответственно read ждет заданное кол-во байт или вылетает по таймауту. Так понятно, что будет работать. Требуется же неблокирующий, чтобы остальные процессы не тормозились. В этом случае включен O_NONBLOCK и имитируется требуемый режим работы за счет:
- передали пакет
- пауза больше времени передачи пакета
- read
Вариант неблокирующего но с частым обращением к read, чаще, чем заполнится FIFO - тоже не годится, линукс не обеспечит требуемое для этого реальное время, да и опять же неоптимально по временным затратам.
Единственный вариант - драйвер должен либо иметь очень большой буфер DMA, либо циклический буфер DMA, а этого и нет, хотя в dtsi и указаны каналы DMA для UART2.
не понимаю честно говоря что вам надо - вы говорите противоположные вещи. Блокирующее чтение делают для того чтобы не вызывать его по нескокльо раз и никакие процессы не тормозятся, блокируется (засыпает) процесс который вызывает блокирущий ioctl до тех пор пока там не будет данных, пока он спит выполняются другие процессы, т.е. происходит решедулинг. Я поменял вызов на неблокирующий и ничего ожидаемо не измеилось потому что суть тут в другом
после передачи tcdrain гарантирует что все данные переданы и при любом чтении read прочитает переданный буфер целиком
Процессы я имею в виду в этой же программе, она должна продолжать работу по другим задачам, а не висеть на ожидании завершения передачи и приема. Если разнести процессы по разным программам, то да, это решение сработает, но процессы тесно взаимодействуют, не пройдет. Теоретически возможно использовать thread, в одну вынеся этот обмен, но это усложнит/утяжелит программу, а хотелось бы иметь простой функционал, простую, понятную и надежную программу. thread сильно зависят от реализации, на Яве сталкивался с тем, что один поток идет на одно ядро процессора и при превышении их кол-ва программа практически останавливается. "Сложно" сделать просто, сложно сделать "просто":)
вот мне интересно - как вы себе это представляете при одностороннем обемене, если вы в произвольный момент вызываете чтение - откуда вы можете знать что весь пакет уже передан а не передаётся или ещё может даже не начинал передаваться?
В osless системах делаю кольцевой DMA буфер, каждый тик своей работы, обычно 10мс, программа забирает по его указателям принятое и обрабатывает. Передача тоже через DMA. Никаких накладных расходов в программе, все аппаратно.