Мы разрабатываем небольшое встраиваемое устройство. В этом устройстве используется плата gumstix overo под управлением OpenEmbedded linux. Наша разработка почти полностью завершена, и мы столкнулись с странной ошибкой, которую мы не можем понять.
У нас есть USB-устройство (спектрофотометр) с разъемом USB2.0. и внешний источник питания для источника света. Обычно вы подключаете блок питания, а затем подключаете USB-соединение к хосту. Когда устройство обнаруживает USB-соединение, оно загружается и включает источник света и вентилятор. Затем устройство может использоваться хост-системой.
Проблема в том, что если устройство подключено к Gumstix до того, как мы включим Gumstix, USB-устройство, по-видимому, не проверяется системой (и, следовательно, не включается). В нормальной ситуации, когда соединение инициализируется подключением кабеля USB, Spectro включается и становится доступным для системы (обычно это можно увидеть через «lsusb»). Ничего из этого не происходит. Нет никаких устройств, обнаруженных с помощью "lsusb", и никаких ошибок dmesg, которые мы можем увидеть. Как будто устройство не подключено к розетке.
Устройство делает появляются и работают нормально, если мы отсоединяем USB-кабель и снова подключаем его после загрузки системы. Он включается и появляется на шине USB, и мы можем получить к нему доступ с помощью нашего драйвера.
На любом другом настольном компьютере или ноутбуке не имеет значения, включена или выключена хост-система, когда мы подключаем спектрометр. Такое поведение я считаю «нормальным» - система USB проверяется и инициализируется во время загрузки, и устройства USB подключаются к сети. Другими словами, наша система полностью функциональна, пока мы подключаем USB-устройство после загрузки системы. К сожалению, в нашем конечном продукте это невозможно - все работает сразу.
Дополнительная информация: 1) Мы пробовали подключать флешку к системе при выключенной системе. Загрузка системы переводит флешку в оперативный режим, как и ожидалось. 2) Нет сообщений о Spectro или USB-устройстве (с использованием dmesg). "lsusb" перечисляет только концентраторы / контроллеры USB. Буквально, как будто устройства нет и не подключено. 3) Мы пробовали новый образ от gumstix и старый образ прошлого года. У обоих изображений есть эта проблема. Эта проблема существует на всех 3 устройствах gumstix, которые мы используем.
У кого-нибудь есть предложения? Насколько я могу судить, на самом деле невозможно выполнить полную «перезагрузку» USB-системы, которая представляет собой полную эмуляцию «отключения» и «повторного подключения» USB-устройства. Я чувствую, что происходит то, что на шине USB нет начального зонда, который запускал бы квитирование USB, но это как-то специфично для Spectro. Кажется, это проблема ядра или, по крайней мере, проблема в том, как ядро инициализирует подсистему USB. Хотя я не совсем уверен.
Я пробовал использовать список рассылки gumstix, но, похоже, никто не сталкивался с этой проблемой раньше. Любые советы или предложения о том, с чего начать поиск, были бы фантастическими.
Спасибо! Блейн
output etc.
$ uname -a
Linux overo 2.6.33 #1 Tue Apr 27 08:35:38 PDT 2010 armv7l GNU/Linux
When the system is up and running and spectro is plugged in (working as intended), this is lsusb:
Bus 001 Device 116: ID 2457:1022
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x2457
idProduct 0x1022
bcdDevice 0.02
iManufacturer 1 USB4000 1.01.11
iProduct 2 Ocean Optics USB4000
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 46
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 400mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 4
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0000
(Bus Powered)
dmesg output:
usb usb1: usb auto-resume
hub 1-0:1.0: hub_resume
usb usb2: usb auto-resume
ehci-omap ehci-omap.0: resume root hub
hub 1-0:1.0: state 7 ports 1 chg 0000 evt 0000
hub 2-0:1.0: hub_resume
hub 2-0:1.0: state 7 ports 3 chg 0000 evt 0000
hub 1-0:1.0: hub_suspend
usb usb1: bus auto-suspend
hub 2-0:1.0: hub_suspend
usb usb2: bus auto-suspend
ehci-omap ehci-omap.0: suspend root hub
usb usb2: usb resume
ehci-omap ehci-omap.0: resume root hub
hub 2-0:1.0: hub_resume
ehci-omap ehci-omap.0: GetStatus port 2 status 001803 POWER sig=j CSC CONNECT
hub 2-0:1.0: port 2: status 0501 change 0001
hub 2-0:1.0: state 7 ports 3 chg 0004 evt 0000
hub 2-0:1.0: port 2, status 0501, change 0000, 480 Mb/s
ehci-omap ehci-omap.0: port 2 high speed
ehci-omap ehci-omap.0: GetStatus port 2 status 001005 POWER sig=se0 PE CONNECT
usb 2-2: new high speed USB device using ehci-omap and address 2
ehci-omap ehci-omap.0: port 2 high speed
ehci-omap ehci-omap.0: GetStatus port 2 status 001005 POWER sig=se0 PE CONNECT
usb 2-2: default language 0x0409
usb 2-2: udev 2, busnum 2, minor = 129
usb 2-2: New USB device found, idVendor=2457, idProduct=1022
usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 2-2: Product: Ocean Optics USB4000
usb 2-2: Manufacturer: USB4000 1.01.11
usb 2-2: uevent
usb 2-2: usb_probe_device
usb 2-2: configuration #1 chosen from 1 choice
usb 2-2: uevent
usb 2-2: adding 2-2:1.0 (config #1, interface 0)
usb 2-2:1.0: uevent
drivers/usb/core/inode.c: creating file '002'
dmesg has nothing to say, and lusb simply lists nothing else but the two default usb controllers / hubs if we plug the device in before the system is turned on.
Вернуть это из мертвых для завершения.
Детали нечеткие, но, как оказалось, само устройство вылетало при загрузке. Я считаю, что это было связано с сгенерированным uBoot трепом на линии USB. По сути, uBoot опрашивает все линии оборудования (включая USB), чтобы найти загрузочный образ. Этот опрос должен быть безвредным, но прошивка на нашем USB-устройстве не смогла с ним справиться и сразу вылетела, что сделало его неработоспособным до полного сброса (физического отключения устройства и его повторного включения).
Мы сообщили об этой ошибке производителю устройства, но не получили никаких указаний на то, что исправление проблемы (которая, по-видимому, затронула только нас) будет приоритетной, поэтому мы прибегли к исправлению за 0,50 доллара.
Мы решили эту проблему творчески, но сработали безупречно. Мы построили простое реле, управляемое GPIO, и пропустили через это реле линию питания USB. По сути, система загрузилась с выключенным реле и, следовательно, без питания USB-устройства. Система загрузилась нормально, и в нашем сценарии запуска мы просто переключили линию GPIO, чтобы активировать реле. USB-устройство нормально загружалось без помех от uBoot.
Похоже, что устройство пыталось общаться с ОС при первой загрузке, и, поскольку стек не был готов в то время, оно «вышло» из концентратора. Рассмотрите возможность добавления раздела в конец процесса загрузки, чтобы удалить драйвер и принудительно перезагрузить его. (modprobe -vr ehci_hcd; modprobe -v ehci_hcd
если USB2.0, uhci_hcd
если USB1.x)
Другая возможность заключается в том, что при выключении Gumstix он сказал устройству перейти в режим энергосбережения, который может неправильно поддерживаться устройством. Windows может делать здесь что-то иное, чем Windows, что может быть всем, что тестировал производитель. Чтобы проверить это, вам может потребоваться указать драйверу устройства, чтобы он не приостанавливал и не выключал устройства во время перезапуска системы. Посмотрите на Документация ядра Linux по энергосбережению в разделе USB, чтобы начать.