Comments 23
Модель OSI мертворождённая и нелюбимая практиками. Модель IP лучше ложится. Уровней меньше: физический, канальный, сетевой, транспортный, прикладной. Заметим, так же как в IP есть некоторое пересечение по L2/L3, некоторые вещи строго к одному уровню не отнести.
А зачем вообще натягивать терминологию из одной области на другую? Когда IP притягивают за уши к OSI, меня это тоже коробит.
мы не натягиваем, мы абстрактно проецируем:)

а ключевые термины из другой области («канальный уровень», «кадр») я как раз явно старался обходить сам и расставлять флажки читателям; неужели не получилось?
Мне в USB не нравится то, что практически н как не разделена логически низкоуровневая часть прикладного интерфейса (энумерация и так далее) и высокоуровневая пользовательская (это относится в первую очередь к кастомным протоколам). В результате, даже в случае простейшего обмена в стиле UART через два ендпоинта, нужно писать (читай, копипастить из примеров от SDK вендора чипа) огромную кучу boilerplate кода и дескрипторов.
UFO landed and left these words here
Ну, скажем, для работы с STM32, используя библиотеку opencm3, ничего страшного делать не нужно: только определить поля структур описаний (но без этого никуда не деться — таки протокол такой) и свои обработчики повесить.
«Жукотряс». Отличный неологизм, надо запомнить.
А то у нас прижилось в одобрительном ключе слово
21+
«Байто2.71б».
Зачем HID, если CDC проще и более к месту?
Да и писать софт для работы с CDC значительно проще (libusb не нужно использовать, да и вообще абстрагироваться от того, что железяка на USB висит).

HID нужен лишь если хочется эмулировать какое-нибудь стандартное устройство (скажем, клаву или мышу).
Communications Device Class — интересный вариант, но главное — не закончить банальным эмулятором последовательного порта, как намекает википедия (это вырвано из контекста; лучше читать статью полностью):
This class can be used for industrial equipment such as CNC machinery to allow upgrading from older RS-232 serial controllers and robotics, since they can keep software compatibility. The device attaches to an RS-232 communications line and the operating system on the USB side makes the USB device appear as a traditional RS-232 port.

Как я понял, с CDC можно работать и в пакетном режиме, это уже интереснее. А если Вы принесете нам сюда примеры проектов для ARM (только проверенные), будет вообще замечательно, можно и врезку сделать в публикацию.

HID нужен лишь если хочется эмулировать какое-нибудь стандартное устройство (скажем, клаву или мышу).

Да бросьте:) А как Вам вот эта клавиатура с мышью?

Вы кофе любите пить? Попробуйте скачать HID Descriptor Tool и собрать на нём интерфейс описанной мною гипотетической HID-кофеварки:)
Сходите ко мне на гитхаб или сосфорж. Там лежат 2 незавершенных, но рабочих проекта (под STM32F103 и STM32F407) с реализацией CDC. Пакетный режим мне не интересен, т.к. протокол коммуникации символьный. Но при желании можно и на блоки разбивать данные.

> Да бросьте:) А как Вам вот эта клавиатура с мышью?
Я бы не парил себе мозг, а сделал на CDC, т.к. а) проще, б) не нужно писать сложных вещей с libusb (а то и вообще извращаться и модули ядра калякать).

Не надо использовать HID в областях, для которых он явно не предназначен!
Пакетный режим мне не интересен, т.к. протокол коммуникации символьный. Но при желании можно и на блоки разбивать данные.
А у меня как раз не символьный, а сообщения. Превращать сообщения в поток, затем поток разбивать на пакеты, затем собирать обратно в поток, затем декодировать сообщения? На эту тему другие ребята копий уже наломали прилично, лично я на стороне RaJa:)
habrahabr.ru/post/208026/#comment_7164068
habrahabr.ru/post/208026/#comment_7164070
habrahabr.ru/post/208026/#comment_7164386
habrahabr.ru/post/208026/#comment_7164290
habrahabr.ru/post/208026/#comment_7163744

не нужно писать сложных вещей с libusb (а то и вообще извращаться и модули ядра калякать)

Тут согласен, под некоторыми платформамми поддержка HID хромает, и я сам в этом убедился. Наш инженерный ян говорит: «используй то, что работает». Инь не остаёт: «найди новый, более эффективный способ сделать привычные вещи». Диалектика:)

Не надо использовать HID в областях, для которых он явно не предназначен!

en.wikipedia.org/wiki/USB_human_interface_device_class#Other_devices
The USB HID class specifications allow for myriad other devices under the USB HID class. Some examples are automobile simulation controllers, exercise machines, telephony devices, thermometers, audio controls and medical instrumentation. Even uninterruptible power supplies and software protection dongles declare themselves under this class, despite the fact they often have no human interface at all. Any device can be a USB HID class device as long as a designer meets the USB HID class logical specifications. This is not to say that there is no need to ship drivers for these devices, nor that an operating system will immediately recognize the device. This only means that the device can declare itself under the human interface device class.

Пример ИБП показателен, я сам подключал SUA750I двумя шнурками и смотрел разницу. Вручную можно работать только по RS232 терминалкой, там простой символьный протокол, по USB так не сделаешь. Но очень страшно нажать не на тот символ, тогда можно вывести прибор из строя. Я к тому, что библиотека должна иметь исключительную надёжность в плане синхронизации символьного потока и сообщений: любой лишний, случайно залетевший байт — и привет, разбор устройства и перепрошивка программатором. Для APC Smart UPS такую библиотеку сделали, это радует. Но для новых устройств получается habrahabr.ru/post/208026/#comment_7164070
Превращать сообщения в поток, затем поток разбивать на пакеты, затем собирать обратно в поток, затем декодировать сообщения?

Не совсем так: у меня есть символьные команды (при желании можно бинарный протокол реализовать, но мне удобней, чтобы можно было и просто хоть при помощи screen устроить сеанс связи), которые расшифровываются, а далее уже — хоть мегабайтный блок данных ожидай с синхрометками…
там простой символьный протокол, по USB так не сделаешь

Почему это? Тот же CDC изначально и был «заменой RS-232». Фактически и есть последовательный порт, только скорости повыше (сколько USB МК может выжать). А еще удобен CDC тем, что можно свое устройство сделать «хабом» для устройств, которые реальный RS-232 используют, и общаться с теми устройствами из компьютера напрямую!
любой лишний, случайно залетевший байт

Откуда ж он туда залетит-то?
Но для новых устройств получается habrahabr.ru/post/208026/#comment_7164070

Так есть и bulk режим для тех, кому нужно бешеные потоки данных пересылать!
Все элементарно же!!! Создаем «составное» устройство: CDC + bulk, CDC используем для команд, а по второму псевдоустройству гоняем бешеные потоки данных. Правилом udev на второе устройство сделаем какой-нибудь симлинк, вроде /dev/bigdataport, а в своей программе просто открываем /dev/ttyACMx и этот /dev/bigdataport; с первым по CDC общаемся (т.е. по сути посимвольно, хотя фактически там идут пакеты по 64 байта), второй в bulk-режиме.
там простой символьный протокол, по USB так не сделаешь

Я имел в виду, что с ИБП Smart UPS SUA750I работать через виртуальный COM-порт по USB не получается. По USB он фигачит именно HID-пакеты (GET_REPORT / SET_REPORT). Но нужна библиотека для работы с этим хозяйством, устройство которой изначально *кажется* сложнее, чем пакетный кодек для простого потока.

Откуда ж он туда залетит-то?

Так от меня и залетит (ха-ха, каламбур), если ошибусь при сборке велосипеда или библиотеку выберу глючную. Счётчик цикла отработал на одну итерацию больше, и всё, съехали пакеты. Канал потерян, срочно сброс и синхронизация заново.
Коллега, я Вас услышал, и вот моё резюме:
1) CDC могут работать как составные (composite) устройства, вывешивая на хост символьный интерфейс для команд и пакетный интерфейс для коммуникационных протоколов канального уровня типа Ethernet, PPP, работающий в крупноблочном (bulk) режиме. Это типовая реализация USB-свистков 3G/4G (там ещё Mass Storage с драйверами в нагрузку идёт).

2) В самой идее HID есть *готовые* абстракции для описания наборов сенсоров, датчиков, индикаторов и прочего. В CDC нет, это чистые коммуникации (дать сырой символьный или пакетный интерфейс хосту).

3) Моей HID-кофеварке бешеные потоки данных не нужны, и пересборка пакетов волнует не с точки зрения производительности (ARM и не поперхнётся). Обмен короткими (не bulk), бинарно-ориентированным структурами данных (пульты, датчики, сенсоры и прочее) потребует либо адаптации символьного интерфейса на пакетный режим (нежелательная пересборка), либо адаптации bulk transfer к коротким передачам определённого формата, укладываемым строго в виде сообщение-пакет, без разбивки/пересборки.

4) Вариант с использованием упомянутого канала bulk transfer в пакетном режиме для моей кофеварки интересен, но готового примера именно такой реализации для ARM Вы пока не предложили, упоминая только символьный протокол. Этот вопрос остаётся открытым.

5) На символьных протоколах работает невероятное количество всяких устройств, в основном, старых. Я хочу пакетной новизны, и у меня есть готовый и работающий (не под всеми платформами одинаково хорошо) пример кода с HID.

6) Получается, что от библиотек и middleware зависит почти всё. Есть и хорошие библиотеки для пакетных кодеков, и плохие для USB HID, и наоборот.

Так что если хорошего примера кода с библиотекой по п. 4 нет, давайте просто не будем мусолить тему по кругу:)
Вариант с использованием упомянутого канала bulk transfer в пакетном режиме для моей кофеварки интересен, но готового примера именно такой реализации для ARM Вы пока не предложили

Я же сказал: мне это пока что не нужно. Если будет нужно — сделаю реализацию. Можете и сами при помощи libopencm3 сделать. Там все значительно проще, чем ковыряться в костылях SPL от индусов STM!
Я хочу пакетной новизны

Ну, не всегда новизна оправдана. А лично я хочу простоты. Мне и так уже два раза приходилось с извращенными устройствами мучиться (одно работало через модуль ядра, который был написан при царе Горохе, и пришлось его рихтовать; второе работало через libusb, но библиотека была плюсовая и пришлось пилить сишную обертку + саму библиотеку рихтовать, т.к. в ней много ошибок было).
Я таки думаю, что HID оправдан тогда, когда вы делаете устройство, работающее по стандартным HID-протоколам.
Получается, что от библиотек и middleware зависит почти всё

Да, поэтому лучше плясать от них, чтобы не тратить кучу времени на софт.

Так что если хорошего примера кода с библиотекой по п. 4 нет

Надо по гитхабу поискать. Вполне возможно, что найдется. Скажем, у самопальных контроллеров видеокамер наверняка bulk-передача!
Кстати, почитал комментарии по ссылкам. Судя по всему, RaJa работает в венде. А там программирование сродни Сизифову труду! В линуксе проблем таких нет. Да и порт при желании можно в неблокирующем режиме открыть (только как потом такую мешанину обрабатывать?).
Классная статья! Написано очень здорово, спасибо автору!
Микроленивчик от меня:
Кадры передаются последовательной передачей бит по методу NRZI.

Можно сделать вот так, для негуглаторов:
Кадры передаются последовательной передачей бит по методу NRZI.


битовый поток по методу NRZI со вставкой бит (bit stuffing). Т.е. передаются нолики, единички и всякие управляющие символы.

Не много не понятно с первого взгляда, причему тут bit stuffing, и что за такие управляющие символы могут быть когда у нас есть либо высокий либо низкий уровень. Внесите ясность, что передаются всегда нолики и единички, но не всегда это данные спустившиеся по USB стэку. Ну либо поправьте меня если я что-то не так понял. Заодно сам пойму :)

Ну и для меня, опять же лично, осталось невыясным: упаковка пакетов происходит по принципу «матрешки» или как и в стеке TCP/IP имеет место биение по максимальному размеру фрэймов на одном/нескольких уровнях?
Спасибо, вопросы правильные.
Я внёс правки в текст, посмотрите. Конечно, по «физике» передаётся ещё кое-что помимо данных, спустившихся по стеку, на то он и стек:) Там на трёх проводах и с помощью синхронихации разыгрывается «0», «1» и ещё несколько специальных символов-сигналов-состояний типа «начало пакета», «конец пакета», «холостой», «сброс», «спать», «проснуться» и т.д.

А что касается фрагментации, то максимальные размеры пакетов закрепляются стандартом, фактические — в процессе работы, транзакции на пакеты не разбиваются и всегда передаются целиком. Остальное решает хост, он может разбить передачу на несколько транзакций, чтобы уступить пропускную способность веб-камере, например.
Разве там D+ и D- не дифференциальная пара? Она вообще отношение к общему проводу имеет только электрическое за счет защитных диодов… фактически данные передаются только по двум проводам, а общий нужен только для питания и удобной «детекции» скорости шины по сопротивлению между сигнальной шиной и общим проводом.
дифференциальная, но когда оба конца подтянуты к земле, получается SE0. При этом подтягивать «вверх» (SE1) нельзя, illegal.

Если угодно, добавил ссылку на книжку, все элетричество разобрано, ничего не выдумываю:)
Да уж, франкенштейн получился… вроде бы и дифф.линия и в тоже время используют её отдельные провода для каких-то других целей. Вот не могли тогда еще добавить еще один провод в спецификацию шины и спать спокойно…
Only those users with full accounts are able to leave comments. Log in, please.