Kernel
為什麼 usb_control_msg 需要 0.25 秒才能完成
我正在通過呼叫向 USB 設備發送同步控制消息
usb_control_msg
。完成需要 0.25 秒。這是正常的/預期的嗎?USB 埠為 USB 3.0。該器件是賽普拉斯 FX3 模組。對 Windows 系統(相同埠、設備、FX3 韌體)進行的類似測試在更短的時間內返回每條消息。在 Linux 中,我注意到發送的第一條消息需要 10 微秒才能完成,而接下來的 19 條左右則需要 0.25 秒才能完成。還有另一條消息會很快完成,然後是另外 19 條左右的消息會很慢。此外,我無法發送設置數據長度超過 8 個字節的控制消息。我將嘗試實現非同步消息,但最好知道是否可以針對同步呼叫改進這種行為。ktime_t start_time = ktime_get(); int ret = usb_control_msg(device, usb_sndctrlpipe(device, 0), 0, 0x40, 0, 0, &command_data_payload, 8, 5000); if (ret < 0) printk(KERN_ERR "Messaged failed: %d\n", ret); else printk("message took: %llu\n", ktime_get() - message_start_time);
更正:我不知道我在比較中使用的 Windows 應用程序是使用同步呼叫還是非同步呼叫。我一定會嘗試使用非同步呼叫來實現測試。
更新:使用非同步呼叫,消息發送得更快,但呼叫完成回調仍需要 0.25 秒。對於按順序發送的 20 條消息,其中 1 條在很短的時間內完成,其他的則每條耗時 0.25 秒。可能延遲是 FX3 USB 設備模組的功能。此外,在 Windows 上仔細檢查後,消息也大多需要 0.25 秒才能完成,其中一些完成得更快。
我猜是因為非同步消息是按順序發送的,很快就出去了,但是完成回調和來自 USB 設備的響應仍然需要 0.25 秒才能發生,延遲是因為 Cypress FX3 模組。我還包括非同步消息的程式碼。
static struct usb_ctrlrequest ctrl_request; static ktime_t last_time = 0; static void write_control_callback(struct urb *urb) { ktime_t now_time = ktime_get(); if (last_time != 0) printk("skel_write_bulk_callback: %llu\n", now_time - last_time); last_time = now_time; } static long send_command(uint8_t * command_data_payload) { int ret; struct urb * cUrb; void * buf; cUrb = usb_alloc_urb(0, GFP_KERNEL); if (!cUrb) return 1; buf = usb_alloc_coherent(device, 32, GFP_KERNEL, &cUrb->transfer_dma); if (!buf) return 1; memcpy(buf, command_data_payload, 32); ctrl_request.bRequest = 0; ctrl_request.bRequestType = 0x40; ctrl_request.wValue = 0; ctrl_request.wIndex = 0; ctrl_request.wLength = 32; usb_fill_control_urb(cUrb, device, usb_sndctrlpipe(device, 0), (unsigned char*)(&ctrl_request), buf, 32, skel_write_bulk_callback, NULL); ret = usb_submit_urb(cUrb, GFP_KERNEL); if (ret) printk("could not submit urb\n"); }
警告!!!:我沒有在這段程式碼中正確釋放分配的緩衝區。