RK3568 USB相机报错问题

UVC

Posted by LXG on October 22, 2025

测试 Demo

AndroidUSBCamera

打开相机的参数


    override fun getCameraRequest(): CameraRequest {
        return CameraRequest.Builder()
            .setPreviewWidth(1920)
            .setPreviewHeight(1080)
            .setRenderMode(CameraRequest.RenderMode.NORMAL)//返回NV21格式
            .setDefaultRotateType(RotateType.ANGLE_0)//旋转角度
            .setExposureNum(11)
            .setPreviewFps(10)
            .setExposureMode(CameraRequest.ExposureMode.EXPOSURE_MANUAL)
            .setPreviewFormat(CameraRequest.PreviewFormat.FORMAT_MJPEG)
            .setAspectRatioShow(true)
            .setCaptureRawImage(false)
            .setRawPreviewData(false)
            .create()
    }


报错日志


2025-10-22 15:43:33.619     0-0     usb 2-1                 kernel                               W  usbfs: process 2572 (USBMonitor) did not claim interface 0 before use
2025-10-22 15:43:33.660     0-0     usb 2-1                 kernel                               W  usbfs: process 2576 (camera-17611190) did not claim interface 0 before use
2025-10-22 15:43:34.020     0-0     usb 2-1                 kernel                               W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:43:34.099  2516-2579  libUVCCamera            com.jiangdg.ausbc                    W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.100  2516-2578  libUVCCamera            com.jiangdg.ausbc                    W  [2578*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.131  2516-2579  libUVCCamera            com.jiangdg.ausbc                    W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.159  2516-2579  libUVCCamera            com.jiangdg.ausbc                    W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.185  2516-2578  ion                     com.jiangdg.ausbc                    E  ioctl c0044901 failed with code -1: Inappropriate ioctl for device
2025-10-22 15:43:34.191  2516-2579  libUVCCamera            com.jiangdg.ausbc                    W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.199  2516-2578  libUVCCamera            com.jiangdg.ausbc                    W  [2578*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.279  2516-2579  libUVCCamera            com.jiangdg.ausbc                    W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.375  2516-2579  libUVCCamera            com.jiangdg.ausbc                    W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:37.755  2516-2579  libUVCCamera            com.jiangdg.ausbc                    W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:40.648     0-0     usb 2-1                 kernel                               W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:45:33.056     0-0     usb 2-1                 kernel                               W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:45:37.736     0-0     usb 2-1                 kernel                               W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:49:00.220     0-0     usb 2-1                 kernel                               W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:49:35.812     0-0     usb 2-1                 kernel                               W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81

日志解析-chatgpt


2025-10-22 15:43:33.619     0-0     usb 2-1  kernel  W  usbfs: process 2572 (USBMonitor) did not claim interface 0 before use
# USBMonitor进程访问UVC设备接口0之前没有调用claim接口。
# 警告级别,不会致命,但说明USB接口使用不够规范,可能导致后续数据传输异常。

2025-10-22 15:43:33.660     0-0     usb 2-1  kernel  W  usbfs: process 2576 (camera-17611190) did not claim interface 0 before use
# camera进程访问UVC设备接口0之前也没有claim。
# 与上一条类似,提示USB访问逻辑不够严格。

2025-10-22 15:43:34.020     0-0     usb 2-1  kernel  W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
# USB端点0x81发生STALL(数据传输中断),应用调用CLEAR_HALT尝试恢复。
# 多数出现在高带宽数据传输或长时间采集时,说明USB压力较大。

2025-10-22 15:43:34.099  2516-2579  libUVCCamera  com.jiangdg.ausbc  W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.100  2516-2578  libUVCCamera  com.jiangdg.ausbc  W  [2578*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.131  2516-2579  libUVCCamera  com.jiangdg.ausbc  W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.159  2516-2579  libUVCCamera  com.jiangdg.ausbc  W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
# libUVCCamera为每一帧分配新的缓冲区。
# 长时间高分辨率预览容易导致ION/CMA内存压力累积。

2025-10-22 15:43:34.185  2516-2578  ion  com.jiangdg.ausbc  E  ioctl c0044901 failed with code -1: Inappropriate ioctl for device
# 核心错误,ION缓冲区分配或操作失败。
# 原因可能:
#   1. 内核IOCTL命令不匹配或权限不足
#   2. ION heap或CMA内存不足
# 这个错误会直接影响UVC预览稳定性,可能导致帧丢失或应用崩溃。

2025-10-22 15:43:34.191  2516-2579  libUVCCamera  com.jiangdg.ausbc  W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.199  2516-2578  libUVCCamera  com.jiangdg.ausbc  W  [2578*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.279  2516-2579  libUVCCamera  com.jiangdg.ausbc  W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.375  2516-2579  libUVCCamera  com.jiangdg.ausbc  W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
# 持续分配缓冲区,说明内存压力累积且没有复用缓冲池。
# 长时间运行可能触发OOM或ION失败。

2025-10-22 15:43:37.755  2516-2579  libUVCCamera  com.jiangdg.ausbc  W  [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
# 继续分配新帧缓冲,长时间采集仍在增加内存压力。

2025-10-22 15:43:40.648     0-0     usb 2-1  kernel  W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:45:33.056     0-0     usb 2-1  kernel  W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:45:37.736     0-0     usb 2-1  kernel  W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:49:00.220     0-0     usb 2-1  kernel  W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:49:35.812     0-0     usb 2-1  kernel  W  Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
# USB端点0x81持续STALL并清除。
# 频繁出现表示USB带宽不足或者主机/摄像头驱动无法稳定传输大量数据。

什么是ION内存

ION 内存是 Android 系统中专门用于多媒体和图形处理的内存分配机制。它的全称是 “Ion Memory Allocator”,由 Google 在 Android 4.x 开始引入,用于解决不同硬件模块之间共享物理内存的效率问题

  1. 解决连续性问题(连续内存) 视频流、图形渲染(比如 SurfaceFlinger 负责的)都需要一大块连续的内存。想象一下,如果一个视频帧的数据被分散存储在内存的各个角落,硬件(如视频解码器)就得花大量时间跳来跳去读取数据,效率极低。

ION 的作用: 它保证分配给你的内存是物理上连续的(或至少在地址空间上看起来是连续的),这样硬件就可以用最快的方式(DMA,直接内存访问)一次性读取或写入数据。

  1. 解决共享和安全问题(零拷贝) 在 Android 中,一个摄像头捕获的帧可能需要被多个组件使用:
  • 摄像头驱动(写入数据)
  • GPU(渲染预览)
  • 视频编码器(压缩数据)

如果使用标准内存,每次组件切换都需要把数据从一个地方拷贝到另一个地方,这非常消耗 CPU 和时间(这就是“零拷贝”技术要解决的问题)。

ION 的作用: 它提供内存句柄(Handle)和文件描述符(FD)。组件 A 申请了一块 ION 内存,然后把这个“通行证”(Handle/FD)交给组件 B。组件 B 可以通过这个通行证直接访问同一块物理内存,无需拷贝。这叫零拷贝 (Zero-Copy),极大地提升了效率。

修改ION 内存大小

rockchip_defconfig


CONFIG_CMA_SIZE_MBYTES=64  # 将 16 改为 64 或更高
CONFIG_CMA_SIZE_SEL_MBYTES=y

dts


&reserved_memory {
 linux,cma {
  compatible = "shared-dma-pool";
  inactive;
  reusable;
  reg = <0x0 0x10000000 0x0 0x04000000>; // 64MB
  linux,cma-default;
 };

假设系统参数:

  • USB 相机分辨率:1920×1080
  • 像素格式:YUYV (2 bytes/pixel)
  • 帧率:30 FPS
  • 双缓冲 (preview + capture)

单帧大小:1920 * 1080 * 2 = 4147200 bytes ≈ 4 MB 双缓冲:4 MB * 2 = 8 MB CMA 预留:8 MB * 2 = 16 MB(留一些余量)

NV21(YUV420SP)模式

1920 × 1080 × 1.5 ≈ 3.1 MB / 帧 双缓冲:3.1 MB × 2 ≈ 6.2 MB

修改后查看CMA内存方法


# 修改前
1|rk3568_r:/ $ cat proc/meminfo
MemTotal:        2004632 kB
CmaTotal:           8192 kB
CmaAllocated:       1976 kB
CmaReleased:        6216 kB
CmaFree:               0 kB

# 修改后
MemTotal:        1947176 kB
CmaTotal:          65536 kB
CmaAllocated:       1944 kB
CmaReleased:       63592 kB
CmaFree:               0 kB


新的报错

报错日志


Build fingerprint: 'WIF/rk3568_r/rk3568_r:11/RD2A.211001.002/20251022.183750:userdebug/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2025-10-24 09:49:02+0800
pid: 2554, tid: 2615, name: camera-17612699  >>> com.jiangdg.ausbc <<<
uid: 10054
signal 11 (SIGSEGV), code 0 (SI_USER), fault addr --------
    x0  0000000000000000  x1  0000000000000004  x2  00000072f8be530c  x3  00000072f8be533a
    x4  0000000000000001  x5  0000000000000000  x6  0000000000000308  x7  a4380f6a470e30ad
    x8  000000000000013c  x9  0000000000000001  x10 0000000000000000  x11 00000072f0e88a60
    x12 ffffff80ffffffe0  x13 00000072f8be86c0  x14 0006cd283464d4cf  x15 0000000029aaaaf1
    x16 00000072f8be8ea0  x17 000000760ac912dc  x18 00000072ee15e000  x19 0000000000000002
    x20 0000007456f49974  x21 000000000000000c  x22 0000000000000224  x23 0000000000000000
    x24 0000007456f49b60  x25 00000073d6f26950  x26 0000007396f40378  x27 00000073c6f2b670
    x28 0000000000000224  x29 00000072f0e88b20
    lr  00000072f8bdf89c  sp  00000072f0e88a60  pc  00000072f8bdf8b0  pst 0000000080001000

backtrace:
      #00 pc 00000000000118b0  /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so (BuildId: 0a3128b26d7b110d699b38305536ccf99ac8ea1b)
      #01 pc 000000000000d618  /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so (BuildId: 0a3128b26d7b110d699b38305536ccf99ac8ea1b)
      #02 pc 000000000000d060  /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so (libusb_handle_events_timeout_completed+600) (BuildId: 0a3128b26d7b110d699b38305536ccf99ac8ea1b)
      #03 pc 000000000000d774  /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so (libusb_handle_events+32) (BuildId: 0a3128b26d7b110d699b38305536ccf99ac8ea1b)
      #04 pc 000000000001155c  /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libuvc.so (_uvc_handle_events+132) (BuildId: ecfb28a6291beb57fec7298797d8213c772ae2c1)
      #05 pc 00000000000af880  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: 23b47e338fca2b85af1ec50fd590d7c7)
      #06 pc 00000000000500d0  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 23b47e338fca2b85af1ec50fd590d7c7)

memory near x2 (/data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so):

AI 分析:

  • 崩溃发生在线程 camera-17612699 中,由 libusb100.so → libuvc.so 调用链触发。
  • 线程执行的是 UVC 相机事件处理线程 (_uvc_handle_events),该线程负责监听摄像头数据流。
  • 核心函数 libusb_handle_events_timeout_completed 崩溃,常见原因包括:
    1. libusb context 已被释放(即相机断开但事件线程未退出)
    2. 多线程访问 libusb context 导致内存竞争
    3. USB 设备异常断开时没有正确调用 uvc_close() 或 libusb_exit()

这次 SIGSEGV 崩溃是由 UVC 摄像头断开或事件线程访问已释放的 libusb context 导致的。

典型场景:

  1. 插拔 USB 摄像头时,Java 层的 UVCCamera.close() 没有同步停止 native 层线程;
  2. 或者设备被系统 USB service 强制重置(例如电源波动);
  3. 或者 UVC 库多线程访问同一 libusb_context(没加锁)。