Для моего проекта домашней автоматизации с openHAB я хочу подключить платы FRDM ( Freedom ) Freescale (теперь NXP), чтобы они могли заботиться об аспектах реального времени и выступать в качестве шлюзов для других моих систем. Одним из способов является использование USB CDC (Serial over USB) в качестве канала связи. Преимущество USB в том, что он питает плату, плюс я могу подключить несколько устройств: до четырех на Raspberry Pi 2 и даже больше с помощью USB-концентратора. В стандартной конфигурации с USB WiFi и USB HID (мышь плюс клавиатура) я все еще могу прикрепить две платы Fesomcale Freescale (ahem, NXP) к Raspberry Pi:
FRDM-K22F и FRDM-K64F присоединены к Raspberry Pi 2
Контур
В этой статье описывается, как использовать Raspberry Pi с устройствами, подключенными к нему с помощью USB CDC. USB CDC — это класс устройств, который реализует протокол «последовательный через USB». Я использую USB CDC (см. « Учебник: USB CDC с платой свободы KL25Z ») во многих моих проектах, так что это элегантный способ связи между Raspberry Pi и встроенным микроконтроллером.
Где мой порт USB?
После подключения устройства USB CDC к Raspberry первая проблема заключается в том, чтобы узнать, какое устройство оно использует. Чтобы увидеть, какие USB-устройства подключены, я могу использовать команду lsusb :
lsusb
который показывает что-то такое:
pi@raspberrypi ~ $ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 7392:7811 Edimax Technology Co., Ltd EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS]
Bus 001 Device 008: ID 1366:0105 SEGGER
Bus 001 Device 005: ID 046d:c52b Logitech, Inc. Unifying Receiver
С участием
Bus 001 Device 008: ID 1366:0105 SEGGER
Он показывает Segger OpenSDA, в котором реализован комбинированный USB CDC.
Если подключить USB-CDC Freescale (см. « USB-CDC с помощью FRDM-K64F, наконец-то! »), То оно будет отображаться как
Bus 001 Device 007: ID 2504:0300
Строка поставщика пуста, потому что я использую «общие» VID и PID, не зарегистрированные в консорциуме USB. См. Http://ubuntuforums.org/showthread.php?t=2234649.
Где 2504 — идентификатор поставщика (VID), а 0300 — идентификатор продукта (PID), сообщаемый устройством USB. Это значения, которые я указал в реализации устройства USB:
Конфигурация USB CDC
Так какое устройство Linux оно использует?
- Подключите USB-кабель
- Используйте команду dmesg
Команда dmesg выводит информацию отладки / журнала ядра:
dmesg
Я должен увидеть что-то подобное для моей реализации USB CDC на плате FRDM:
[23621.397305] usb 1-1.3: New USB device found, idVendor=2504, idProduct=0300
[23621.397337] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[23621.397354] usb 1-1.3: Product: FSL CDC DEVICE
[23621.397371] usb 1-1.3: Manufacturer: FREESCALE INC.
[23621.398717] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device
Или для Segger USB CDC (OpenSDA):
[ 226.413679] usb 1-1.3: new full-speed USB device number 8 using dwc_otg
[ 226.519865] usb 1-1.3: New USB device found, idVendor=1366, idProduct=1015
[ 226.519890] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 226.519908] usb 1-1.3: Product: J-Link
[ 226.519924] usb 1-1.3: Manufacturer: SEGGER
[ 226.519940] usb 1-1.3: SerialNumber: 000000123456
[ 226.524041] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device
[ 226.527545] usb-storage 1-1.3:1.3: USB Mass Storage device detected
[ 226.527989] scsi host0: usb-storage 1-1.3:1.3
[ 227.525152] scsi 0:0:0:0: Direct-Access SEGGER MSD Volume 1.00 PQ: 0 ANSI: 4
[ 227.527831] sd 0:0:0:0: [sda] 21829 512-byte logical blocks: (11.1 MB/10.6 MiB)
[ 227.528693] sd 0:0:0:0: [sda] Write Protect is off
[ 227.528721] sd 0:0:0:0: [sda] Mode Sense: 0b 00 00 08
[ 227.529304] sd 0:0:0:0: [sda] No Caching mode page found
[ 227.529327] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 227.551467] sda:
[ 227.555561] sd 0:0:0:0: [sda] Attached SCSI removable disk
[ 227.562302] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 237.448489] usb 1-1.3: USB disconnect, device number 8
[ 237.533960] FAT-fs (sda): unable to read boot sector to mark fs as dirty
[ 245.623749] usb 1-1.3: new full-speed USB device number 9 using dwc_otg
[ 245.729928] usb 1-1.3: New USB device found, idVendor=1366, idProduct=0105
[ 245.729954] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 245.729971] usb 1-1.3: Product: J-Link
[ 245.729988] usb 1-1.3: Manufacturer: SEGGER
[ 245.730003] usb 1-1.3: SerialNumber: 000621000000
[ 245.732360] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device
Поскольку OpenSDA Segger J-Link представляет собой композитное (несколько) USB-устройство, оно показывает несколько устройств: MSD (запоминающее устройство большой емкости), J-Link и USB CDC (ACM). Опять же, он использует ttyACMx в качестве устройства.
Это говорит мне о том, что устройство было распознано и обрабатывается драйвером USB CDC ttyACM0.
: idea: См. https://www.rfc1149.net/blog/2013/03/05/what-is-the-difference-between-devttyusbx-and-devttyacmx/ о разнице между ACMx и USBx.
Команда udevadm показывает мне детали для устройства:
udevadm info -a -n /dev/ttyACM0
Опция ‘-a’ печатает всю информацию в цепочке устройств, а опция ‘-n’ используется для указания устройства (/ dev / ttyACM0) здесь:
сведения об устройстве, и он показывает мои данные устройства USB CDC:
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3':
KERNELS=="1-1.3"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{devpath}=="1.3"
ATTRS{idVendor}=="2504"
ATTRS{speed}=="12"
ATTRS{bNumInterfaces}==" 2"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="16"
ATTRS{busnum}=="1"
ATTRS{devnum}=="9"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="100mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="c0"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="0"
ATTRS{bcdDevice}=="0002"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="13"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="FREESCALE INC. "
ATTRS{removable}=="removable"
ATTRS{idProduct}=="0300"
ATTRS{bDeviceClass}=="02"
ATTRS{product}=="FSL CDC DEVICE"
Какое устройство / порт (/ dev / ttyACM0, / dev / ttyACM1,…) зависит от порядка их подключения. Ниже приведен пример подключения Segger OpenSDA J-Link и USB CDC, где он использует ttyACM0 для Segger USB CDC и ttyACM1 для родного USB CDC:
[ 3753.941466] usb 1-1.3: Product: J-Link
[ 3753.941482] usb 1-1.3: Manufacturer: SEGGER
[ 3753.941499] usb 1-1.3: SerialNumber: 000621000000
[ 3753.943825] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device
[ 3763.815366] usb 1-1.2: new full-speed USB device number 9 using dwc_otg
[ 3763.919642] usb 1-1.2: New USB device found, idVendor=2504, idProduct=0300
[ 3763.919671] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 3763.919709] usb 1-1.2: Product: FSL CDC DEVICE
[ 3763.919727] usb 1-1.2: Manufacturer: FREESCALE INC.
[ 3763.921320] cdc_acm 1-1.2:1.0: ttyACM1: USB ACM device
Бег
udevadm info -a -n /dev/ttyACM1
показывает мне следующую информацию для Segger OpenSDA J-Link:
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3':
KERNELS=="1-1.3"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="02"
ATTRS{bDeviceProtocol}=="01"
ATTRS{devpath}=="1.3"
ATTRS{idVendor}=="1366"
ATTRS{speed}=="12"
ATTRS{bNumInterfaces}==" 3"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{busnum}=="1"
ATTRS{devnum}=="8"
ATTRS{configuration}=="Configuration"
ATTRS{bMaxPower}=="100mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="80"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="0"
ATTRS{bcdDevice}=="0100"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{serial}=="000621000000"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="586"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="SEGGER"
ATTRS{removable}=="removable"
ATTRS{idProduct}=="0105"
ATTRS{bDeviceClass}=="ef"
ATTRS{product}=="J-Link"
Нам понадобится эта информация позже.
Терминальная программа Minicom
Теперь, когда я знаю устройство, мне нужна терминальная программа для связи с устройством. Я нашел программу терминала minicom очень простой в использовании, и она работает как с удаленного SSH, так и локально на Raspberry Pi.
Если minicom еще не установлен, используйте следующую команду для его установки:
sudo apt-get install minicom
Запустите миником с
minicom -D /dev/ttyACM0 -b 38400
Где -D указывает устройство, которое будет использоваться, и -b скорость передачи устройства. Это запускает программу терминала:
Началась мини-сессия
Как указано в нижней части экрана, я могу нажать «CTRL + A» (нажатие «CTRL», затем нажать клавишу «a» (нижний регистр), отпустить обе клавиши и затем нажать «z» на клавиатуре), чтобы отобразить меню справки:
Справка Minicom
Я могу использовать это меню, например, для включения / выключения локального эха. Без меню я просто использовал бы «CTRL + E» и «e»:
Local Echo On
Теперь я могу использовать minicom как обычную терминальную программу для общения с моими приложениями через оболочку (как показано ниже, где я разговариваю с моим проектом беспилотного квадрокоптера на FRDM-K22F ):
терминальная сессия minicom
Чтобы оставить миником, я использую CTRL + A, за которым следует x . Это повесит сессию.
Постоянные имена устройств для устройств USB CDC
Остается одна проблема: какое устройство используется, зависит от порядка, в котором оно распознается. Позже, когда я захочу использовать плату с openHAB, мне нужно убедиться, что плата всегда подключена к одному и тому же устройству. Чтобы назначить фиксированное устройство, я могу использовать правила udev . С помощью этих правил я могу указать, что произойдет при подключении нового устройства. Смотрите также эту статью о том, как писать файлы правил udev.
В /etc/udev/rules.d я создаю новый файл с именем
99-usb-serial.rules
99-USB-serial.rules
Файл должен иметь расширение .rules. Число 99 объясняется тем, что правила> = 90 должны выполняться последними (см. Http://hackaday.com/2009/09/18/how-to-write-udev-rules/ ).
Теперь мне нужно найти атрибуты, чтобы различать несколько USB CDC-устройств. Для этого я использую команду udevadm, которую я использовал ранее.
Чтобы создать выделенное устройство для Segger J-Link, я могу добавить следующую строку в 99-usb-serial.rules :
SUBSYSTEM=="tty", ATTRS{idVendor}=="1366", ATTRS{product}=="J-Link", ATTRS{idProduct}=="0105", ATTRS{serial}=="000621000000", SYMLINK+="ttyUSB50"
В частности, я пытаюсь использовать набор соответствующих атрибутов для идентификации устройства, а затем создать символическую ссылку для него с помощью команды SYMLINK + = .
Таким же образом я добавляю следующую строку для идентификации моей реализации USB CDC:
SUBSYSTEM=="tty", ATTRS{idVendor}=="2504", ATTRS{product}=="FSL CDC DEVICE", ATTRS{manufacturer}=="FREESCALE INC. ", SYMLINK+="ttyUSB51"
Это означает, что устройство по-прежнему будет использоваться как \ dev \ ttyACMx, но будет создана символическая ссылка / dev / ttyUSB50 или / dev / ttyUSB51.
Я использую следующую команду для проверки правил:
udevadm test /dev/ttyACM0
Это не создаст ссылки, но может быть полезно посмотреть, что происходит.
Правила Udev вступают в силу немедленно, но не сработают, если устройство уже подключено. Чтобы проверить мои новые правила, я должен отключить и повторно подключить устройства USB. Или использовать
udevadm trigger
С участием
ls -l /dev
Я должен видеть, что ссылка была создана:
lrwxrwxrwx 1 root root 7 Dec 26 19:23 ttyUSB50 -> ttyACM0
lrwxrwxrwx 1 root root 7 Dec 26 19:30 ttyUSB51 -> ttyACM1
Благодаря этому к Raspberry Pi можно подключить несколько плат, и они будут использовать фиксированное устройство:
Платы FRDM подключены к Raspberry Pi
Обратите внимание, что если у меня нет различий между устройствами, я не могу их различить. Это, например, проблема, например, с устройством USB CDC FSL, если я не меняю атрибуты по умолчанию. Я думаю о добавлении серийного номера в дескриптор устройства USB, чтобы я мог легко различать различные устройства таким образом.
Резюме
С некоторой работой я могу легко работать с устройствами USB CDC, подключенными к USB-портам Raspberry Pi. С помощью lsusb я вижу, какие устройства подключены, с помощью информации udevadm я могу проверить атрибуты устройства, а с помощью правил udev я могу назначить постоянные имена устройств на основе атрибутов. А с minicom у меня есть хорошая терминальная программа, которую я могу использовать для общения с USB-устройствами CDC.