Потеря данных при чтении через cdc_acm

(1/2) > >>

WWX:
Доброго времени суток.

Есть некое устройство, работающее через USB (на high speed).
При подключении к хосту определяется как "/dev/ttyACMx".
Насколько я понимаю, работает через драйвер "cdc_acm".

Чтение из этого устройства организовано примерно так:
- Вызов "read" с соответствующими параметрами.
- В зависимости от того, сколько байт прочитано за предыдущий вызов "read", перевызываю "read" с соответствующими изменениями параметров.

(За один вызов "read" всегда читается 4095 байт или меньше. (Во всяком случае ни разу не видел, чтобы было 4096 или больше.)

При чтении больших объёмов (до 512 МБ) из этого "виртуального COM-порта" периодически пропадают данные.
Замечено, что перед пропажей "read" возвращает 16 (или более) раз подряд число 4095.
Если перед вызовом "read" поставить задержку, то "read" всегда возвращает 4095 и после примерно 20-го вызова кусок данных теряется (т. е. при наличии задержки воспроизводится почти сразу).

Пропавший кусок всегда кратен 512 Б (что логично, т. к. соответствует размеру bulk endpoint'а на high speed).
Смотрел USB шину аппаратным USB-анализатором. Никаких ошибок на шине нет. Все данные, даже те, которые не добрались до пользовательского приложения, на шине присутствуют и подтверждены (ACK).

Вопрос в том, почему теряются данные?

Могу предположить, что в случае если "read" не успевает выкачивать данные, то происходит переполнение какого-то внутреннего буфера.
Возможно имеет смысл обновить драйвер "cdc_acm", только не очень понятно какой пакет обновлять.

ОС: Centos 7

Вывод "uname -r":
3.10.0-1160.6.1.el7.x86_64

RXL:
Что буфера нерезиновые, это понятно, от того и потери.
Умеет ли устройство управлять потоком? Попробуй включить hardware flow control на tty. Устройства класса ttyACM должны быть подобны модемам.
Кстати, там же буфером можно управлять, может получится большими порциями забирать.

WWX:
Спасибо за ответ.

Цитата

Что буфера нерезиновые, это понятно, от того и потери.
Т. е. потеря данных от полного заполнения буфера считается нормальным? Мне казалось, что в этом случае драйвер должен подождать, пока пользовательская программа заберёт данные и до этого момента не слать плате USB токены IN.

Цитата

Умеет ли устройство управлять потоком? Попробуй включить hardware flow control на tty. Устройства класса ttyACM должны быть подобны модемам.
Какого-то специального "hardware flow control" на устройстве нет, кроме предусмотренного стандартом USB. Физически плата соединена USB шнуром (физического COM-порта нет).
Это USB устройство, реализующее протокол CDC. Грубо говоря, там есть две BULK endpoints: In и Out.
Если хост хочет что-то прочитать, он шлёт токен IN и в ответ получает 512 байт (если устройству есть что передать).

Вопрос состоит в том, почему он (хост) шлёт токен IN тогда, когда его буфер переполнен; а потом ещё и подтверждает приём данных (шлёт токен ACK).

Цитата

Кстати, там же буфером можно управлять, может получится большими порциями забирать.
А как задать размер буфера?
(Понятно, что это не решение, но хотя бы в порядке эксперимента.)
И можно ли как-то программно узнать размер буфера?
(Тогда можно будет просто запрашивать данные меньшими порциями.)

darkelf:
может есть что в логах ядра?
Есть возможность устанавливать общий размер буферов для всей подсистемы USB.
Ещё, как я понимаю, есть альтернативный вариант общения с драйвером, но использовать не приходилось, так-что по конкретике подсказать не смогу.
Ещё вариант - попробовать работать через libusb.

WWX:
В логах (dmesg; /var/log/messages) никаких ошибок нет.
Пробовал в "/sys/module/usbcore/parameters/usbfs_memory_mb" увеличивать размер буфера (с 16 на 1000) - поведение не изменилось.

С остальным надо разбираться. В любом случае спасибо за ссылки — наводки.

Навигация

[0] Главная страница сообщений

[#] Следующая страница