Comments 7
Спасибо. Интересно. Лет 5 назад, экспериментировал с USB и STM32, особо в этом не шаря, но удалось реализовать передачу температуры с датчика DS18B20 с МК в приложение на смартфон на Android-е по USB , а с кнопки в приложении, включать/выключать светодиод на плате с STM32. Магия :)
нельзя просто так взять и и поменять VID и PID
Технически, можно всё. Просто если самодеятельствовать, то нельзя лепить шильдик о совместимости с USB (который торговая марка). Но можно как-то намекнуть, что ваше устройство втыкается в порт вот примерно такой формы.
Но проблема в том, что винда будет относиться к неизвестному vid:pid также как и к демо vid:pid.
Более того, есть подозрения, что и большая часть принтеров начинают определяться полноценно только после установки драйвера, который прописывает vid:pid (если принтер реализует стандартный класс, этим можно ограничиться). Просто для настоящих принтеров у MS есть база драйверов с автозагрузкой.
Да, по факту, никто не мешает использовать любую понравившуюся комбинацию vid:pid.
большая часть принтеров начинают определяться полноценно только после установки драйвера, который прописывает vid:pid
Так работает почти всё что подключается к Windows. Честно говоря, я туда пока не погружался - полезу и буду пытаться писать свой драйвер когда заработает печатающая голова (уже в процессе).
У меня сложилось впечатление что Windows смотрит на класс устройства и представляет стандартный драйвер. Однако, если есть специальный драйвер для какой-то комбинации vid:pid, то подхватываться будет он.
можно как-то намекнуть, что ваше устройство втыкается в порт вот примерно такой формы.
Можно написать свой inf файл, в котором указываетсч какой драйвер должен использоваться для конкретного устройства и принципе описывается что это за устройство. Это будет иметь смысл только если комбинация vid:pid действительно уникальна. Уникальность обеспечивается наличием официально зарегистрированных vid:pid и подписей у драйвера и т.е. наличием организации, которая выдаёт vid (какой дали, с таким и живёшь) и через которую, вроде, можно (а может и не нужно) зарегистрировать pid (производитель выбирает сам для своих устройств).
В процессе разработки демо vid:pid более чем достаточно. Меня совершенно никак не коробит использовать левый vid:pid в релизе (вдруг он случится - можно помечтать) и драйвер, на который будет ругаться ОС т.к. это моё устройство и я знаю что это такое и что оно делает. Других пользователей подобное может напугать, да и выглядит не очень профессионально ;)
У меня сложилось впечатление что Windows смотрит на класс устройства и представляет стандартный драйвер.
Даже для стандартного класса как правило нужно чтобы был хотя бы простенький INF файл, который говорит "используй вот этот стандартный драйвер с этим устройством" (INF может ссылаться и на системный драйвер, а не только свой).
Исключение сделано только для очевидных USB Mass Storage и USB HID (чтобы всё многообразие китайских флешек, мышей и клавиатур точно работало без настройки), если ничего не поменялось с тех пор. По этой причине, кстати, много самоделок реализуют USB HID совсем не являясь HID устройствами в привычном смысле этого слова (USB HID Class поддерживает кастомные report, позволяя слать произвольные данные). Тупо чтобы пользователям не нужно было ставить никаких драйверов, а было достаточно user space приложения даже не требующего установки (WinAPI содержит функции для отправки/приёма кастомных USB HID reports). Для задач где не нужно передавать много данных (протокол HID не позволяет передавать слишком много и слишком часто) подходит отлично.
Даже с USB CDC уже надо либо использовать VID:PID, которые винда из коробки ассоциирует с COM-портами (благо, у большинства производителей микроконтроллеров есть те самые демо идентификаторы, вы могли заметить, что обычно их несколько - один для HID, один для CDC, один для MSC и т. д. - как раз потому что у них разные ассоциации в винде), либо написать INF и поставить. Для принтеров - тем более (только производители могут не давать отдельный демо идентификатор для него, потому что более редкий use-case и у производителей принтеров всё равно есть свои VID:PID).
При этом пока вы укладываетесь в функционал стандартного USB Printer Class, вы можете ограничиться только тем самым INF файлом (и даже распространять его, даже если ваш VID:PID не уникален, достаточно чтобы у пользователя не было одновременно вашего устройства и того с которым у вас коллизия). А если, например, ограничиться всеми не стандартизированными функциями в отдельном приложении, то можно сделать composite device реализующий не только принтер, но и HID, чтобы не пришлось писать полноценный драйвер.
Composite device потом ещё попробую. Моё внимание привлёк не столько HID, сколько Image, MSC. Хочется сразу иметь доступ хотябы к логам на SD карте, возможно отдавать задание на печать (что потребует рендера на устройстве, но вполне можно и RAW отправить). Ну а через Image можно сканер попробовать завести.
Ещё, возможно, имеет смысл познакомиться с Download Firmware Update, насколько понял, его можно использовать для обновления прошивки, но надо будет заиметь минимальный бутлодер для запуска и обновления этой самой прошивки (двойной буфер?).
Обычно бутлоадер просто пишется в отдельную область памяти, которая резервируется и основная прошивка не может её занимать. При этом контроллер в том или ином виде позволяет использовать таблицу прерываний из памяти бутлоадера, а не основной прошивки, когда запущен бутлоадер (с помощью изменяемой базы таблицы прерываний или особого маппинга памяти в режиме бутлоадера).
Бутлоадер запускается перед основной прошивкой, проверяет какое-то условие и либо запускается полноценно, либо отдаёт контроль ей.
Условие обычно либо какая-нибудь кнопка (тогда нужно при включении/перезагрузке контроллера одновременно зажать специальную кнопку), либо программный флаг (нужно отдать команду основной прошивке любым удобным образом, она взведёт флаг в памяти и перезагрузит контроллер, а бутлоадер проверит этот флаг пользуясь тем, что при soft-reset память у многих МК не очищается сама собой). Хотя всё равно хорошо бы продублировать кнопкой (на случай если нечаянно будет записана глючная прошивка, которая не может принимать команды).
У STM32 старших моделей (например, линейки STM32F4), кстати, есть встроенный с завода USB MSC бутлоадер активируемый по какой-то комбинации BOOT-пинов (достаточно вывести наружу устройства кнопку сброса и кнопку замыкающую один из BOOT-пинов). У младших моделей типа линейки STM32F1 встроен только UART бутлоадер. Но можно прошить дополнительно свой с поддержкой USB.
У STM32 старших моделей (например, линейки STM32F4), кстати, есть встроенный с завода USB MSC бутлоадер
Не знал, посмотрю как дойдёт дело.
В плане логики работы загрузчика пока в голове три варианта:
Хранить дамп старой и новой прошивки в энергонезависимой памяти снаружи (например, SD карта, EEPROM, внешняя flash) и перешивать область основной прошивки по необходимости (с соблюдением каких-то условий). Так обновление разделится на 2 этапа - загрузка новой прошивки и непосредственно перезапись flash
Иметь двойной буфер во flash для основной прошивки. При глюках новой прошивки будет возможность запустить старую без перепрошивки контроллера лёгким движением руки, но я пока не уверен что мне хватит памяти на такое. Самое главное, так можно сдеать бутлоадер потоком внутри RTOS, а не отдельной программой со своим местом внутри flash
Прошивка так прошивка. Останавливаем основную прошивку и переключаемся на бутлоадер при прошивке. Перешивается область памяти где лежит основная прошивка.
Сейчас я использую Nucleo - у неё есть ST-Link с возможностью подключения как MSC к ПК и на неё можно сбросить новый файл прошивки, который при каких-то условиях загрузится во flash подключённого к ST-Link контроллеру. В принципе, в этом плане можно ничего не менять, разве что объединить 2 USB в один через хаб, но это уже звучить как излишняя заморочка.
Я ещё изучу этот вопрос, для меня это пока не изученная тема.
DIY Open Source принтер. Часть 1. Покоряем USB Printer Class и имитируем печать текста