简体   繁体   English

在Linux上读取USB批量消息

[英]read USB bulk message on Linux

I am trying lessons on USB http://www.linuxforu.com/2011/12/data-transfers-to-from-usb-devices/ and stuck with the problem - while reading, usb_bulk_msg returns error 22 - Invalid argument. 我正在尝试在USB http://www.linuxforu.com/2011/12/data-transfers-to-from-usb-devices/上的课程,但遇到了问题-阅读时,usb_bulk_msg返回错误22-无效参数。 Write operation succeeds. 写操作成功。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>

#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
#define BULK_EP_OUT 0x01
#define BULK_EP_IN 0x82
#define MAX_PKT_SIZE 512

static struct usb_device *device;
static struct usb_class_driver class;
static unsigned char bulk_buf[MAX_PKT_SIZE];

static int pen_open(struct inode *i, struct file *f)
{
    return 0;
}
static int pen_close(struct inode *i, struct file *f)
{
    return 0;
}
static ssize_t pen_read(struct file *f, char __user *buf, size_t cnt, loff_t *off)
{
    int retval;
    int read_cnt;

    /* Read the data from the bulk endpoint */
    retval = usb_bulk_msg(device, usb_rcvbulkpipe(device, BULK_EP_IN),
            bulk_buf, MAX_PKT_SIZE, &read_cnt, 5000);
    if (retval)
    {
        printk(KERN_ERR "Bulk message returned %d\n", retval);
        return retval;
    }
    if (copy_to_user(buf, bulk_buf, MIN(cnt, read_cnt)))
    {
        return -EFAULT;
    }

    return MIN(cnt, read_cnt);
}
static ssize_t pen_write(struct file *f, const char __user *buf, size_t cnt, loff_t *off)
{
    int retval;
    int wrote_cnt = MIN(cnt, MAX_PKT_SIZE);

    if (copy_from_user(bulk_buf, buf, MIN(cnt, MAX_PKT_SIZE)))
    {
        return -EFAULT;
    }

    /* Write the data into the bulk endpoint */
    retval = usb_bulk_msg(device, usb_sndbulkpipe(device, BULK_EP_OUT),
            bulk_buf, MIN(cnt, MAX_PKT_SIZE), &wrote_cnt, 5000);
    if (retval)
    {
        printk(KERN_ERR "Bulk message returned %d\n", retval);
        return retval;
    }

    return wrote_cnt;
}

static struct file_operations fops =
{
    .open = pen_open,
    .release = pen_close,
    .read = pen_read,
    .write = pen_write,
};

static int pen_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
    int retval;

    device = interface_to_usbdev(interface);

    class.name = "usb/pen%d";
    class.fops = &fops;
    if ((retval = usb_register_dev(interface, &class)) < 0)
    {
        /* Something prevented us from registering this driver */
        err("Not able to get a minor for this device.");
    }
    else
    {
        printk(KERN_INFO "Minor obtained: %d\n", interface->minor);
    }

    return retval;
}

static void pen_disconnect(struct usb_interface *interface)
{
    usb_deregister_dev(interface, &class);
}

/* Table of devices that work with this driver */
static struct usb_device_id pen_table[] =
{
    { USB_DEVICE(0x058F, 0x6387) },
    {} /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, pen_table);

static struct usb_driver pen_driver =
{
    .name = "pen_driver",
    .probe = pen_probe,
    .disconnect = pen_disconnect,
    .id_table = pen_table,
};

static int __init pen_init(void)
{
    int result;

    /* Register this driver with the USB subsystem */
    if ((result = usb_register(&pen_driver)))
    {
        err("usb_register failed. Error number %d", result);
    }
    return result;
}

static void __exit pen_exit(void)
{
    /* Deregister this driver with the USB subsystem */
    usb_deregister(&pen_driver);
}

module_init(pen_init);
module_exit(pen_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anil Kumar Pugalia <email_at_sarika-pugs_dot_com>");
MODULE_DESCRIPTION("USB Pen Device Driver");  

There could be many possible reasons for this error but in my case it happened that the BULK_EP address was wrong. 发生此错误的原因可能有很多,但在我的情况下,发生了BULK_EP地址错误的情况。 I recommend setting up your endpoint addresses in the probe function rather than hard-coding them. 我建议您在探测功能中设置端点地址,而不是对其进行硬编码。 Feel free to refer the below code to setup bulk endpoint addresses. 请随意参考以下代码来设置批量端点地址。

static void
set_bulk_address (
    struct my_device *dev,
    struct usb_interface *interface)
{
    struct usb_endpoint_descriptor *endpoint;
    struct usb_host_interface *iface_desc;
    int i;

    iface_desc = interface->cur_altsetting;
    for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
        endpoint = &iface_desc->endpoint[i].desc;

        /* check for bulk endpoint */
        if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) 
            == USB_ENDPOINT_XFER_BULK){

            /* bulk in */
            if(endpoint->bEndpointAddress & USB_DIR_IN) {
                dev->bulk_in_add = endpoint->bEndpointAddress;
                dev->bulk_in_size = endpoint->wMaxPacketSize;
                dev->bulk_in_buffer = kmalloc(dev->bulk_in_size,
                                GFP_KERNEL);
                if (!dev->bulk_in_buffer)
                    print("Could not allocate bulk buffer");
            }

            /* bulk out */
            else
                dev->bulk_out_add = endpoint->bEndpointAddress; 
        }
    }
}

As you may notice, I have defined my own device struct to hold the endpoint information. 您可能会注意到,我已经定义了自己的设备结构来保存端点信息。 Here is my struct definition 这是我的结构定义

struct my_device {
    struct usb_device   *udev;      /* usb device for this device */
    struct usb_interface    *interface; /* interface for this device */
    unsigned char       minor;      /* minor value */
    unsigned char *     bulk_in_buffer; /* the buffer to in data */
    size_t          bulk_in_size;   /* the size of the in buffer */
    __u8            bulk_in_add;    /* bulk in endpoint address */
    __u8            bulk_out_add;   /* bulk out endpoint address */
    struct kref     kref;       /* module references counter */
};

The error is coming because you have to mention the correct bulk endpoints as per your usb device not the ones given in the example code. 由于您必须根据USB设备(而不是示例代码中给出的)提及正确的批量端点,因此出现错误。 For that you can either check /sys/kernel/debug/usb/devices file or /proc/bus/usb/devices . 为此,您可以检查/sys/kernel/debug/usb/devices文件或/proc/bus/usb/devices In the file check the section containing your device's vendorId and productId and in that section check the E segment for endpoints. 在文件中,检查包含设备的vendorId和productId的部分,然后在该部分中检查端点的E段。 In that segment the one with (I) will be BULK_EP_IN value and the one with (O) will be the value for BULK_EP_OUT . 在该段中,带有(I)将是BULK_EP_IN值,带有(O)将是BULK_EP_OUT的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在USB设备Linux内核模块内调用USB批量发送消息时出现问题 - Problems when calling USB bulk send message inside USB device Linux Kernel module 多个批量URB接收数据到USB LINUX中的特定URB - Multiple bulk URB receive data to particular URB in USB LINUX Linux下的USB批量传输超时,而它在Windows下工作 - usb bulk transfer timeout under Linux while it works under Windows 读取 USB 调制解调器的健康/状态 - Linux - Read the Health/Status of USB Modem - Linux linux命令读取RFID usb端口 - linux command to read RFID usb port USB大容量读取超时,协议分析仪称已传送数据 - USB bulk read times out, protocol analyzer says data delivered Linux:如何从用户空间通过 cdc-adm 驱动程序的 USB 批量端点传输数据 - Linux : how to transfer data through USB bulk endpoint of cdc-adm driver from userspace Linux usb 批量传输内核驱动程序和硬件环回的性能非常差(~0.4MB/s) - very poor performance (~0.4MB/s) with Linux usb bulk transfer kernel driver and hardware loopback 如何(可靠地)读取嵌入式(无头)Linux中的USB条形码扫描器? - How to (reliably) read USB barcode scanner in embedded (headless) Linux? 将DOS程序移植到linux以通过usb读/写串口 - Porting DOS program to linux to read/write serial port over usb
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM