Что надо:
Надо из юзерспейса читать посылки и обрабатывать их.
Что накодил:
Использую /dev/ttymxc1 , termios.h , fcntl.h
Получение дескриптора:
Настройки, которые задаёт программа через termios:
В чём проблема:
Данные впервые поступают в read только после накопления 4096 Б, и далее вновь по мере накопления 4096 Б. То есть они валятся огромным массивом примерно раз в 500мс, что неприемлемо. Причём считывание идёт как 4095 + 1.
Для сравнения, на компьютере (тоже дебиан) в такой же код при передаче данных через usb-rs-232 адаптер (ICPcon i-7561) данные залетают в read по 10-40 байт.
Что надо:
Получать и обрабатывать данные по мере поступления. Пусть склеенными даже по 5-10 пакетов, но не по 400...
Что пробовал:
Пробовал играть с параметрами VMIN и VTIME, делая их ненулевыми в разных сочетаниях. Эффекта никакого.
Переписал с использованием встроенного в Qt QSerialPort - результат тот же: данные приходят в read по 4096 байт.
Вытянул репозиторий по предложенной Вами ссылке, скомпилил test_rx, предварительно дополнив перечень портами /tev/ttymx*. Результат вновь тот же: данные приходят слепленными в 4096 байт (4095+1).
Проблема не в том, что я не могу их разлепить. Могу. Проблема в том, что количество байт, доступных для чтения (если раз в 2 мс долбить метод read или poll), на плате imx6 меняется как 0-0-0-...-0-0-0-4096-0-0-0-...-0-0-0-4096-0-0-0-...
Абсолютно тот же самый пример из этой библиотеки на компьютере даёт примерно 20-20-30-20-30-20-40-20-30-20... Числа написаны условно. Главное то, что на компьютере данные выдаются в юзерспейс по мере поступления, а на плате - когда весь входной буфер забьётся.
АБСОЛЮТНО ОДИНАКОВЫЙ КОД на компьютере работает правильно, а на плате - нет. На компьютере данные обрабатываются сразу, как устройство начинает их слать. На плате первые данные появляются через полсекунды и далее раз в полсекунды.
результат - прием по 100 байт максимум за один раз
а может наоборот ? Вам просто надо понять что это не микроконтроллер и не РТОС - нет никакой гарантии в юзерспейс что задержка 2 мс - гарантируется только то что она минимум 2 мс, а может быть и секунду, невозможно сказать сколько байт в буфере после такой задержки.
Если откинуть в сторону Windows - в Linux есть системные вызовы poll/select - с ними не надо никаких задержек делать, выполнение текущей задачи можно приостанвить до появления данных в буфере порта, в данном примере циклические задержки нужны для совместимости с Windows. Для одного порта можно вообще блокирущее чтение использовать без всяких задержек - текущая задача уснет пока нет данных. Эта библиотека просто как пример.
Может, я непонятно объясняю. Ещё раз. Устройство шлёт данные непрерывно пакетами по 10 байт, межпакетного интервала нет. Прикладываю код и лог.
Модифицированный пример:
Фрагмент лога на компьютере (Debian 8.7):
Фрагмент лога на плате (Debian 9.3):
Как видно из логов, на компьютере метод Poll каждый раз считывает некоторое небольшое количество байт, находящихся сейчас во входном буфере. На плате метод Poll возвращает нули до тех пор, пока буфер не заполнится целиком, после чего возвращает весь буфер целиком. То, по сколько байт я хочу считывать, не имеет значения. Посмотрите на временные отметки. Все 4096Б становятся доступны одновременно. Между выдачей данных стабильное время, равное времени полного заполнения буфера. Поскольку поток не блокируемый, я не понимаю, какого лешего так происходит. Я понимаю, что это не реалтайм операционка, но камооон, 10 кБ / сек невозможно обрабатывать чаще одного раза в 900 мс?..
На этой же самой плате работает другая программа, которая с другого устройства совершенно аналогичным кодом принимает данные. Только вот то устройство делает межпакетные интервалы, поэтому метод read возвращает сразу длину всего пакета.
Такое ощущение, что реализация tty в дебиане на плате отчаянно пытается дождаться конца посылки данных (нет межпакетного интервала - нет конца), не может его дождаться, и потому вынужденно отдаёт данные после заполнения буфера.
это понятно - непонятно с чего вы решили что система обязана в таком случае принимать их кусками размером какой вам нужен - какая разница, 4096 байт вы будете потом парсить или 80 ?
отключите DMA у порта и будет вам "как на компьютере"