usb_control_msgが完了するのに0.25秒かかるのはなぜですか?

usb_control_msgが完了するのに0.25秒かかるのはなぜですか?

通話を介してUSBデバイスに同期制御メッセージを送信していますusb_control_msg。完了するまでに0.25秒かかります。これが正常/予想されたものですか? USBポートはUSB 3.0です。このデバイスはCypress 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秒かかり、一部のメッセージはすぐに完了します。

ベストアンサー1

非同期メッセージが順次送信されるため、すぐに発行されると推測されますが、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");
}

警告する! ! ! :このコードは割り当てられたバッファを正しく解放しません。

おすすめ記事