Pull to refresh

Comments 9

За попытку сделать хорошо принимайте от меня плюсы.

Но в целом... Вы же понимаете что статья всего лишь вольная интерпретация всеми любимого "Chapter 9 USB Device Framework" вместе с "Class definitions for Communication Devices" (ну еще немного STM32 для того, чтоб не совсем теория). Критиковать, безусловно, легко. Делать сложно. Но мне кажется, что ссылок на оригинальные документы (как минимум) категорически не хватает. Ну и еще один сайтик - https://www.usbmadesimple.co.uk/index.html Он весьма не плох именно как выжимка основного из USB. Его бы перевести... Хотя документация бывает или русской или правильной... К сожалению (или к счастью) до сих пор актуально.

И да - тег "Реверс-инжиниринг" несколько сомнителен.

"Chapter 9" изучу, спасибо. Но когда я разбирался в коде этот документ мне не попадался, и приходилось копаться в том коде, который хотя как-то работал, восстанавливая его логику.

Насколько я помню есть перевод USB made simple, там как раз хорошее описание того, как составлять дескрипторы.

В целом, прежде чем начинать программировать, крайне желательно ознакомиться со спецификациями. В частности программируя USB устройство очень желательно почитать спецификацию USB. При этом ее глава 9 (посвященная именно устройствам), несомненно самая важная часть для поставленной задачи. А вот стоит ли ей ограничиться, или все же как минимум ознакомиться и с остальными - это уже целиком и полностью ответственность разработчика.

Как думаете, что отличает хорошего разработчика от... остальных... в свете высказываний из данного комментария? И да Communication Device Class - это отдельная спецификация. Тоже довольно объемная. Но вполне поддающаяся пониманию. В целом в USB спецификации не так уж много воды и откровенных канцеляризмов. Но читать ее надо вдумчиво.

Если уж работаете на регистрах, неужели не видели других реализаций? Моей, например, или Эдди. Еще где-то была реализация на шаблонах С++.
В этом документе содержатся адреса нужных для работы регистров и описание битов в этих регистрах. А также режимов работы этих битов (это важно). Для удобства программирования, я вынес эти адреса в макросы:
Зачем, если они объявлены в заголовочниках от ST? Ладно код, но макросы вы вряд ли напишете эффективнее.
Следующий важный момент, без которого мы не сможем настроить наше устройство — дескрипторы. Это заранее заготовленные и отформатированные ответы на запросы хоста «что ты такое» и «как ты работаешь».

А когда захотите поменять ConfigurationDescriptor — пересчитывать все размеры? Можете посмотреть как это сделано у меня:
Первый попавшийся пример - от MSD
static const uint8_t USB_ConfigDescriptor[] = {
  ARRLEN34(
  ARRLEN1(
    bLENGTH, // bLength: Configuration Descriptor size
    USB_DESCR_CONFIG,    //bDescriptorType: Configuration
    wTOTALLENGTH, //wTotalLength
    1, // bNumInterfaces
    1, // bConfigurationValue: Configuration value
    0, // iConfiguration: Index of string descriptor describing the configuration
    0x80, // bmAttributes: bus powered
    0x32, // MaxPower 100 mA
  )
  ARRLEN1(
    bLENGTH, //bLength
    USB_DESCR_INTERFACE, //bDescriptorType
    0, //bInterfaceNumber
    0, // bAlternateSetting
    2, // bNumEndpoints
    MSDCLASS_MSD, // bInterfaceClass: 
    MSDSUBCLASS_SCSI, // bInterfaceSubClass: 
    MSDPROTOCOL_BULKONLY, // bInterfaceProtocol: 
    0x00, // iInterface
  )
...


EP0R = (EP0R^0x3030)&0xBFBF

За магические чиселки бить по рукам!
#define ENDP_STAT_TX(num, stat) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ stat; }while(0)
...
ENDP_STAT_TX(idx, USB_EP_TX_VALID);

внутрь устройства был помещён целый интерпретатор команд, подобных G-кодам, который читает с флэш-карты различные сценарии, исполняет их и даже сигнализирует об ошибках.

Так может, стоило не CDC делать, а MSD (флешку)?
Заголовок спойлера
Я делал такое habr.com/ru/post/549016
и даже такое habr.com/ru/post/654853

Спасибо за ссылки. Сохранил вашу статью к себе.

Что касается MSC, я об этом думал и изначально планировал, однако решил отложить реализацию на следующий этап работы над проектом, после очередной чистки и утрамбовывания кода. И ещё потому, что сейчас мне нужно переключиться на задачи совсем другого типа, а уже потом влезать в особенности работы BOT.

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

От заголовочника ST у меня сильно подгорело именно потому, что там слишком большое количество ссылок из одних макросов в другие. В этом было очень неудобно разбираться, поскольку между Reference Manual и тем, что написано в коде был ряд промежуточных абстракций. Кроме того при компиляции оказалось, что прямые "магические циферки" занимают в итоге меньше места, чем использование любых других конструкций (за исключением, разве что, прямого вынесения этих циферок в макросы).

функции расчёта длины их частей и прочие необходимые действия в любом случае занимали бы больше ПЗУ.
Во всех нормальных реализациях (к ST-HAL это, понятное дело, не относится) размер дескриптора и всех его частей считается на этапе компиляции. У меня это макрос, у плюсовиков — шаблон. То есть объем прошивки не возрастает. Да и слабо представляю как ее считать в рантайме: длина ведь далеко не всегда вторым байтом идет.
Понимаю, что код, который оптимизируется по размеру
И сколько вам удалось выжать объема от «чистого» USB-CDC без дополнительных функций?
От заголовочника ST у меня сильно подгорело именно потому, что там слишком большое количество ссылок из одних макросов в другие.
Если бы макросов еще ладно, но они между функциями байты гоняют! Причем одни и те же.

Эпичная работа проделана. Мне часто сложно увязать большие объемы данных друг с другом. Тут же, все собрано и объяснено, что вызывает уважение.

Sign up to leave a comment.

Articles