Pull to refresh

Comments 21

Интересная у Вас работа :) А когда рефлектограмма приходила не полностью, как поняли? Файл не открывался, артефакты?
Поняли мы это по странному поведению цепочки утилит, которая обрабатывала данные на выходе с программы usbgather. Они-то рассчитывали на железобетонно целую рефлектограмму. Эхх, знали бы мы тогда как мы ошибались :)
да, USB не гарантирует доставку
Это, вообще говоря, неверно. Так же как и в IP (работающем поверх какого-то физического протокола, например Ethernet) тут есть варианты, например: TCP и UDP. Так вот, в USB и физический уровень и уровень протокола стандартизирован и есть их там (по большому счёту) два:
а) bulk (почти оно же control и interrupt) — с гарантированной доставкой, но негарантированной задержкой и полосой
б) isochronous — с гарантированной полосой и задержкой, но негарантированной доставкой

По тексту у Вас вроде USB bulk. Поэтому ошибка где угодно, но только не в USB. Может быть в передатчике, может быть в приёмнике. Я имею ввиду программно-аппаратную часть которая буферирует/отправляет/принимает данные. Но вероятность, что данные теряются именно при передаче по USB исчезающе мала (там есть и блочный CRC и контроль чётности слов). Иначе флешками было бы невозможно пользоваться (а там протокол — навес над USB bulk).
Так вроде бы автор написал, что причина не в протоколе, а в кривой реализации CDC-EEM в NutOS.
Так я вроде и не против. Я ж написал, что при поиске ошибки полагать, что usb bulk теряет пакеты методолгически неверно. Собственно только этот пассаж я прокомментировал и уточнил.
Ну, в реализации CDC-ACM, видимо, тоже не боги пакеты по горшкам раскладывают, если накосячили в EEM, кто мешает сделать аналогичный баг в ACM. (И вообще мне кажется это один и тот-же баг...)
Т.е. если CRC не совпала, пакет надо-бы перепослать, но кто такой стандарт чтобы указывать что нам делать?

urx, похоже что ваша STM не проверяет пришло ли ACK для текущего пакета, и тупо шлет следующий, в то время как хост думает, что она честно перепосылает предидущий.

А фразы типа «Соответственно мы из следующего пакета вычитываем N потерянных байт, а следующие данные воспринимаем как начало нового EEM-пакета и интерпретируем первые 2 байта как заголовок.» заставляют шевелиться волосы на голове.
Ладно потеряли пакет из середины, а что контрольную сумму итогового TCP пакета никто не проверял??

И кто-бы вы думали виноват???
и USB я стал любить чуть меньше, чем раньше.
по пунктам:
ACM работало как надо. Просто при приеме кривого пакета мы в силу кривизны алгоритма убегали за пределы памяти.

Насколько я помню — OTG корка генерит нам прерывание о возможности выгребать пакет из FIFO когда уже все ACK пришли.

работа с ЕЕМ заголовком происходит на том уровне, когда никакого ТСР еще нет.

И кто бы вы думали искал тут виноватых? Пост вообще-то не о том как какие-то нехорошие люди сделали плохой алгоритм, а мы его героически исправили. Даже наоборот — в силу сложившихся обстоятельств мы наступили на самолично написанные ранее грабли и узнали немного нового.
Не пойму:
ACM работало как надо. Просто при приеме кривого пакета мы в силу кривизны алгоритма убегали за пределы памяти.

дык не должно быть никаких кривых пакетов, если алгоритм реализован правильно.

Насколько я помню — OTG корка генерит нам прерывание о возможности выгребать пакет из FIFO когда уже все ACK пришли.

Это на стороне прибора насколько я понимаю, я-же говорю что похоже что модуль, не проверяет ушел ли пакет правильно.

мы наступили на самолично написанные ранее грабли и узнали немного нового

А… Так EEM-код в модуле тоже ваш… Недопонял :)

Так чем-же тогда USB провинился? :)
АСМ и ЕЕМ работают параллельно. И все жило до тех пор, пока в ЕЕМ не терялась часть данных и не происходило кривой интерпретации заголовка.

ОТГ — в модуле. А со стороны прибора там ОТГ, потом хаб, потом уже ОТГ модуля.

USB — лично для меня — сложность отладки.
Наверное я выложил недостаточно предистории. Сейчас попробую исправить это тут.

Изначально у нас связь прибора с модулем была реализована так:



И все работало нормально. Но потом купить такой USB хаб стало невозможно, и мы заменили его на CY7C65642. Тут и начались проблемы. При этом если карта работала напрямую с USB хостом — данные не терялись. Мы начали дебажить и заметили что в какой-то момент урбы от хоста на модуль не уходят. Читали разные доки по USB и в одной наткнулись на такую фразу:

4.3.1.3.6.1 Transmission Errors
For errors in this category, USB defines a policy that allows the transaction to be retried for up to three times before the transfer is failed and returned to the client.

Отсюда и возникло предположение что данные могут не дойти в USB bulk.

Ситуация усугублялась тем, что много приборов уже было поставлено и заменой хаба проблему было не решить. После долгих копаний и отладки был выбран EEM + TCP/IP.

А не рассматривали идею подключения STM32 через модули UART <=> WiFi?
Я пользуюсь — не нарадуюсь. Нужен роутер WiFi, если его нет в учреждении, и по одному модулю на прибор.
Конечно модули денег стоят (от 400 р./шт. на aliexpress), но зато нету возни с USB стэком, максимальная скорость до 3 Мбит с модулями за 1000р. или до 460 кбит с модулями за 400-500р… Также нету возни с проводами (мобильность), ну и работаешь с хостом со стороны МК как с обычным последовательным портом.
Одно врем была идея делать что-то с вафлей, но дальше нее дело не пошло.
Почему, если не секрет? Может и я зря связался с ним?
А я не знаю почему. К сожалению.
потому что в пределах одного дивайса wifi не нужен.
а автономные модули (то есть, без прибора, с интерфейсом на планшете, телефоне, ноутбуке, ...) не хотят покупать. поэтому не делаем.
Хммм… Я смотрю на схему в этом комментарии.

USB Host мне видится как головная ЭВМ. На ней интерфейс? Между USB Host и несколькими узлами STM32 я и подразумевал расшаренную WiFi.
:)
это всё в пределах одного прибора. в нём два модуля, подключаемых по usb к управляющей плате. wifi здесь не совсем к месту.
хехе… я себе представил больничный кабинет несколькими модулями (блоками), от которых тянутся USB кабели к головной машине. Некий такой стимпанк в пластиковом исполнении.
А тут оказывается комплекс внутри единого корпуса.
Не дойти-то они могут. Но клиенту (STM) об этом будет сообщено. И он может продолжать перепосылать недоставленный пакет столько, сколько захочет.
В этом случае, даже если вы выдернете провод (usb), и вставите обратно, ни одного пакета потеряно не будет.
Читаю и волосы дыбом встают…
Я конечно не знаю, что за проблема с USB bulk оказалась у автора и почему теряются данные (как так?)… ведь bulk вообще-то гарантирует целостность данных…
Меня настораживает тенденция крупноблочного мышления разработчиков.
На первом месте у нас, конечно, time-to-market — то есть выдать продукт как можно быстрее.
Есть проблема? Не будем сильно разбираться с корнем проблемы, а попробуем решить в лоб, добавим сверху еще уровней, слоев, протоколов, возьмем какой-нибудь готовый lib, обойдем проблему, авось та первая проблема замаскируется, не будет вылазить.
Технологическая сингулярность — человечество изобретает технологии быстрее, чем осваивает старые. Как работают новые технологии? А никто не знает… Взяли за основу пример «один», добавили библиотек из источника «два» и «три» — вроде бы все работает.
Покрыть тестами? Наверное процента на 2-3 сможем, а дальше? Не известно, мы же точно не знаем как тот стек протоколов внутри устроен… Потом удивляемся, что хакеры дистанционно автомобили останавливают…

Sign up to leave a comment.