Hardware
- Board: Radxa Zero 3W (RK3566)
- Camera: TSTC USB20 WEB CAMERA (1bcf:2cd1), connected via Type-C port (USB2.0)
- WiFi: RTL8812AU (USB, on the same USB bus)
- Use case: FPV drone, air unit
Problem
When the drone experiences physical shaking/vibration, the USB camera UVC driver enters a permanent -71 (EPROTO) state:
uvcvideo: Failed to set UVC probe control : -71 (exp. 26).
After this error, two scenarios can occur:
Scenario A (more common): /dev/video0 still exists, but all V4L2 ioctls fail.
- GStreamer pipeline reports: "Device '/dev/video0' failed during initialization"
- The error never self-recovers
- The pipeline restarts in an infinite loop (~730ms per cycle)
Scenario B (less common): /dev/video0 disappears entirely.
- OpenHD enters a "waiting for reconnection" loop
- The camera is still visible in
lsusb, but UVC driver probe fails
- Kernel shows: "cannot get freq at ep 0x86"
Recovery only works with:
- Full application restart, OR
- USB authorized reset:
echo 0 > /sys/.../authorized; echo 1 > /sys/.../authorized, OR
- Physically unplugging and replugging the camera
What we have implemented
We added a USB recovery mechanism in GStreamerStream:
- Error counter: Track consecutive "failed during initialization" errors (with 10-second window to reset the counter for new failure episodes)
- USB authorized reset: When counter >= 2, write 0 to the USB device"s authorized sysfs node to disconnect and let the kernel auto-reconnect
- Active polling: After disconnect, poll
open(/dev/video0, O_RDONLY) in a loop (200ms interval, up to 5s) until the device is fully re-initialized by the UVC driver
The problem we still face
The USB reset via authorized sysfs works, but only when we manually run the command from shell AFTER stopping OpenHD.
It does NOT work reliably when triggered programmatically while OpenHD is running and actively retrying the pipeline, because:
- The USB reset sysfs path becomes invalid immediately after writing 0 (the device directory disappears from sysfs)
- The device re-enumeration takes ~1-3 seconds
- The GStreamer pipeline rebuilds faster than the device can re-initialize, leading to repeated "failed during initialization" errors
Questions for the OpenHD team
- Is there a better way to reset a stuck UVC device? Should we use v4l2_release() + v4l2_open() instead of USB authorized reset?
- Should we avoid rebuilding the GStreamer pipeline and instead kill/restart the entire process?
- Is there a way to prevent the UVC driver from entering this stuck state in the first place? Are there UVC driver module parameters that could help with transient USB errors?
- Would using VIDIOC_RESET on the V4L2 device help?
- Is there an existing way in OpenHD to handle USB camera disconnection/reconnection that we should use instead of our custom mechanism?
- Is the -71 error on the RK3566 platform possibly related to the USB controller (dwc3/xhci) rather than the camera itself? Any known issues with dwc3 on RK3566 under vibration?
Hardware
Problem
When the drone experiences physical shaking/vibration, the USB camera UVC driver enters a permanent -71 (EPROTO) state:
After this error, two scenarios can occur:
Scenario A (more common):
/dev/video0still exists, but all V4L2 ioctls fail.Scenario B (less common):
/dev/video0disappears entirely.lsusb, but UVC driver probe failsRecovery only works with:
echo 0 > /sys/.../authorized; echo 1 > /sys/.../authorized, ORWhat we have implemented
We added a USB recovery mechanism in
GStreamerStream:open(/dev/video0, O_RDONLY)in a loop (200ms interval, up to 5s) until the device is fully re-initialized by the UVC driverThe problem we still face
The USB reset via authorized sysfs works, but only when we manually run the command from shell AFTER stopping OpenHD.
It does NOT work reliably when triggered programmatically while OpenHD is running and actively retrying the pipeline, because:
Questions for the OpenHD team