Пока с заглушками,
ковыряюсь. Читаю исходник модуля ядра и не понимаю: функция usb_xfer принимает массив структур i2c_msg. У каждой структуры есть поле адреса, соответственно, подразумевается, что каждая такая посылка должна начинаться со START, потом отправка адреса, а заканчиваться выставлением STOP. По крайней мере, именно так я и реализовывал все функции работы с I2C на STM32. А тут - в начале выставляют START, потом пишут/читают все N сообщений, и лишь затем STOP! Неужели оно так будет работать? Что-то сомневаюсь… Посмотрел исходники "robotfuzz" - там та же бодяга, только, похоже, START выставляют на каждое сообщение, а вот STOP - только в самом конце.
Полезу ка, почитаю мануал на МК: вдруг так правда можно?
Ну, да ладно. Вчера приличную часть времени убил, пытаясь понять, почему тестовая утилитка автора принимает отправляемые мною ответы и не ругается, а модуль ядра сразу нафиг посылает. Полез в исходники. У автора постоянно то VENDOR-запрос, то CLASS. А в модуле ядра все - VENDOR. Похоже, софтовый USB на I2C реализован совсем примитивно. Ну, ОК, пока что я продублировал функции (они и VENDOR, и CLASS). Я, кстати, поначалу для VENDOR не делал поля data, а вона как вышло.
И опять ломал голову, как бы поизящней реализовать тот факт, что если wireshark показывает все красиво в случае OUT-запроса (64 байта стандартного запроса + N<=64 байт данных), то фактически нужно, проанализировав, что дальше будут данные, отправить ZLP (при этом сохранив тело запроса), а уже получив данные, вызывать функцию. Мучился с этим впервые еще когда реализацию CDC на STM32 рисовал. А тут вот решил очередную революцию устроить: в "тело библиотеки" поместить лишь общее (т.е. инициализацию, создание конечных точек и обработку прерывания + базу по EP0), а идентификаторы и прочее вынести в отдельные файлы (как это, в принципе, народ и делает).
Но как эти чертовы OUT SETUP пакеты с данными обрабатывать нормально - вообще не понимаю! Ведь получается, что ты никак заведомо не можешь знать, будет там "хвост" с данными или нет. Если там данных не подразумевается, ответишь ZLP, и дальше ничего может не быть какое-то время, т.е. функцию-обработчик сразу надо вызывать. Если подразумеваются данные - вызывать ее только после их получения. Хоть таймаут ставь, блин! Но это уж совсем идиотизм получается. Так что, пока сделал так: и при получении SETUP, и при получении просто данных я вызываю обработчики (только в первом случае в полях data и datalen нули). А уж сами обработчики пусть думают, что им с этим делать (скажем, если получил OUT, тебе нужны данные, а их нет - просто выходишь; ну или что то же самое - получил SETUP+OUT).
И это я еще нигде не встречал точек INTERRUPT! Кстати, ХЗ, зачем я ее инициализирую - надо будет убрать нафиг.
Эх, вот как бы так красиво и лаконично USB реализовать, чтобы не превратить в подобие убогого калокуба или opencm3?
На работе, кстати, тоже сейчас занимаюсь перепахиванием: добавляю в свою "сниппетобиблиотеку" поддержку сокетов. И, с одной стороны, хочется попроще сделать, а с другой - обеспечить все свои нужды на будущее… Вот, уже три раза базовые функции переписывал. Вчера более-менее закончил с клиентом, нужно еще сервер нарисовать (с опциональным автозапуском потока, анализирующего пришедшие данные и выполняющего обработчики из переданного в него списка). Клиенту, кстати, подобное же надо добавить (например, чтобы вручную не ловить ответы на геттеры, а использовать их в виде сеттеров локальных переменных).
В общем, ближе к выходным еще повожусь с железякой. Основная задумка - попытаться на ее VID/PID поднять CDC. Понятно, что эмуляцию PL2303, увы, уже так не сделать, но вот "обычный унылый" /dev/ttyACMx, возможно, получится. Вот тогда все будет замечательно. А если нет, то хорошо бы поискать, существуют ли вообще среди простых STM32 МК, которые не приколачивают гвоздями в регистры USB номер, полученный при энумерации - чтобы можно было на них эмулировать USB hub.
P.S. Кстати, слышал обидную новость: нацик выкинул из ядра поддержку reiserfs. Уныло, однако. Теперь уж точно придется до определенной версии ядро заморозить. А когда уже HDD или SDD с корнем помрут - ставить систему почти с нуля, но уже на другую ФС. Правда, я понятия не имею, какую ФС сейчас для корня использовать. Не ублюдскую же ext4! Да и где гарантии, что с той же ZFS не поступят аналогично, как с reiserfs?