Sunday 27 June 2010

Weekly report - Week 5

Status:
  • Managed to fix the throughput issue with my USB flash device. I now get 19.11 MB/sec, close to the maximum throughput when the USB device is directly connected to the host.
    In my previous version, I used only one urb/request pair per endpoint: when data came from the device (through an urb), it was forwarded to the host (as a request), and the driver would only resubmit the urb when the data was properly sent to the host.

    • I fixed this by having 8 urb/requests submitted to the USB controller driver, to make sure that there is always some buffer available to write incoming data to. This alone improved the performance to 12.79 MB/sec.
    • The second thing I did is to have a larger buffer per urb/request: instead of allocating 512 bytes (i.e. wMaxPacketSize) per urb/request, I allocated 4096 bytes. I guess that this reduces the number of interrupts (and the number of times my handlers are called), giving an extra performance gain. This should also be transparent to the host/device, as transfers larger than wMaxPacketSize are split into smaller packets of size wMaxPacketSize (except the last one). Since our buffer size is a multiple of wMaxPacketSize, this should not cause problems.

  • SET_INTERFACE command works (this is a prerequisite for isochronous transfers). This was a bit tricky, as disabling endpoints cannot be done in interrupt context, so I submit a work_struct to do that in process context.
  • I started working on isochronous transfers. I got clean audio coming from the microphone integrated in a webcam. The video still does not work, but I am working on it.
Plans:
  • Fix isochronous transfers, as the urb buffer is filled in a special way in these cases (I'll write about that next week), my code works by chance with the audio from the webcam.
  • Code cleanup, again. Some parts are unstable again, causing oopses and warning, after some of my recent updates.
  • Maybe, collect statistics on urb/request usage, to see how many urb/requests are needed for maximum performance.
Risks:
  • From what I see in MUSB, the driver does not support high-bandwidth endpoints (i.e. isochronous transfers with maxPacketSize > 1024 bytes), that are used by High-Speed device. The driver may need to be updated.
  • Bandwidth allocation: with this proxy model, there is nothing much with can do if bandwidth allocation fails on the BeagleBoard. If the host believes enough bandwidth is available, it will use high-throughput interfaces, and there is nothing that can be done on the BeagleBoard to prevent that, in case there is not enough bandwidth available on the EHCI controller of the BeagleBoard. This causes problems with the video on the USB webcam, but the configuration option CONFIG_USB_EHCI_TT_NEWSCHED seems to help, though.

4 comments:

  1. Hello,

    Your project is very interesting. I believe that it would be a great help to my research in developing a new USB device. In trying to get your code up and running I have a few questions.

    - is there any special adapters (not listed on the beagleboard shopping list) that I will need to connect to a device and a host? Basically can you describe your setup?

    - where can I find the steps to compiling the Angstrom kernel? I am very familiar with normal kernel compiling, though I do not know where to get the cross-compiling toolchain and your link is not working on the Wiki.

    - Is there a reason you went the Angstrom route?

    - Have you implemented the sniffing capability yet or is that to come?

    ReplyDelete
  2. - You need:
    - A USB cable (mini-B), to connect your host to the BeagleBoard. This is commonly found to connect external hard drives, so you probably have one already.
    - If your device is Full-speed or Low-speed, you need a USB 2.0 hub, to connect to your hard drive.
    - You need a 5V adapter, and a serial cable (the IDC10->DB9 adapter).

    - This is not an "Angstrom kernel", this is a normal (patched) Linux kernel. Some building instructions can be found here: http://www.elinux.org/BeagleBoard#Linux_kernel, and prebuilt toolchain: http://www.angstrom-distribution.org/toolchains/ .
    Which link is not working on the Wiki?

    - I didn't go the "Angstrom route". My code is almost completely user-space independent. Then, Angstrom is what most people seem to be using with the BeagleBoard, so that's why I used it.

    - It's not a complete solution yet. There are 2 parts: 1. a proxy driver, that forwards traffic between the host and the device. 2. a USB traffic logger. If your device works with the proxy driver, then logging is easy, just use the usbmon infrastructure in the kernel.

    ReplyDelete
  3. Thank you for the quick reply. From the link you provided I found the below one, which is very informative on the subject.

    http://www.elinux.org/BeagleBoardLinuxKernel

    Could you provide me with the link/version where you downloaded the kernel source from and a diff (patch file)? This way I could easily see the files you have added and modified to understand your code.

    The missing link is in this line:
    Compile the kernel with the default beagleboard configuration (see here).

    Thanks again for the reply.

    ReplyDelete
  4. The kernel source is here: http://gitorious.org/beagleboard-usbsniffer/beagleboard-usbsniffer-kernel, use the stable branch as indicated in my instructions.

    I fixed the missing link, which was supposed to point at the page I mentionned above.

    ReplyDelete