Как исправить ошибку «Ошибка -5» при передаче произвольного количества байтов с использованием LIB-USB? - PullRequest
4 голосов
/ 28 октября 2008

У меня проблема с проектом USB, использующим LIB-USB. Устройство USB основано на PIC18F4550 и имеет единственную контрольную точку управления. Интерфейс ПК написан на MSVC и использует Lib-Usb 1.12.

На ПК программа запускается с настройки конфигурации, запроса интерфейса, затем отправки (и получения) управляющих сообщений (в зависимости от поставщика) - все успешно. После того, как было передано случайное число байтов (где-то между 100 и 2000), передача останавливается с error rc = -5 , возвращенной из вызова usb_control_msg.

На ПК-конце вызовы выглядят так:

ret = usb_set_configuration(udev, 1);  
ret = usb_claim_interface(udev, 0);    
ret = usb_control_msg(udev, USB_TYPE_VENDOR|USB_RECIP_DEVICE, CMD_RESET, 0, 0, buffer, 0, 100);  
ret = usb_control_msg(udev, 0xC0, GET_FIFO_DATA, 0, 0, buffer, 8, 100); 

Последний вызов, который фактически получает данные с устройства USB, выполняется много раз подряд, но всегда прерывается после передачи таким образом случайного числа байтов (всего от 100 до 2000). Смена канала на EP1 делает то же самое с той же ошибкой, которая в конечном итоге появляется.

На конце USB-устройства (PIC) дескриптор очень прост, имеет только канал EP0 и выглядит следующим образом:

Device
db 0x12, DEVICE ; bLength, bDescriptorType  
db 0x10, 0x01   ; bcdUSB (low byte), bcdUSB (high byte)  
db 0x00, 0x00   ; bDeviceClass, bDeviceSubClass  
db 0x00, MAX_PACKET_SIZE    ; bDeviceProtocol, bMaxPacketSize  
db 0xD8, 0x04   ; idVendor (low byte), idVendor (high byte)    
db 0x01, 0x00   ; idProduct (low byte), idProduct (high byte)  
db 0x00, 0x00   ; bcdDevice (low byte), bcdDevice (high byte)  
db 0x01, 0x02   ; iManufacturer, iProduct  
db 0x00, NUM_CONFIGURATIONS ; iSerialNumber (none), bNumConfigurations  
Configuration1  
db 0x09, CONFIGURATION  ; bLength, bDescriptorType  
db 0x12, 0x00   ; wTotalLength (low byte), wTotalLength (high byte)    
db NUM_INTERFACES, 0x01 ; bNumInterfaces, bConfigurationValue    
db 0x00, 0xA0   ; iConfiguration (none), bmAttributes    
db 0x32, 0x09   ; bMaxPower (100 mA), bLength (Interface1 descriptor starts here)  
db INTERFACE, 0x00      ; bDescriptorType, bInterfaceNumber  
db 0x00, 0x00   ; bAlternateSetting, bNumEndpoints (excluding EP0)  
db 0xFF, 0x00   ; bInterfaceClass (vendor specific class code), bInterfaceSubClass  
db 0xFF, 0x00   ; bInterfaceProtocol (vendor specific protocol used), iInterface (none)  

Фактическая структура - это структура Брэдли Минча на ассемблере.

Если кто-то сталкивался с подобным типом проблемы, прежде чем я хотел бы услышать об этом, поскольку я пытался решить практически все, включая использование другого канала (EP1, с теми же результатами), включив бит UOWN PIC перед записью в канал, рукопожатие с хостом ПК (когда ПК должен отправить специфичную для поставщика команду перед записью датсы), но безрезультатно.

Ответы [ 3 ]

2 голосов
/ 31 октября 2008

теперь работает !!

Конечно, теперь я чувствую себя «умным, как мешок молотков». Если бы я внимательно прочитал раздел 18, я бы заметил строку о добавлении конденсатора 220 нФ между Vusb и землей. Добавлен колпачок 470 нФ между контактом 18 и землей, и это было все, что потребовалось .... надежные передачи сейчас.

Просто еще один случай "I forgot to read the fine print"

1 голос
/ 28 октября 2008

Очень желательно иметь анализатор шины USB Lecroy и Ellisys - это высокопроизводительные и немного дорогие. Итоговая фаза является примером нижнего уровня.
Использование анализаторов шин поможет вам в написании как вашей прошивки, так и программного обеспечения для ПК, если вы можете себе это позволить. Используя анализатор, вы можете определить, является ли проблема на вашем компьютере (данные, которые вы читаете, находятся на шине, но вы не видите их в программном обеспечении), или проблема в вашей прошивке (вы не видите данных на шине) ,

Из вашего описания трудно понять, в чем проблема, и я не знаю, что означает ошибка -5, если вы можете опубликовать определение имени для этого, я мог бы быть более полезным.
Как правило, рекомендуется передавать данные с устройства на устройства, кратные максимальному размеру пакета. Я также предлагаю вам внимательно прочитать соответствующие разделы 5.5.3 (для контрольных передач) и 5.8.3 для массовых передач в USB Spec

Дополнительный комментарий на основе второго предоставленного журнала :

Реальная ошибка, возвращаемая стеком usb, находится в вашем журнале:
vendor_class_request(): request failed: status: 0xc0000001, urb-status: 0xc000000c

Состояние URB (блока запроса USB), определенное в комплекте драйверов Windows usb.h как:
usb.h:#define USBD_STATUS_BUFFER_OVERRUN ((USBD_STATUS)0xC000000CL)

Я нашел хорошее объяснение этой ошибке здесь .

Пожалуйста, игнорируйте тот факт, что это ошибка, определенная WinDriver, это просто переопределенная ошибка из Windows, и объяснение того, что она обычно означает, является правильным.

Здесь - пример того, почему это может произойти, но есть и другие потенциальные причины для такого поведения.

0 голосов
/ 30 октября 2008

У меня нет анализатора («пока», по крайней мере), но я установил DebugView, чтобы увидеть, что делает драйвер, со следующей трассировкой вывода. Первая показанная передача (специфичная для поставщика) успешна, а вторая умирает. Код возврата «-5», означающий «ошибка ввода-вывода» (не особенно полезен), возвращается из вызова.

00002674 315.26220703 LIBUSB-DRIVER - vendor_class_request (): тип: поставщик
00002675 315.26223755 LIBUSB-DRIVER - vendor_class_request (): получатель: устройство
00002676 315.26223755 LIBUSB-DRIVER - vendor_class_request (): запрос: 0x04
00002677 315.26223755 LIBUSB-DRIVER - vendor_class_request (): значение: 0x0000
00002678 315.26223755 LIBUSB-DRIVER - vendor_class_request (): индекс: 0x0000
00002679 315.26223755 LIBUSB-DRIVER - vendor_class_request (): размер: 8 00002680 315.26226807 LIBUSB-ВОДИТЕЛЬ - vendor_class_request (): направление: в
00002681 315.26226807 LIBUSB-DRIVER - vendor_class_request (): время ожидания: 100
00002682 315.26617432 LIBUSB-DRIVER - vendor_class_request (): передано 8 байт 00002683 315.26721191
00002684 315.26721191
00002685 315.26721191 LIBUSB-DRIVER - vendor_class_request (): тип: вендор
00002686 315.26721191 LIBUSB-DRIVER - vendor_class_request (): получатель: устройство
00002687 315.26724243 LIBUSB-DRIVER - vendor_class_request (): запрос: 0x04
00002688 315.26724243 LIBUSB-DRIVER - vendor_class_request (): значение: 0x0000
00002689 315.26724243 LIBUSB-DRIVER - vendor_class_request (): индекс: 0x0000
00002690 315.26724243 LIBUSB-DRIVER - vendor_class_request (): размер: 8 00002691 315.26724243 LIBUSB-DRIVER - vendor_class_request (): направление: в
00002692 315.26727295 LIBUSB-DRIVER - vendor_class_request (): время ожидания: 100
00002693 315.27017212 LIBUSB-DRIVER - vendor_class_request (): запрос не выполнен: статус: 0xc0000001, статус urb: 0xc000000c
00002694 315.27407837 [3684] LIBUSB_DLL: ошибка: usb_control_msg: ошибка отправки управляющего сообщения, ошибка win: устройство, подключенное к системе, не работает.
00002695 315.27407837 [3684]
00002696 315.27511597
00002697 315.27514648 LIBUSB-DRIVER - release_interface (): интерфейс 0

...