babble detected on USB2.0 with embedded UVC camera

I am attempting to debug a problem that occurs when a UVC webcam is used on a WIN7 Enbedded system. The same camera works with the same test script on an XP system without issue (different host hardware, however). The test script alternately streams video from the subject UVC camera (turns on or off streaming) and a second different UVC camera, dwelling about 8 seconds on each. This switching back and forth between cameras will usually run for about 2 hours or so before trouble occurs.

The “trouble” that occurs seems to be that the subject webcam gets a USB RESET condition, which causes it to reboot (it is a Linux-based USB/UVC gadget running on an embedded DM368 Davinci/ARM processor). Using ‘logman’ I’v ebeen able to capture a lot of data about the sequence of actions in the USBHUB and USBPORT drivers just before the problem area. This data shows that a BABBLE condition is detected and it seems to always happen on the FIRST USB BULK data completion where a partial video frame is sent. I have poured over the code many times in this area and I don’t see how the BABBLE can happen.

Any guidance or advice on tracking this down a bit more would be greatly appreciated. I’m using logman to get ets logs of USBHUB and USBPORT events and then I’m using Netmon 3.4 to parse and display the event log. There is a great deal of data … so much that I may be missing the most important item(s).

xxxxx@ece.ucsb.edu wrote:

The “trouble” that occurs seems to be that the subject webcam gets a USB RESET condition, which causes it to reboot (it is a Linux-based USB/UVC gadget running on an embedded DM368 Davinci/ARM processor). Using ‘logman’ I’v ebeen able to capture a lot of data about the sequence of actions in the USBHUB and USBPORT drivers just before the problem area. This data shows that a BABBLE condition is detected and it seems to always happen on the FIRST USB BULK data completion where a partial video frame is sent. I have poured over the code many times in this area and I don’t see how the BABBLE can happen.

Interesting. “Babble” means your device sent a packet that was larger
than the schedule told it to expect. I believe usbvideo.sys always
sends requests with a multiple of the maximum packet size, so the only
way babble should be possible is if you sent more than 512 bytes. Do
you have a USB analyzer to see what really happens on the bus? Software
analyzers aren’t really much help in a babble situation.

I’m not sure usbvideo.sys bulk has received the same attention as
usbvideo.sys isochronous. Do your cameras support isochronous?

How are you sending a partial video frame? Are you sending a short
packet to terminate, and then starting the next packet with another UVC
header?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

On 04/17/2013 09:32 AM, Tim Roberts wrote:

xxxxx@ece.ucsb.edu wrote:
> The “trouble” that occurs seems to be that the subject webcam gets a USB RESET condition, which causes it to reboot (it is a Linux-based USB/UVC gadget running on an embedded DM368 Davinci/ARM processor). Using ‘logman’ I’v ebeen able to capture a lot of data about the sequence of actions in the USBHUB and USBPORT drivers just before the problem area. This data shows that a BABBLE condition is detected and it seems to always happen on the FIRST USB BULK data completion where a partial video frame is sent. I have poured over the code many times in this area and I don’t see how the BABBLE can happen.
Interesting. “Babble” means your device sent a packet that was larger
than the schedule told it to expect. I believe usbvideo.sys always
sends requests with a multiple of the maximum packet size, so the only
way babble should be possible is if you sent more than 512 bytes. Do
you have a USB analyzer to see what really happens on the bus? Software
analyzers aren’t really much help in a babble situation.

I’m not sure usbvideo.sys bulk has received the same attention as
usbvideo.sys isochronous. Do your cameras support isochronous?

How are you sending a partial video frame? Are you sending a short
packet to terminate, and then starting the next packet with another UVC
header?

Our webcam device uses BULK mode rather than ISOC because it does not do
compression and we cannot get the frame rate and/or frame sizes we need
with the 1x 1024 transfers per microframe ISOC limits. This is because
our hardware cannot do 2x or 3x transfers per microframe. Our BULK
mode requests have large payload sizes (153602 is used, I believe).
These payloads get subdivided into 512+2-byte USB transactions by our
on-chip controller.

We have a USB analyzer on order … expected tomorrow. That should
help use understand the problem better. In answer to your question
about whether we are sending a partial video frame. Yes, each frame
(640x480x2-byte pixels) is 614400 bytes in size. We send the overall
frame in four pieces, each exactly 1/4th of the frame in size. It
seems that our babbling only happens on the *first* BULK transaction,
hence the possibility that there might be something left in our hardware
FIFOs from the previous streaming session. We are looking into the
gadget driver to see whether this is possible or not.

It seems that under WIN-XP the same user-level test code switches back
and forth between UVC cameras successfully and runs for weeks and weeks
without issue. BUT, one difference we see is that on Win-XP our camera
is never told to stop streaming. This is different from the way that
WIN7 Embedded does things. So, this focusses our efforts even more
into the whole stream stop and stream startup area.

Steven Butner wrote:

Our webcam device uses BULK mode rather than ISOC because it does not do
compression and we cannot get the frame rate and/or frame sizes we need
with the 1x 1024 transfers per microframe ISOC limits. This is because
our hardware cannot do 2x or 3x transfers per microframe.

I surprised at that. It’s not that much more work for the device. You
just get requests more often.

Our BULK
mode requests have large payload sizes (153602 is used, I believe).
These payloads get subdivided into 512+2-byte USB transactions by our
on-chip controller.

Umm, what do you mean by “512+2”? Your USB packets must be 512 bytes
exactly (except for the last one). When you have a UVC header to send,
you send the 2-byte UVC header plus 510 bytes of payload, for a total of
512. If you actually sent 514 bytes, you’d get… babble.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

On 04/17/2013 11:56 AM, Tim Roberts wrote:

Steven Butner wrote:
> Our webcam device uses BULK mode rather than ISOC because it does not do
> compression and we cannot get the frame rate and/or frame sizes we need
> with the 1x 1024 transfers per microframe ISOC limits. This is because
> our hardware cannot do 2x or 3x transfers per microframe.
I surprised at that. It’s not that much more work for the device. You
just get requests more often.

> Our BULK
> mode requests have large payload sizes (153602 is used, I believe).
> These payloads get subdivided into 512+2-byte USB transactions by our
> on-chip controller.
Umm, what do you mean by “512+2”? Your USB packets must be 512 bytes
exactly (except for the last one). When you have a UVC header to send,
you send the 2-byte UVC header plus 510 bytes of payload, for a total of
512. If you actually sent 514 bytes, you’d get… babble.

I was surprised as well … but the DM36x built-in hardware cannot do
the 2x or 3x multi-shot-per-microframe style of ISOC traffic. Our
project went quite far into development before we understood the full
implications of this limitation. We need to use all-hardware (i.e.
DMA) to accomplish our USB I/O or else we cannot even get close to our
30 frames per second goals. So … we are stuck with BULK mode until
we move to a different processor … sigh.

When I typed the “512+2” in my previous email I was mis-remembering the
way the little 2-byte headers got inserted. You are exactly correct in
that all of the bulk traffic happens in 512-byte chunks where the first
chunk of our one-quarter-video-frame payload has the 2-byte UVC header
inserted and thus there are just 510 bytes of video in that one while
all following chunks in that payload have 512 bytes of video data in
them. The next payload (which is the next 1/4 frame of video) again
has the 2-byte header with 510 bytes in the first I/O chunk with all
following chunks having 512 bytes.

I think our problem is related to cleaning up after the *previous*
streaming session was turned off. WIN7 seems to queue up about 8 URBs
(representing 8, quarter video frames or 2 full video frames in all) and
when the stream is turned off any outstanding URBs that have already
been dispatched get cancelled. On my end of this, there are packets
queued up ready to go out and when we are told to stop streaming we
clean that up. In the clean-up area there is double-buffered FIFO
hardware that needs to be treated as two separate, but
sequentially-connected single FIFOs and I am thinking that the FIFO
clean-up is not treating this double, yet actually two single units
situation correctly. I’ve made a new build of the system and I’m
running the test now. Hopefully this improved clean-up will fix our
babble issue by ensuring that we never have anything in our FIFOs that
is left over from a previous streaming session.

If my test fails, I’ll re-post but at this point I have high hopes.
Thanks for your help and insight …