如何让在Linux USB的URB信息 [英] how to get usb's urb info in linux

查看:426
本文介绍了如何让在Linux USB的URB信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让USB记忆棒的URB的信息。我写这样如下:

I'm try to get usb stick's urb info. And I write like follows:

#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <usb.h>
/* #include <stropts.h> */
/* #include <inttypes.h> */
#include <linux/usbdevice_fs.h>
/* #include <asm/byteorder.h> */
/* #include <linux/usb/ch9.h> */
#define USBDEVFS_REAPURB           _IOW('U', 12, void *)
int main(int argc, char *argv[])
{ 
  int fd;
  int result;
  int i;
  struct usbdevfs_urb * receive;
  receive = malloc(sizeof (struct usbdevfs_urb));

  bzero(receive, sizeof (struct usbdevfs_urb));

  char file[30];
  strncpy (file, argv[1], 30);

  if ((fd = open(file, O_RDWR)) < 0)
    {
      printf("failed to open device: %s, \n error: %s \n", file, strerror(errno));
    }
  else 
    {
      printf ("Open successed: Device: %s\n", file);
      for (i = 0; i < 1000; ++i)
        {
          printf ("polling...\n");
          result = ioctl(fd, USBDEVFS_REAPURB, receive);
            if (result < 0)
              {
                printf ("Error!  : ioctl returned : %d\n errno =%s\n", result, strerror(errno));
                break;
              }
          printf ("The %d th time ok.\n", i + 1);
          usleep(2000);
        }
    }
  close(fd);
  return 0;
}

我可以编译它。但是,当我运行它,它说是无效的说法。
那么,什么是我错了?

I can compile it. But when I run it it said that Invalid argument. So, what's wrong with me?

推荐答案

我结束了一个类似的问题 - 所以这里是我的笔记......除了这些问题至今在评论中指出,我认为主要的问题同OP code是:

I ended up with a similar problem - so here are my notes... Besides the problems pointed out so far in comments, I think the main issues with the OP code are:


  1. 您不能只是收获一个URB;你首先必须提交一个(读或写)URB,那么你收获它

  2. 您不能只是打开 A 文件,您得到了来自命令行参数(<$ C $ PATH 字符串C>的argv [1] ),并获得一个文件描述符有效URB 的ioctl

  1. You cannot just "reap" a URB; you first have to "submit" a (read or write) URB, then you "reap" it
  2. You cannot just open a file string that you got as path from command line arguments (argv[1]), and obtain a file descriptor valid for URB ioctl

至于1,看也许<一个href=\"http://stackoverflow.com/questions/7964315/user-mode-usb-isochronous-transfer-from-device-to-host\">c - 从设备到主用户模式USB同步传输

As for 1, see maybe c - User mode USB isochronous transfer from device-to-host

此外,一旦我填补这个结构我是正确的思维,我需要调用如下结果
   INT retSubmit =的ioctl(FD,USBDEVFS_SUBMITURB,&安培; usbRequest); 结果
  然后一旦提交我可以等用结果来完成请求
   USBDEVFS_REAPURBNDELAY

Also, once I have filled this structure am I right in thinking I need to call the following:
int retSubmit = ioctl( fd, USBDEVFS_SUBMITURB, &usbRequest );
and then once submitted I can wait for the request to complete using
USBDEVFS_REAPURBNDELAY

[的Linux-USB用户] USBFS URB收获的问题。 - MARC

常规,并调用它,whidch我用提交URB如下:结果
  ...结果
  提交URB工作正常。这是我尝试收割:结果
  ...

The routine, and the call to it, whidch I use to submit the URB are as follows:
...
Submitting the URB works fine. This is how I try to reap it:
...

linux.usb.devel - 回复:usbdevfs问题(和其他...) - 味精#00167

是的,你提交批量型usbdevfs_urb到中断端点。
  它得到的数据一个数据包。您可以提交多是那些会
  排队。我猜'收获'是读指针,不喜欢严峻
  收割者(尽管也许是...:)

Yes, you submit a BULK type usbdevfs_urb to the interrupt endpoint. It gets one packet of data. You can submit multiple ones that will queue up. and I'm guessing 'reap' is REAd Pointer, not like the grim reaper (although maybe it is...:)

我的认为的(但我不知道100%)认为,提交和收获等同于提交和完成作为的虚拟USB分析仪 - 教程

I think (but I'm not sure 100%) that "submit" and "reap" are equivalent to "submit" and "completion" as noted in Virtual USB Analyzer - Tutorial.

至于2.去 ​​- 这取决于种类的设备。举例来说,如果一个Arduino Duemillanove,具有FT232 USB串口芯片,连接到Linux的PC - 将自动加载 ftdi_sio 内核驱动程序,这反过来又负荷 usbserial 驱动程序,然后创建文件(设备节点)的/ dev / ttyUSB0 。因此,Linux的会看到这个文件,充其量作为一个普通的串行口 - 不是必然相关的URB请求(我想类似的东西也适用于USB闪存thumbdrives);后来我得到了相同的错误OP,试图调用OP code。与的/ dev / ttyUSB0 的参数时。

As far as the 2. goes - it depends on the kind of the device. For instance, if you connect an Arduino Duemillanove, which has an FT232 USB serial chip, to a Linux PC - that will automatically load the ftdi_sio kernel driver, which in turn loads usbserial driver, which then creates the file (device node) /dev/ttyUSB0. Thus, Linux would see this file, at best, as a plain serial port - not something necessarily related to a URB request (I guess something similar goes for USB flash thumbdrives); and I was getting the same error as OP, when trying to call the OP code with an argument of /dev/ttyUSB0.

获取该文件描述符是有些困难,因为它是有点难以追查的例子:

Obtaining this file descriptor is somewhat difficult, as it's kinda hard to track down examples:

回复:有USBDEVFS访问USB设备 - MARC

在周五,2006年5月05,在下午4时45分三十秒-0400,丹尼Budik写道:结果
  >我如何使用原始USBFS?我试图在/ dev /巴士/ USB文件读取搜索
  在使用错误的地址已经 - >并得到了绑定。

On Fri, May 05, 2006 at 04:45:30PM -0400, Danny Budik wrote:
> How do I use the "raw" usbfs? I tried reading from the /dev/bus/usb file
> and got a bind - address already in use error.

怎么看待的libusb是对于如何做一个很好的例子来实现。结果
  该人士$ ​​C $ C到'的lsusb还可以帮助你在这里。

Look at how libusb is implemented for a good example of how to do this.
The source code to 'lsusb' will also help you out here.

Linux内核文档/ USB / proc_usb_info.txt

注意:文件系统已经从usbdevfs到
改名
          USBFS,以减少混乱与devfs的。你可能结果
          仍然可以看到引用到旧usbdevfs的名字。

NOTE: The filesystem has been renamed from "usbdevfs" to
"usbfs", to reduce confusion with "devfs". You may
still see references to the older "usbdevfs" name.

我基本上是从code开始在 [讨论-gnuradio对于fusb_linux新的实现不分配/释放,并试图修改OP code,因此具有一个Arduino Duemillanove工作。问题是,它使用旧的的libusb-0.1 code,其中有头和功能的一些不同的名字;例如的libusb-0.1 拥有的的libusb / usbi.h ,而较新的的libusb-1.0 拥有的的libusb / libusbi.h 。在本质上,的libusb 函数可用于获得适当的文件描述符。

I basically started from the code in [Discuss-gnuradio] New implementation for fusb_linux without allocs/frees, and tried to modify the OP code so it works with an Arduino Duemillanove. The problem is that it uses the older libusb-0.1 code, which has some different names of headers and functions; e.g. libusb-0.1 has libusb/usbi.h, while the newer libusb-1.0 has libusb/libusbi.h. In essence, libusb functions can be used to obtain the proper file descriptor.

修改后的OP code是下面,让我们说,我们把它叫做 testu.c 。我测试过它在Ubuntu纳蒂 - 首先,连接Arduino的Duemillanove,其中挂钩 ftdi_sio 驱动程序(这可以在终端进行检查与尾 - F /无功/ log / syslog的)。因此,首先,去掉自动上钩驱动程序(的libusb 并不需要它来与设备对话,并有可能它会干扰;注意删除后,的/ dev / ttyUSB0 文件不存在了):

The modified OP code is below, let's say we call it testu.c. I've tested it on Ubuntu Natty - first, connect the Arduino Duemillanove, which hooks the ftdi_sio driver (this can be checked in terminal with tail -f /var/log/syslog). So, to begin with, remove the auto-hooked driver (libusb doesn't need it to talk to the device, and it's possible it could interfere; note after removal, /dev/ttyUSB0 file doesn't exist anymore):

sudo modprobe -r ftdi_sio   # this also removes usbserial 
lsmod | grep ftdi           # make sure ftdi_sio isn't listed by lsmod

然后,我们将通过的libusb 使用USB供应商/产品ID连接到设备;找到它,使用的lsusb

Then, we will use the USB vendor/product ID to connect to the device via libusb; to find it, use lsusb:

$ lsusb | grep FT
Bus 002 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC

的VID:PID 0403:6001 在硬codeD testu.c ;然后我们就可以建立并运行它。请注意, testu 程序必须跑了作为根(通过须藤) - 其他的libusb 将不能与设备进行通信:

The VID:PID 0403:6001 is hardcoded in testu.c; then we can build and run it. Note that the testu program has to be ran as root (via sudo) - else libusb won't be able to communicate with the device:

$ gcc -o testu -Wall -g testu.c `pkg-config --libs --cflags libusb-1.0`
testu.c:23:1: warning: ‘fd_from_usb_dev_handle’ defined but not used

$ sudo ./testu
First
Second 0x8B4B4F0
Open successed: Device: 0403:6001 6
polling...
The 1 th time ok.
polling...
The 2 th time ok.
polling...
The 3 th time ok.
polling...
The 4 th time ok.
polling...
The 5 th time ok.
polling...
The 6 th time ok.
polling...
The 7 th time ok.
polling...
The 8 th time ok.
polling...
The 9 th time ok.
polling...
The 10 th time ok.

在code提交一个写请求(端点0×02),然后收获它 - 我可以看到RX LED闪烁Arduino上 - 这意味着一些数据没有得到它,符合市场预期。然而,并非远远超过出现这种情况 - 所以我不知道,如果code回答获取USB的URB信息的一部分:)但是,它确实显示怎样可以得到的文件描述符,所以生的ioctl s时,可以工作 - 通过的libusb 虽然(你可能必须通过的libusb 源越挖越深,为了离不开libusb的相同)。

The code submits a write request (on endpoint 0x02), then reaps it - and I can see the RX led blink on the Arduino - meaning some data does get to it, as expected. However, not much more than that happens - so I'm not sure if the code answers the "get usb's urb info" part :) However, it does show how the file descriptor can be obtained, so the raw ioctls can work - albeit via libusb (you'd probably have to dig deeper through the libusb source, in order to do the same without libusb).

下面是 testu.c (注意,安装的libusb-dev的包,因此它可以编译):

Here is testu.c (note, install the libusb-dev package so it can compile):

#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <usb.h>
/* #include <stropts.h> */
/* #include <inttypes.h> */
#include <linux/usbdevice_fs.h>
/* #include <asm/byteorder.h> */
/* #include <linux/usb/ch9.h> */
//~ #define USBDEVFS_REAPURB           _IOW('U', 12, void *)

#include <libusb.h>

struct libusb_device_handle *d_udh = NULL;


// [http://www.mail-archive.com/discuss-gnuradio@gnu.org/msg17549.html [Discuss-gnuradio] New implementation for fusb_linux without allocs/frees]
static int
fd_from_usb_dev_handle (libusb_device_handle *udh) //(usb_dev_handle *udh)
{
  return *((int *) udh);
}

//~ ./libusb/os/linux_usbfs.c
struct linux_device_handle_priv {
  int fd;
};

//~ ./libusb/libusbi.h
#define usbi_mutex_t                    pthread_mutex_t
struct list_head {
        struct list_head *prev, *next;
};
struct libusb_device_handle {
        /* lock protects claimed_interfaces */
        usbi_mutex_t lock;
        unsigned long claimed_interfaces;

        struct list_head list;
        struct libusb_device *dev;
        unsigned char os_priv[0];
};

//~ ./libusb/os/linux_usbfs.c
struct linux_device_handle_priv* _device_handle_priv(
        struct libusb_device_handle *handle)
{
  struct linux_device_handle_priv* out;
  out =  (struct linux_device_handle_priv *) handle->os_priv;
  return out;
};



int main(int argc, char *argv[])
{
  int fd;
  int result;
  int i;
  struct usbdevfs_urb * receive;
  struct usbdevfs_urb * send;
  struct linux_device_handle_priv *hpriv;
  send = malloc(sizeof (struct usbdevfs_urb));
  memset(send, 0, sizeof (*send));
  send->buffer_length = 10;
  send->buffer = malloc(sizeof(unsigned char)*10);
  send->type = USBDEVFS_URB_TYPE_BULK;
  send->endpoint = 0x02;
  send->signr = 0;


  receive = malloc(sizeof (struct usbdevfs_urb));

  bzero(receive, sizeof (struct usbdevfs_urb));

  char file[30];
  if (argv[1]) strncpy (file, argv[1], 30);

  printf ("First\n");
  result = libusb_init(NULL);
  if (result < 0)
  {
    printf("failed to initialise libusb:\n");
  }
  d_udh = libusb_open_device_with_vid_pid(NULL, 0x0403, 0x6001);
  hpriv = _device_handle_priv(d_udh);
  printf ("Second 0x%X\n", (unsigned int)d_udh);
  result = d_udh ? 0 : -EIO;
  //~ if ((fd = open(file, O_RDWR)) < 0)
  if (result < 0)
    {
      printf("failed to open device: %s, \n error: %s \n", "0403:6001", strerror(errno)); //file
    }
  else
    {
      //~ fd = fd_from_usb_dev_handle(d_udh); // doesn't work
      fd = _device_handle_priv(d_udh)->fd;
      printf ("Open successed: Device: %s %d\n", "0403:6001", fd ); // file);
      for (i = 0; i < 10; ++i)
        {
          result = ioctl (fd, USBDEVFS_SUBMITURB, send);
            if (result < 0)
              {
                printf ("Error! USBDEVFS_SUBMITURB : ioctl returned : %d\n errno =%s\n", result, strerror(errno));
                break;
              }
          printf ("polling...\n");
          result = ioctl(fd, USBDEVFS_REAPURB, receive);
            if (result < 0)
              {
                printf ("Error! USBDEVFS_REAPURB : ioctl returned : %d\n errno =%s\n", result, strerror(errno));
                break;
              }
          printf ("The %d th time ok.\n", i + 1);
          usleep(2000);
        }
    }
  close(fd);
  return 0;
}

好了,希望这可以帮助别人,结果
干杯!

Well, hope this helps someone,
Cheers!

这篇关于如何让在Linux USB的URB信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆