You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写libusb 1.0代码读取USB鼠标原始数据?

求助:libusb 1.0读取USB鼠标数据时仅收到回调超时,无法获取中断传输数据

我是USB和libusb的初学者,正在寻找可读取USB鼠标数据的libusb 1.0代码。网上找到的示例代码无法满足需求,相关讨论提到鼠标无法接收数据。以下是我自己的代码:

主函数代码

int main(void)
{
  libusb_device **devs;
  int r;
  int numread;
  ssize_t cnt;
  int counter = 0;
  
  r = libusb_init(&ctx);
  //  r = libusb_init_context(/*ctx=*/NULL, /*options=*/NULL, /*num_options=*/0);  

  if (r < 0)
    return r;

  libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
  
  libusb_set_debug(ctx, 3); // debug level 3 //

  cnt = libusb_get_device_list(ctx, &devs); // returns device list //
  if (cnt < 0)
    {
      libusb_exit(NULL);
      return (int) cnt;
    }
  
  print_devs(devs);

  libusb_free_device_list(devs, 1);

 // open device //
  handle = libusb_open_device_with_vid_pid(ctx, USB_VENDOR_ID, USB_PRODUCT_ID);

  if (!handle)
    {
      perror("device not found");
      return 1;
    }

  // set auto detach/attach kernel driver //

  r = libusb_set_auto_detach_kernel_driver(handle, 1); // enable = 1 //

  //  r = libusb_detach_kernel_driver(handle, 1); // enable = 1 //

  printf("auto_detach result = %d\n", r);
  
  // claim interface //
  r = libusb_claim_interface(handle, 0);

  if (r < 0)
    {
      fprintf(stderr, "usb_claim_interface error %d\n", r);
      return 2;
    }
  
  printf("Interface claimed\n");

// allocate transfer of data IN (IN to host PC from USB-device)
  transfer_in = libusb_alloc_transfer(1);

  if (transfer_in == NULL)
    {
      printf("ERROR allocating usb transfer.\n");
    }

  // Note: in_buffer is where input data is written //
  //  libusb_fill_bulk_transfer(transfer_in, handle, USB_ENDPOINT_IN, in_buffer, LEN_IN_BUFFER, callback_in, NULL, 0); // NULL for no user data //
  libusb_fill_interrupt_transfer(transfer_in, handle, USB_ENDPOINT_IN, in_buffer, 1, callback_in, NULL, 1); // NULL for no user data, 1 is TIMEOUT //

  // submit next transfer //
  r = libusb_submit_transfer(transfer_in);

  if (r < 0)
    {
      printf("submit transter result = %d\n", r);
    }
  
  // connect SIGINT to function sigint_handler() //
  if (signal(SIGINT, sigint_handler) == SIG_ERR)
    {
      printf("ERROR: Cannot Connect to SIGINT!");
    }

  // Block SIGALRM in the main thread //
  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, SIGALRM);
  pthread_sigmask(SIG_BLOCK, &sigset, NULL);
  
  printf("WAITING...\n");

  while (exitprogram == 0)
    {
      printf("exitprogram = %d\n", exitprogram);
      
      // waiting //
      //      r = libusb_handle_events_completed(ctx, NULL);
      r = libusb_handle_events(ctx);
      if (r < 0)
    {
      printf("ERROR at events handling\n");
      break;
    }
    }

printf("exitprogram = %d\n", exitprogram);
  
  if (transfer_in)
    {
      r = libusb_cancel_transfer(transfer_in);
      if (r == 0)
    {
      printf("transfer_in successfully cancelled.\n");
    }
      else
    {
      printf("ERROR cancelling transfer\n");
    }
    }

  // close device usb handle //
  
  libusb_close(handle);
  
  libusb_exit(ctx);
  
  return 0;
}

回调函数与信号处理函数代码

// called when data for in_buffer is AVAILABLE //
void callback_in(struct libusb_transfer *transfer)
{
  switch (transfer->status)
    {
      case LIBUSB_TRANSFER_COMPLETED:
        {
            // Success here, data transfered are inside 
            // xfr->buffer
            // and the length is
            // xfr->actual_length
      
          printf("LIBUSB_TRANSFER_COMPLETED\n");
          break;
        }
      case LIBUSB_TRANSFER_CANCELLED:
        {
          printf("LIBUSB_TRANSFER_CANCELLED\n");
          break;
        }
      case LIBUSB_TRANSFER_NO_DEVICE:
        {
          printf("LIBUSB_TRANSFER_NO_DEVICE\n");
          break;
        }
      case LIBUSB_TRANSFER_TIMED_OUT:
        {
          printf("LIBUSB_TRANSFER_TIMED_OUT\n");
          break;
        }
      case LIBUSB_TRANSFER_ERROR:
        {
          printf("LIBUSB_TRANSFER_ERROR\n");
          break;
        }
      case LIBUSB_TRANSFER_STALL:
        {
          printf("LIBUSB_TRANSFER_STALL\n");
          break;
        }
      case LIBUSB_TRANSFER_OVERFLOW:
        {
          printf("LIBUSB_TRANSFER_OVERFLOW\n");
          break;
        }
      break;
    }

  printf("transfer flags = %b\n", transfer->flags);

  printf("transfer actual length = %d\n", transfer->actual_length);
  printf("transfer data = %d\n", *(transfer->buffer + 0));

  totalbytes = totalbytes + transfer->actual_length;

  // submit next transfer //
  libusb_submit_transfer(transfer_in);
}

// *** sigint_handler *** //
// note that the SIGINT interupts the main thread //
void sigint_handler(int signo)
{
  write(fileno(stderr), "\nCtrl-C Interrupt Detected.\n", 28);

  exitprogram = 1;
}

目前的问题是:我完全无法收到任何USB中断传输,仅能收到回调超时。恳请各位提供帮助!


内容的提问来源于stack exchange,提问作者Christos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:54:51