USB-приложения, использующие библиотеку libusb - PullRequest
1 голос
/ 24 января 2012

Я хочу использовать библиотеку libusb для написания некоторых тестовых приложений для USB. Кто-нибудь может подсказать, как настроить передачу управления с помощью вызова usb_control_msg?

Я получаю ошибку плохого дескриптора при выполнении следующего кода.

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "usb.h"
static int vendor_id;
static int product_id;

typedef struct{
    int requesttype; 
    int request;
    int value;
    int index; 
    char *bytes;
    int size;
    int timeout;
}ctrlmsg_param;

void print_endpoint(struct usb_endpoint_descriptor *endpoint)
{
    printf("=====End point Information====\n");
    printf("bEndpointAddress: %x\n", endpoint->bEndpointAddress);
    printf("bmAttributes:     %x\n", endpoint->bmAttributes);
    printf("wMaxPacketSize:   %d\n", endpoint->wMaxPacketSize);
    printf("bInterval:        %d\n", endpoint->bInterval);
    printf("bRefresh:         %d\n", endpoint->bRefresh);
    printf("bSynchAddress:    %d\n", endpoint->bSynchAddress);
}

void print_altsetting(struct usb_interface_descriptor *interface)
{
    int i;

    printf("\n=====Alternate Setting Information====\n");
    printf("bInterfaceNumber:   %d\n", interface->bInterfaceNumber);
    printf("bAlternateSetting:  %d\n", interface->bAlternateSetting);
    printf("bNumEndpoints:      %d\n", interface->bNumEndpoints);
    printf("bInterfaceClass:    %d\n", interface->bInterfaceClass);
    printf("bInterfaceSubClass: %d\n", interface->bInterfaceSubClass);
    printf("bInterfaceProtocol: %d\n", interface->bInterfaceProtocol);
    printf("iInterface:         %d\n", interface->iInterface);

    for (i = 0; i < interface->bNumEndpoints; i++)
        print_endpoint(&interface->endpoint[i]);
}

void print_interface(struct usb_interface *interface)
{
    int i;

    for (i = 0; i < interface->num_altsetting; i++)
        print_altsetting(&interface->altsetting[i]);
}

void print_configuration(struct usb_config_descriptor *config)
{
    int i;

    printf("=====Configuration Information====\n");
    printf("wTotalLength:         %d\n", config->wTotalLength);
    printf("bNumInterfaces:       %d\n", config->bNumInterfaces);
    printf("bConfigurationValue:  %d\n", config->bConfigurationValue);
    printf("iConfiguration:       %d\n", config->iConfiguration);
    printf("bmAttributes:         %x\n", config->bmAttributes);
    printf("MaxPower:             %d\n", config->MaxPower);

    for (i = 0; i < config->bNumInterfaces; i++)
        print_interface(&config->interface[i]);
}

int print_device(struct usb_device *dev)
{
    usb_dev_handle *udev;
    char str[100];
    int ret, i;
    udev = usb_open(dev);
    if (udev) {
        if (dev->descriptor.iManufacturer) {
            ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer, str, sizeof(str));
            if (ret > 0)
            {
                printf("Manufacturer is %s\n",str);
            }
        }
        if (dev->descriptor.iProduct) {
            ret = usb_get_string_simple(udev, dev->descriptor.iProduct, str, sizeof(str));
            if (ret > 0)
            {
                printf("Product is %s\n",str);
            }
        } 

    }

    if (udev)
        usb_close(udev);
    printf("Possible configurations are %x\n",dev->descriptor.bNumConfigurations);
    sleep(2);
    for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
        print_configuration(&dev->config[i]);

    return 0;
}
int htod( const char* str )
{
    int decimal;
    sscanf( str, "%x", &decimal);
    return decimal;
}
void set_data(struct usb_device *dev)
{

ctrlmsg_param  param;
param.requesttype= 0;
param.request=0;
param.value=0;
param.index=0;
param.bytes=10;
param.size=0;
param.timeout=5000;
usb_control_msg(dev, param.requesttype, param.request, param.value, param.index, param.bytes, param.size, param.timeout);
printf("error is %s\n",strerror(errno));
return;

}
int main(int argc, char *argv[])
{
    struct usb_bus *bus;
    struct usb_device *dev;

    if(argc != 3)
    {
        printf("Error in number of arguments\n");
        printf("Usage:./usb_info <vendor id> <product id>\n");
        exit(0);
    }

    vendor_id=htod(argv[1]);
    product_id=htod(argv[2]);

    printf("initializing USB library\n");
    usb_init();

    printf("Finding Buses and Devices\n");
    usb_find_busses();
    usb_find_devices();

    for (bus = usb_get_busses(); bus; bus = bus->next) {
        for (dev = bus->devices; dev; dev = dev->next) {
            if ((dev->descriptor.idProduct == product_id) && (dev->descriptor.idVendor == vendor_id)){           
                printf("Found device with produxt id %x and vendor id %x\n",product_id,vendor_id);
                print_device(dev);
                set_data(dev);
                print_device(dev);
            }
        }
    }
    return 0;
}

С уважением, Sandeep

1 Ответ

2 голосов
/ 23 ноября 2014

Я думаю, что вы имеете в виду usb_control_msg() - возвращает код ошибки для «плохой дескриптор».Пожалуйста, уточните, если это неверно.

Передачи управления USB имеют некоторые очень специфические правила форматирования, и если пакет, который вы формируете, отправляется на любое совместимое устройство, он вернет ошибку / остановку запроса на шине.

Вы отправляете управляющий перевод:

bmRequestType = 0x00
bRequest      = 0x00
wValue        = 0x0000
wIndex        = 0x0000
wSize         = 0x0000

это должно быть интерпретировано USB-устройством как запрос GET_STATUS, поэтому для wLength должно быть 2, а для bmRequestType должен быть верхний битустановить, указывая, что это запрос направления IN (с точки зрения хоста).Это все из главы 9 спецификации USB 1.1 / 2.0 / 3.1, доступной на сайте www.usb.org.

Параметр char *bytes (ваш param.bytes) также должен быть адресом / указателем вВы выполняете вызов.

Хорошая стандартная контрольная передача для тестирования будет:

bmRequestType = 0x80
bRequest      = 0x06
wValue        = 0x0001
wIndex        = 0x0000
wSize         = 0x0008

Этот запрос вернет первые 8 байтов дескриптора устройства, он действителен для каждого USBdevice, во всех состояниях.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...