linux usb 通信异常,如何解决?

问题遇到的现象和发生背景

host 和 device 使用usb 进行通信
host 和 device 的网卡ifconfig 看都正常,但是两端无法通信。
我们抓的usb 数据包只能看出,设备运行一段时间,host 只发送sof 包,不发送in / out 包。在这之前,所有的sop device都有相应,这是啥问题呀?

运行结果及报错内容

img

[2022/7/8 16:43:10] [ 2265.837082] ------------[ cut here ]------------
[2022/7/8 16:43:10] [ 2265.841720] WARNING: CPU: 0 PID: 0 at net/sched/sch_generic.c:319 dev_watchdog+0x2cc/0x2d8
[2022/7/8 16:43:10] [ 2265.849990] Modules linked in: cryptodev(O)
[2022/7/8 16:43:10] [ 2265.854191] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G           O    4.14.98 #1
[2022/7/8 16:43:10] [ 2265.861413] Hardware name: Freescale i.MX8DX MEK - NIO (DT)
[2022/7/8 16:43:10] [ 2265.866992] task: ffff000009934c00 task.stack: ffff000009920000
[2022/7/8 16:43:10] [ 2265.872919] PC is at dev_watchdog+0x2cc/0x2d8
[2022/7/8 16:43:10] [ 2265.877281] LR is at dev_watchdog+0x2cc/0x2d8
[2022/7/8 16:43:10] [ 2265.881641] pc : [<ffff000008a7324c>] lr : [<ffff000008a7324c>] pstate: 20000145
[2022/7/8 16:43:10] [ 2265.889039] sp : ffff000008003d90
[2022/7/8 16:43:10] [ 2265.892358] x29: ffff000008003d90 x28: 0000000000000020 
[2022/7/8 16:43:10] [ 2265.897675] x27: ffff000009925180 x26: ffff000009934c00 
[2022/7/8 16:43:10] [ 2265.902991] x25: 00000000ffffffff x24: ffff000009926000 
[2022/7/8 16:43:10] [ 2265.908308] x23: 0000000100077a12 x22: ffff800036a4c41c 
[2022/7/8 16:43:10] [ 2265.913625] x21: 0000000000000000 x20: ffff800036a4c000 
[2022/7/8 16:43:10] [ 2265.918942] x19: ffff800036897600 x18: 0000000000000010 
[2022/7/8 16:43:10] [ 2265.924258] x17: 0000ffff9f100fc0 x16: 0000000000000000 
[2022/7/8 16:43:10] [ 2265.929575] x15: ffffffffffffffff x14: 32342074756f2064 
[2022/7/8 16:43:10] [ 2265.934892] x13: 656d697420302065 x12: ffff000009929e78 
[2022/7/8 16:43:10] [ 2265.940209] x11: ffff0000083b3e80 x10: 72656874655f6364 
[2022/7/8 16:43:10] [ 2265.945525] x9 : 0000000000000015 x8 : 3a474f4448435441 
[2022/7/8 16:43:10] [ 2265.950842] x7 : 572056454454454e x6 : 00000000000098ba 
[2022/7/8 16:43:10] [ 2265.956159] x5 : 0000000000000001 x4 : 0000000000000002 
[2022/7/8 16:43:10] [ 2265.961475] x3 : 0000000000000000 x2 : 0000000000000040 
[2022/7/8 16:43:10] [ 2265.966792] x1 : ffff000009934c00 x0 : 0000000000000049 
[2022/7/8 16:43:10] [ 2265.972109] Call trace:
[2022/7/8 16:43:10] [ 2265.974562] Exception stack(0xffff000008003c50 to 0xffff000008003d90)
[2022/7/8 16:43:10] [ 2265.981010] 3c40:                                   0000000000000049 ffff000009934c00
[2022/7/8 16:43:10] [ 2265.988845] 3c60: 0000000000000040 0000000000000000 0000000000000002 0000000000000001
[2022/7/8 16:43:10] [ 2265.996683] 3c80: 00000000000098ba 572056454454454e 3a474f4448435441 0000000000000015
[2022/7/8 16:43:10] [ 2266.004520] 3ca0: 72656874655f6364 ffff0000083b3e80 ffff000009929e78 656d697420302065
[2022/7/8 16:43:10] [ 2266.012355] 3cc0: 32342074756f2064 ffffffffffffffff 0000000000000000 0000ffff9f100fc0
[2022/7/8 16:43:10] [ 2266.020192] 3ce0: 0000000000000010 ffff800036897600 ffff800036a4c000 0000000000000000
[2022/7/8 16:43:10] [ 2266.028028] 3d00: ffff800036a4c41c 0000000100077a12 ffff000009926000 00000000ffffffff
[2022/7/8 16:43:10] [ 2266.035864] 3d20: ffff000009934c00 ffff000009925180 0000000000000020 ffff000008003d90
[2022/7/8 16:43:10] [ 2266.043696] 3d40: ffff000008a7324c ffff000008003d90 ffff000008a7324c 0000000020000145
[2022/7/8 16:43:10] [ 2266.051535] 3d60: ffff000008f9ef50 0000000000000000 0000ffffffffffff 00000000000000c0
[2022/7/8 16:43:10] [ 2266.059369] 3d80: ffff000008003d90 ffff000008a7324c
[2022/7/8 16:43:10] [ 2266.064256] [<ffff000008a7324c>] dev_watchdog+0x2cc/0x2d8
[2022/7/8 16:43:10] [ 2266.069668] [<ffff000008125ba4>] call_timer_fn.isra.5+0x24/0x80
[2022/7/8 16:43:10] [ 2266.075589] [<ffff000008125ca4>] expire_timers+0xa4/0xb0
[2022/7/8 16:43:10] [ 2266.080905] [<ffff000008125d64>] run_timer_softirq+0xb4/0x170
[2022/7/8 16:43:10] [ 2266.086659] [<ffff000008081204>] __do_softirq+0x124/0x218
[2022/7/8 16:43:10] [ 2266.092062] [<ffff0000080cb648>] irq_exit+0xd0/0xf0
[2022/7/8 16:43:10] [ 2266.096946] [<ffff00000810f278>] __handle_domain_irq+0x60/0xb8
[2022/7/8 16:43:10] [ 2266.102781] [<ffff000008080fe0>] gic_handle_irq+0x78/0x174
[2022/7/8 16:43:10] [ 2266.108270] Exception stack(0xffff000009923dd0 to 0xffff000009923f10)
[2022/7/8 16:43:10] [ 2266.114717] 3dc0:                                   0000000000000000 0000000000000000
[2022/7/8 16:43:10] [ 2266.122556] 3de0: 0000000000000001 0000000000000000 ffff000009916108 ffff000009923f00
[2022/7/8 16:43:10] [ 2266.130393] 3e00: 0000800034649000 0000000000000000 0000000000000002 ffff000009923e90
[2022/7/8 16:43:10] [ 2266.138228] 3e20: 0000000000000870 0000000000000000 0000000000000001 0000000000000000
[2022/7/8 16:43:10] [ 2266.146065] 3e40: 0000ffff9f349c38 0000ffff9f347dd8 ffff000008217408 0000ffff9f100fc0
[2022/7/8 16:43:10] [ 2266.153899] 3e60: 00000000000000b6 ffff000009912018 ffff000009929000 ffff000009929000
[2022/7/8 16:43:10] [ 2266.161737] 3e80: ffff00000991bc38 ffff000009929f18 0000000000000000 0000000000000000
[2022/7/8 16:43:10] [ 2266.169573] 3ea0: ffff000009934c00 0000000000000400 0000000081290018 ffff000009923f10
[2022/7/8 16:43:10] [ 2266.177409] 3ec0: ffff000008084e94 ffff000009923f10 ffff000008084e98 0000000000000145
[2022/7/8 16:43:10] [ 2266.185246] 3ee0: 0000000000000000 00000000bde74b80 ffffffffffffffff ffff000008135f74
[2022/7/8 16:43:10] [ 2266.193078] 3f00: ffff000009923f10 ffff000008084e98
[2022/7/8 16:43:10] [ 2266.197962] [<ffff000008082a30>] el1_irq+0xb0/0x124
[2022/7/8 16:43:10] [ 2266.202845] [<ffff000008084e98>] arch_cpu_idle+0x10/0x18
[2022/7/8 16:43:10] [ 2266.208163] [<ffff0000081012a0>] do_idle+0x120/0x1e0
[2022/7/8 16:43:10] [ 2266.213132] [<ffff0000081014fc>] cpu_startup_entry+0x24/0x28
[2022/7/8 16:43:10] [ 2266.218798] [<ffff000008c34318>] rest_init+0xd0/0xe0
[2022/7/8 16:43:10] [ 2266.223775] [<ffff000009090b58>] start_kernel+0x380/0x394
[2022/7/8 16:43:10] [ 2266.229173] ---[ end trace 3e5cf4612cfdf364 ]---
[2022/7/8 16:43:10] [ 2266.233839]  xhci-cdns3: Cancel URB ffff80003bce2a00, dev 1, ep 0xf, starting at offset 0x96089840
[2022/7/8 16:43:10] [ 2266.242826]  xhci-cdns3: // Ding dong!
[2022/7/8 16:43:10] [ 2266.246602]  xhci-cdns3: Stopped on Transfer TRB for slot 1 ep 29
[2022/7/8 16:43:10] [ 2266.252711]  xhci-cdns3: Removing canceled TD starting at 0x96089840 (dma).
[2022/7/8 16:43:10] [ 2266.259678]  xhci-cdns3: Finding endpoint context
[2022/7/8 16:43:10] [ 2266.264385]  xhci-cdns3: Cycle state = 0x1
[2022/7/8 16:43:10] [ 2266.268485]  xhci-cdns3: New dequeue segment = ffff800036a61980 (virtual)
[2022/7/8 16:43:10] [ 2266.275278]  xhci-cdns3: New dequeue pointer = 0x96089850 (DMA)
[2022/7/8 16:43:10] [ 2266.281208]  xhci-cdns3: Set TR Deq Ptr cmd, new deq seg = ffff800036a61980 (0x96089000 dma), new deq ptr = ffff00000a125850 (0x96089850 dma), new cycle = 1
[2022/7/8 16:43:10] [ 2266.295218]  xhci-cdns3: // Ding dong!
[2022/7/8 16:43:10] [ 2266.298989]  xhci-cdns3: Successful Set TR Deq Ptr cmd, deq = @96089850
[2022/7/8 16:43:10] [ 2266.305646]  xhci-cdns3: Cancel URB ffff80003bce2100, dev 1, ep 0xf, starting at offset 0x96089850
[2022/7/8 16:43:10] [ 2266.314619]  xhci-cdns3: // Ding dong!
[2022/7/8 16:43:10] [ 2266.318382]  xhci-cdns3: Stopped on Transfer TRB for slot 1 ep 29
[2022/7/8 16:43:10] [ 2266.324490]  xhci-cdns3: Removing canceled TD starting at 0x96089850 (dma).
[2022/7/8 16:43:10] [ 2266.331460]  xhci-cdns3: Finding endpoint context
[2022/7/8 16:43:10] [ 2266.336169]  xhci-cdns3: Cycle state = 0x1
[2022/7/8 16:43:10] [ 2266.340271]  xhci-cdns3: New dequeue segment = ffff800036a61980 (virtual)
[2022/7/8 16:43:10] [ 2266.347065]  xhci-cdns3: New dequeue pointer = 0x96089860 (DMA)
[2022/7/8 16:43:10] [ 2266.352993]  xhci-cdns3: Set TR Deq Ptr cmd, new deq seg = ffff800036a61980 (0x96089000 dma), new deq ptr = ffff00000a125860 (0x96089860 dma), new cycle = 1
[2022/7/8 16:43:10] [ 2266.367003]  xhci-cdns3: // Ding dong!
[2022/7/8 16:43:10] [ 2266.370763]  xhci-cdns3: Successful Set TR Deq Ptr cmd, deq = @96089860
[2022/7/8 16:43:10] [ 2266.377405]  xhci-cdns3: Cancel URB ffff80003bd9ee00, dev 1, ep 0xf, starting at offset 0x96089860
[2022/7/8 16:43:10] [ 2266.386377]  xhci-cdns3: // Ding dong!
[2022/7/8 16:43:10] [ 2266.390140]  xhci-cdns3: Stopped on Transfer TRB for slot 1 ep 29
[2022/7/8 16:43:10] [ 2266.396248]  xhci-cdns3: Removing canceled TD starting at 0x96089860 (dma).
[2022/7/8 16:43:10] [ 2266.403219]  xhci-cdns3: Finding endpoint context
[2022/7/8 16:43:10] [ 2266.407928]  xhci-cdns3: Cycle state = 0x1
[2022/7/8 16:43:10] [ 2266.412030]  xhci-cdns3: New dequeue segment = ffff800036a61980 (virtual)
[2022/7/8 16:43:10] [ 2266.418822]  xhci-cdns3: New dequeue pointer = 0x96089870 (DMA)
[2022/7/8 16:43:10] [ 2266.424752]  xhci-cdns3: Set TR Deq Ptr cmd, new deq seg = ffff800036a61980 (0x96089000 dma), new deq ptr = ffff00000a125870 (0x96089870 dma), new cycle = 1

usb设备需要驱动?

CDC 网卡驱动

根据您提供的信息,可能是因为 host 没有正确地向设备发送数据包导致通信失败。以下是一些可能的解决方法:

  1. 确认您的驱动程序是否正确地实现了 struct usb_driver 结构体中的 .probe() 和 .disconnect() 函数。这两个函数分别在设备连接和断开时被调用,可以在其中执行相应的初始化和清理工作。

  2. 确认您的驱动程序是否正确地实现了 struct file_operations 结构体中的 .read() 和 .write() 函数。这两个函数分别在用户空间程序向设备读取和写入数据时被调用,可以在其中执行相应的数据传输操作。

下面是一个简单的 USB 通信示例,其中使用的是 Linux 内核自带的 USB HID 驱动程序。该示例可以在 host 端向设备发送数据,并从设备接收响应。
设备端代码:

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

static const struct usb_device_id my_hid_table[] = {
    { USB_INTERFACE_INFO(
        USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
        USB_INTERFACE_PROTOCOL_KEYBOARD) },
    {}
};

MODULE_DEVICE_TABLE(usb, my_hid_table);

static int my_hid_probe(struct usb_interface *intf,
                        const struct usb_device_id *id)
{
    printk(KERN_INFO "my_hid_probe\n");
    return 0;
}

static void my_hid_disconnect(struct usb_interface *intf)
{
    printk(KERN_INFO "my_hid_disconnect\n");
}

static struct usb_driver my_hid_driver = {
    .name = "my_hid",
    .probe = my_hid_probe,
    .disconnect = my_hid_disconnect,
    .id_table = my_hid_table,
};

module_usb_driver(my_hid_driver);
MODULE_LICENSE("GPL");

主机端代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/hiddev.h>

#define HID_DEV "/dev/usb/hiddev0"

int main()
{
    int fd, ret;
    char buf[8];

    // 打开 HID 设备
    fd = open(HID_DEV, O_RDWR);
    if (fd < 0) {
        perror("Failed to open HID device");
        return -1;
    }

    // 发送数据包
    memset(buf, 0, sizeof(buf));
    buf[0] = 0x01;  // 报告 ID
    buf[1] = 0x02;  // 数据字节 1
    buf[2] = 0x03;  // 数据字节 2
    ret = write(fd, buf, sizeof(buf));
    if (ret < 0) {
        perror("Failed to write data to HID device");
        close(fd);
        return -1;
    }

    // 接收响应包
    memset(buf, 0, sizeof(buf));
    ret = read(fd, buf, sizeof(buf));
    if (ret < 0) {
        perror("Failed to read data from HID device");
        close(fd);
        return -1;
    }
    printf("Received response: %02X %02X %02X %02X %02X %02X %02X %02X\n",
           buf[0], buf[1], buf[2], buf[3],
           buf[4], buf[5], buf[6], buf[7]);

    // 关闭 HID 设备
    close(fd);
    return 0;
}

在上述示例中,设备端代码实现了一个简单的 USB HID 驱动程序,主机端代码向 HID 设备发送数据包,并等待设备返回响应包。您可以根据自己的需求进行相应修改,例如使用 Bulk Transfer 替代 HID Transfer 进行数据传输。注意,在调试过程中建议打开内核 debug 日志以获取更详细的信息