Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: STM32 и USB (практика)

Вс апр 04, 2021 19:58:38

И второй вопрос: как я понял, размер пакета для нулевой EP ограничен снизу, для FS USB 2.0 у меня меньше 16 байтов не работает. Действительно ли есть такое ограничение, или где-то в коде ошибка?
Нет. Только что проверил на 8-битной точке, все работает.
Так вот такой вопрос: как лучше (как принято): принимать указатель на функцию или std::function?
Не думаю, что вам это поможет, но в моем варианте за разбиение данных по размеру endpoint'a (кроме ep0) отвечает юзерский код, вызываемый по колбэку endpoint_IN. Но у меня Си, не С++.

Re: STM32 и USB (практика)

Вс апр 04, 2021 20:07:58

COKPOWEHEU писал(а):Только что проверил на 8-битной точке, все работает.

Эх, а я уж понадеялся, что все нормально. А на какой ОС, можете сказать? Просто вроде проскакивало здесь, что тот же Linux более лояльный (у меня самая свежая Win10).

COKPOWEHEU писал(а): за разбиение данных по размеру endpoint'a (кроме ep0) отвечает юзерский код

Выбирал, как сделать, решил попробовать освободить юзера от необходимости разбивать самостоятельно. Но, возможно, тоже приду к тому, что это сам пользователь должен делать, если окажется слишком накладно.

Re: STM32 и USB (практика)

Вс апр 04, 2021 21:09:02

А что именно вы хотите настолько эффективно посылать? В том смысле что в USB весь обмен хост-центрчен, то есть он дает устройству команду "мне нужно столько-то байт", устройство посылает и спит до следующей команды. То есть информация о завершении ему просто не нужна.
Есть, конечно, исключение с Interrupt-точками, но там посылки обычно мелкие и в буфер влезают запросто.
Или зайдем с другой стороны - MSD, где надо сначала огромный кусок данных послать, а потом еще специальный пакет-подтверждение. Это для простого буфера (или что там у вас) наоборот неподъемная задача. Откуда ему знать что после передачи основного буфера надо еще дополнительный передать? То есть даже так юзеру останется немало работы.
Эх, а я уж понадеялся, что все нормально. А на какой ОС, можете сказать?
Linux, WinXP, win10.
Но в документации прямо сказано что ep0 может быть 8, 16, 32 и 64 байта. А для низкоскоростных только 8 байт, без вариантов.

Re: STM32 и USB (практика)

Вс апр 04, 2021 21:17:15

Выбирал, как сделать, решил попробовать освободить юзера от необходимости разбивать самостоятельно.
Имеет смысл сделать очередь отправки в ep0. Для остальных точек на откуп пользователя буферизация, так как даже в пределах одного класса задачи могут быть совсем разные и требуют творческого подхода.

Re: STM32 и USB (практика)

Вс апр 04, 2021 21:23:42

COKPOWEHEU писал(а):Но в документации прямо сказано что ep0 может быть 8, 16, 32 и 64 байта.
Понял, спасибо. Пойду искать ошибку.

VladislavS писал(а):Имеет смысл сделать очередь отправки в ep0
А я думал наоборот. Задача Ep0 - это нумерация (пока по крайней мере) и там очередная отправка только после приема, очередь не стал делать.

Re: STM32 и USB (практика)

Вс апр 04, 2021 21:47:42

Очередь это разбиение одного пакета на кусочки по размеру точки. Отправлять байты по своему желанию через нее нельзя, только в ответ на запросы. Ну а очередь на передачу одного пакета и у меня реализована. Даже банальный DeviceDescriptor занимает больше 8 байт, а другие могут и в 64 байта не поместиться.

Re: STM32 и USB (практика)

Вс апр 04, 2021 21:49:42

COKPOWEHEU писал(а):Очередь это разбиение одного пакета на кусочки по размеру точки.
Я подумал, VladislavS имеет ввиду еще более высокую очередь.

Re: STM32 и USB (практика)

Вс апр 04, 2021 22:20:53

В случае USB очередь из нескольких пакетов оправдана разве что для Interrupt-точек. Ну не знаю, чтобы прикинуться клавиатурой и послать последовательность символов.

Re: STM32 и USB (практика)

Вс апр 04, 2021 22:25:31

COKPOWEHEU писал(а):В случае USB очередь из нескольких пакетов оправдана разве что для Interrupt-точек.
Но я и в этом случае соглашусь с вашим прошлым сообщением - пусть пользователь сам отправляет, как надо, и в этом случае как раз callback на успешную передачу будет полезен.

Re: STM32 и USB (практика)

Пн апр 05, 2021 22:19:56

Нашел проблему, очень интересно для меня все оказалось.
Тыкание пальца в небо показало, что если установку адреса перенести из лямбды в обработчик CTR_TX, то все начинает работать правильно. Практически уверен, что словил следующую ситуацию: после первых 8 (или 16, отладку процесса нумерации так и не осилил) хост кинул второй сброс (что написано в "USB in a NutShell", надо быть все-таки более внимательным), но поле класса, обозначающее оставшееся количество байтов для передачи не обнулилось. Далее пришел SetAddress, на что я кинул ZLP, но и там остаток не обнулил, поэтому в обработке успешной передачи ZLP девайс отправил хосту оставшиеся 2 байта от дескриптора устройства, хост сошел с ума, дважды попытался завершить нумерацию, ничего не получилось, выдал ошибку. Сейчас в отправке ZLP обнуляю счетчик остатка и все нормально.
Спасибо за помощь.

Re: STM32 и USB (практика)

Вт апр 06, 2021 03:31:33

Что-то вы всё усложняете. Там же тупой автомат "Запрос -> Ответ". По reset всё сбросить.

Размер очереди отправки задаётся только в момент формирования ответа или обнуляется по reset. Если ответ это ZLP, то и очередь автоматом обнулится. При штатном прохождении энумерации не должно быть ситуаций когда хост даёт новый запрос не дочитав ответ на старый. Но автомат должен быть к этому готов. При формировании каждого нового ответа очередь инициализируется заново. Досылать ничего от прошлого ответа уже не надо. Хотя, повторюсь, при правильном обмене такой ситуации не должно возникать.

Проверьте, что вы правильно обрабатываете следующие моменты:
1. По ресет надо сбрасывать все регистры usb-контроллера в состояние как до энумерации. Все ваши программные очереди и статусы тоже.
2. При ответе на SetAddress надо сначала отправить ZLP и только после его ухода записать полученный адрес в регистр. Я недавно открыл для себя, что самое оптимальное по коду это при каждом CTR_TX в ep0 писать в регистр адрес. Для контроллеров с OTG с этим можно не заморачиваться, у них можно устанавливать адрес сразу.
3. При запросе дескрипторов хост пишет сколько он хочет получить в ответ. Если дескриптор больше, чем просит хост, то отправить надо столько сколько попросили. Не надо пихать весь дискриптор в этом случае. Хост по заголовку увидит реальный размер дескриптора и переспросит больше, если захочет. В обратной же ситуации, когда просят больше чем есть, надо отправлять реальный размер.
4. Если размер дескриптора кратен размеру конечной точки, то в конце надо ZLP дослать. Похоже, автомат хоста не доверяет длине, написанной в поле дескриптора, а за конец ответа принимает ситуацию когда пакет меньше размера конечной точки. И только после этого начинает проверку и разбор дескриптора.

Если учесть вышеперечисленные особенности, то нештатных обрывов или недосылов не будет.

Насчёт отладки процесса энумерации - посмотрите мой проект. Там в RTT всё что может быть полезно валится. RTT вообще стоит освоить и в каждом проекте в Debug ветке использовать.

Re: STM32 и USB (практика)

Вт апр 06, 2021 07:07:44

3. При запросе дескрипторов хост пишет сколько он хочет получить в ответ.
Обычно сначала запршивает 8 байт
4. Если размер дескриптора кратен размеру конечной точки, то в конце надо ZLP дослать. Похоже, автомат хоста не доверяет длине, написанной в поле дескриптора, а за конец ответа принимает ситуацию когда пакет меньше размера конечной точки.
Дело не в хосте, а в устройстве. Оно может послать данных меньше, чем хочет передать хост. А неоконченный пакет как раз и является признаком конца передачи. Даже если пакет обрывается не успев начаться.
И никто не отменял криворуких разработчиков железа (вроде меня, azhel12 или китайских бракоделов - не путать с нормальными разработчиками). Они вполне могут послать и слишком длинный ответ, и внутренне противоречивый, который невозможно корректно распарсить. И хост должен попытаться. Или хотя бы не сойти с ума.

Re: STM32 и USB (практика)

Вт апр 06, 2021 09:09:42

Обычно сначала запршивает 8 байТ
Вот даже думать об этом не хочу. Сколько хостов - столько реализаций. Хоть один пусть спрашивает.

Добавлено after 58 minutes 27 seconds:
Насчёт 8 байт. Это вы моему ноуту расскажите. Лог обмена под спойлером.

Re: STM32 и USB (практика)

Вт апр 06, 2021 11:03:35

VladislavS, я же сказал "обычно" а не "всегда". Закладываться на подобное и опасно и бесполезно: логику обработки это ни разу не упростит.
Лог обмена под спойлером.
Лучше бы лог wireshark'а приложили, чем своей железки, который надо еще как-то расшифровывать. Мне это делать лень, так что поверю вам на слово.

Re: STM32 и USB (практика)

Вт апр 06, 2021 11:52:31

Закладываться на подобное и опасно и бесполезно: логику обработки это ни разу не упростит.
В том же сообщении я написал, что ХОТЬ ОДИН пусть спрашивает. Вам лишь бы поспорить?

Re: STM32 и USB (практика)

Вт апр 06, 2021 12:46:29

VladislavS, я смотрю важнее всего найти повод поспорить именно для вас!
Ну вот вроде бы ни слова возражения не сказал - нет, VladislavS считает своим долгом начать срач!

Re: STM32 и USB (практика)

Вт апр 06, 2021 14:15:48

Просто не будьте столь категоричны в суждениях.

Re: STM32 и USB (практика)

Вт апр 06, 2021 14:43:32

Будьте добры расшифровать что вы хотели сказать этими цитатами. Во избежание очередного недопонимания.

Re: STM32 и USB (практика)

Вт апр 06, 2021 15:05:52

см. выше: библиотека это скомпилированный файл.
То-то и оно, что в заголовочниках исполняемый код не пишут.

Это общеизвестный факт, не знаю зачем его цитировать.
Вот именно об этом я и говорил. Категоричное ОБЩЕИЗВЕСТНЫЙ ФАКТ ничего общего не имеющее с действительностью. Все ошибаются, про 8 байт в ep0 вы же поправились. А вот тут не хочу на третий круг заходить.

Ну да, обычно если размер заранее неизвестен запрашивается сначала 8 байт или минимальный размер дескриптора.
Откуда вы это взяли? Вы готовы доказать, что 50% + 1 хостов так делают? Иначе категоричное ОБЫЧНО выглядит совершенно необоснованным.

Re: STM32 и USB (практика)

Вт апр 06, 2021 15:24:29

Я бы в своей реализации хоста в случае неизвестного размера дескриптора просил бы выслать 256 байт ☺
А уж на компе так вообще можно килобайтный буфер выделить и сразу килобайт просить — чего уж там!
Ответить