批量消息传输 USB Linux

Bulk message transfer USB Linux

我刚开始为 dds 生成器编写自己的 Linux 驱动程序。

我想在内核调用探测函数时向生成器写入 2 条批量消息。但是我不知道如何调用 usb_bulk_msg 函数。我希望你可以。

同步

static int dds_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
int retval = 0;

retval = usb_bulk_msg();

dev_info(&interface->dev, "DDS generator is now attached\n");
return 0;
}

内核是一个不言自明的项目,所以通常您可以在内核代码中找到正确的答案。

函数用法

include/linux/usb.h:在这里你可以看到这个函数的签名

extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
                        void *data, int len, int *actual_length,
                        int timeout);

drivers/usb/core/message.c: 在这里你可以看到这个函数的很好的描述(参数,return值,如何使用它)

/**
 * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion
 * @usb_dev: pointer to the usb device to send the message to
 * @pipe: endpoint "pipe" to send the message to
 * @data: pointer to the data to send
 * @len: length in bytes of the data to send
 * @actual_length: pointer to a location to put the actual length transferred
 *                 in bytes
 * @timeout: time in msecs to wait for the message to complete before
 *           timing out (if 0 the wait is forever)
 *
 * Context: !in_interrupt ()
 *
 * This function sends a simple bulk message to a specified endpoint
 * and waits for the message to complete, or timeout.
 *
 * Don't use this function from within an interrupt context, like a bottom half
 * handler.  If you need an asynchronous message, or need to send a message
 * from within interrupt context, use usb_submit_urb() If a thread in your
 * driver uses this call, make sure your disconnect() method can wait for it to
 * complete.  Since you don't have a handle on the URB used, you can't cancel
 * the request.
 *
 * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT ioctl,
 * users are forced to abuse this routine by using it to submit URBs for
 * interrupt endpoints.  We will take the liberty of creating an interrupt URB
 * (with the default interval) if the target is an interrupt endpoint.
 *
 * Return:
 * If successful, 0. Otherwise a negative error number. The number of actual
 * bytes transferred will be stored in the @actual_length parameter.
 *
 */

例子

如果您需要一些如何使用此功能的示例,您也可以在内核代码中找到它们,例如使用 LXR site.

如果您是USB驱动开发的新手,您可能也对一些教程感兴趣:

在评论中回答问题

when I plug in my generator, the kernel execute my driver but then the usbcore loads the usbhid driver, because the generator is an hid device and at the next time the usbcore does not execute my "driver".

我知道两种可能的解决方法:

  1. 使用 usbhid 驱动程序的“quirks”参数。

    将您设备的供应商 ID 和产品 ID 作为 quirks 参数提供给 usbhid 模块。您可以通过内核 cmdline 传递此参数。编辑 /etc/default/grub 文件,将类似 usbhid.quirks=0xdead:0xbeef:0x4 的内容添加到 GRUB_CMDLINE_LINUX_DEFAULT,然后执行:

    $ sudo update-grub
    

    然后重启。

  2. 使用 udev.

    使用 ignore_device 选项为您的设备创建 udev 规则。但是好像这个选项在新版本的udev中被移除了,所以你可能无法使用它。

详情:

[1] https://unix.stackexchange.com/questions/55495/prevent-usbhid-from-claiming-usb-device/55590#55590

[2]http://ubuntuforums.org/showthread.php?t=1175001&p=7548820#post7548820