使用 libusb 库的 USB 应用程序

发布于 2024-12-28 16:55:58 字数 4912 浏览 2 评论 0原文

我想使用 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;
}

问候, 桑迪普

I want to use libusb library for writing some test applications for USB.
Can any one please suggest how to set control transfers using usb_control_msg call?

I am getting bad descriptor error while running the following code.

#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;
}

Regards,
Sandeep

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜夜流光相皎洁 2025-01-04 16:55:58

我认为您的意思是 usb_control_msg() 返回“错误描述符”的错误代码。请澄清这是否不正确。

USB 控制传输有一些非常具体的格式化规则,如果您正在形成的数据包发送到任何兼容设备,它将在总线上返回请求错误/停顿。

您正在发送控制传输:

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

这应该被 USB 设备解释为 GET_STATUS 请求,因此 wLength 需要为 2,并且 bmRequestType 需要设置最高位,表明这是一个 IN 方向请求(从主机的角度)的视图)。这些内容均来自 www.usb.org 上 USB 规范 1.1/2.0/3.1 的第 9 章。

参数char *bytes(您的param.bytes)也需要是您正在进行的调用中的地址/指针。

用于测试的良好标准控制传输如下:

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

该请求将返回设备描述符的前 8 个字节,它对于所有状态下的每个 USB 设备都有效。

其他传输类型(批量、中断)没有这些严格的格式规则,并且可以更容易地开始。我想您已经解决了这个问题,因为这个问题已经发布很长一段时间了,但也许这个回复仍然会帮助其他人。

I think that you mean usb_control_msg() is returns an error code for "bad descriptor". Please clarify if this is incorrect.

USB control transfers have some very specific formatting rules, and if the packet you are forming is sent to any compliant device, it will return a request error / stall on the bus.

You are sending the control transfer:

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

this should be interpreted by the USB device as a GET_STATUS request, so wLength is required to be 2, and bmRequestType needs to have the top bit set, indicating this is an IN direction request (from the host's point of view). This is all from Chapter 9 of the USB specification 1.1/2.0/3.1 available at www.usb.org.

The parameter char *bytes (your param.bytes) also needs to be an address/pointer in the call you are making.

A good standard control transfer to test with would be:

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

This request will return the first 8 bytes of the Device Descriptor, it is valid for every USB device, in all states.

The other transfer types (bulk, interrupt) don't have these strict formatting rules, and can be an easier place to start. I'd imagine you have already moved past this issue, since the question has been posted for quite a while, but maybe this response will still help someone else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文