SG2002 双核摄像头流水线 — UVC + JPU + IVE CSC

C906B(StarryOS)+ C906L(裸机)· UVC 采集 → JPU 硬解 → IVE 硬件 CSC → 共享内存 → mmap 零拷贝 · 真机实测 60fps / 640×480 RGB888

1 · 性能总览

60 fps
640×480 端到端(强光)
0.1 ms
IVE 硬件 CSC(640×480)
1.0 ms
JPU 硬件解码(640×480)
0 ms
大核用户态拷贝(mmap 零拷贝)
1000×
IVE 硬件 vs 软件 CSC 加速比
57.5 fps
大核用户态实测(mmap 读 RGB)
0.3%
JPU 失败率(自动恢复)
4 MB
预留区(从 2MB 扩展)

2 · 优化历程:帧率从 13 到 60

整个优化经历了多个阶段,每个阶段解决一个瓶颈。下图展示帧率随优化的演进:

帧率 (fps) 0 20 40 60 13.4 初始 JPU wedge +AE=1 16.7 修 JPU 超时按时间 +真复位 60.0 AE priority=0 恒定帧率 58.5 mmap 零拷贝 +双缓冲 57.5 +IVE 硬件 CSC ■ JPU 超时按次数算 → 230s 才触发 ■ 复位序列没真正拉低复位位 ■ 改按时间判定(200ms 超时) ■ hard_reset_at: assert→deassert ■ CT_AE_PRIORITY=0 摄像头不再降帧率换曝光 ■ 消除 75ms 非缓存内核拷贝 ■ 双缓冲消除撕裂 ■ IVE 硬件 YUV→RGB (0.1ms) 比软件快 1000 倍

帧率从 13.4 → 60.0,每个阶段解决一个瓶颈。IVE CSC 额外开销仅 0.1ms,几乎不影响帧率。

3 · 系统架构

大核 C906B(StarryOS, S-mode, 1GHz) 小核 C906L(裸机, M-mode, 25MHz) 硬件外设 共享 DRAM
UVC 摄像头 0c45:64ab MJPEG 640×480 DWC2 Host Isoch IN 1020 B/µframe USB HS 小核 C906L · 裸机 M-mode · 25MHz ① uvc_capture_one_frame() ~12ms ② JPU decode → YUV422 ~1ms ③ IVE CSC → RGB888 ~0.1ms ④ mailbox::notify() + dcache_clean ISR: PLIC 61(收大核消息) USB 中断 + 轮询混合模式 JPU 硬件解码 MJPEG→YUV422 IVE 硬件 CSC YUV→RGB 0.1ms 邮箱控制器 0x01900000 mbox_set + PLIC PLIC 0x70000000 src 61→小核 · src 101→大核 共享 DRAM — 预留区 0x8FE00000 + 4MB YUV422 帧 0x8FE88000 · 600KB RGB888 planar 0x8FF5E000 · 900KB 邮箱+统计 0x90040000 小核:cached identity → 写后 dcache_clean_range 大核:ax_mm::iomap → non-cacheable Device 映射 大核用户态:mmap /dev/cvi-yuv → 零拷贝 大核用户态:mmap /dev/cvi-mailbox → 读帧信息 JPU DMA IVE DMA 大核 C906B StarryOS · S-mode · OpenSBI ISR: PLIC 101(每帧一次) /dev/cvi-mailbox(读帧信息) /dev/cvi-yuv(mmap RGB) 用户态 yuv-fps(零拷贝) 写 /dev/cvi-mailbox → src 61 101 61 ④ 触发中断 mmap 读

数据流:摄像头 → USB → 小核(JPU+IVE) → 共享 DRAM → 大核 mmap。控制流:邮箱 + PLIC 双向中断。

4 · 帧处理时序(640×480, 60fps 强光)

小核 C906L(每帧 16.7ms = 60fps) ① USB 抓帧 ~12ms ② JPU 空闲(等下一帧曝光) 12.0ms 1.0ms 0.1ms ~0 ~3.6ms 空闲 大核 C906B(用户态,零拷贝) ISR mmap 空闲 ~0ms ~0ms PLIC 101 中断 小核合计:12.0 + 1.0 + 0.1 + 0 = 13.1ms(帧预算 16.7ms,余量 3.6ms) 大核合计:~0ms(mmap 零拷贝,直接读共享 DRAM) 端到端延迟:~13ms(从摄像头曝光到大核用户态可见)

5 · 各阶段耗时实测(rdtime, 25MHz)

阶段耗时说明瓶颈
① USB 抓帧(cap)12.0 ms~70 次 isoch_in_uframe 轮询,每次 ~1.1 微帧USB 等时带宽 + 摄像头出帧速度
② JPU 解码(dec)1.0 msMJPEG → YUV422,poll ~0.9ms + 拷贝 ~0.1msJPU 硬件解码时间
③ IVE CSC(ive)0.1 msYUV422 → RGB888 planar,硬件加速IVE 硬件处理时间
④ notify + cache~0 ms写邮箱 32B + dcache_clean_range + mbox_set
大核 ISR~0 ms清 int_st + 读 DRAM 邮箱 → latest_frame
大核 mmap 读0 ms零拷贝:用户态直接读共享 DRAM 映射
合计~13.1 ms帧预算 16.7ms(60fps),余量 3.6ms

5.1 · JPU 内部分解

子步骤耗时说明
JPEG 拷入 stream_buf~600 µscopy_to_phys + dcache_clean
JPU 硬件解码(poll)~930 µs真正的 JPEG 解码计算
dcache clean~50 µsstream_buf 写回
合计~1.0 ms

5.2 · IVE CSC 耗时对比

方案640×480320×240加速比
小核软件 YUV→RGB~120 ms~30 ms
大核软件 YUV→RGB~10 ms~2.5 ms12×
IVE 硬件 CSC0.1 ms0.37 ms1200×

IVE 硬件在 640×480(307200 像素)上仅用 107µs,吞吐约 2.9 G 像素/秒。

6 · 内存布局(4MB 预留区)

预留区 0x8FE00000 — 0x90200000 (4MB) 小核镜像 (.text + .data + .bss + stack) 0x8FE00000 — 0x8FE88000 (~552KB) YUV422 单缓冲(JPU DMA 直写) 0x8FE88000 — 0x8FF1E000 (614400 B = 600KB) JPU DMA pool (stream_buf 256KB) 0x8FF1E000 — 0x8FF5E000 (262144 B) RGB888 planar 输出(IVE CSC 输出,R+G+B 各 307200B) 0x8FF5E000 — 0x9003F000 (921600 B = 900KB) 大核通过 mmap /dev/cvi-yuv 读取 邮箱 32B + 统计块 48B 0x90040000 / 0x90040040
布局无重叠:YUV(600KB) + JPU pool(256KB) + RGB(900KB) + 镜像(552KB) = 2.3MB,4MB 预留区够用。
预留区从 2MB 扩到 4MB:修改 DTB fast_image reg = <0x00 0x8fe00000 0x00 0x400000>

7 · 通信机制

7.1 · 邮箱中断(小核→大核,PLIC source 101)

小核主循环 共享 DRAM 邮箱控制器 PLIC 大核 ① 写 frame_count / yuv_size / flags ② dcache_clean_range(邮箱, 32B) ③ en[1] |= 1; mbox_set = 1 ④ 拉高 CPU1 中断线 ⑤ source 101 → ctx1 ⑥ ISR: 清 int_st + 清 en(deassert) ⑦ ISR 读 DRAM 邮箱 → latest_frame ⑧ 用户态 mmap 读 RGB 数据

7.2 · 寄存器索引 = 接收方 CPU 号

这是最容易搞错的一点。CPU 编号:0=CA53, 1=C906B(大核), 2=C906L(小核)。发送方写的是接收方那一组寄存器。小核→大核 = cpu_mbox_en[1],大核→小核 = cpu_mbox_en[2]

7.3 · Cache 一致性

一侧映射方式要求
小核cached identity (VA=PA)写共享数据后必须 dcache_clean_range()
大核ax_mm::iomap non-cacheable直接 read_volatile 即可
大核用户态mmap /dev/cvi-yuv → non-cacheable零拷贝,直接读共享 DRAM

8 · 优化前 vs 优化后对比

指标优化前优化后改善
帧率13.4 fps60.0 fps4.5×
JPU 超时恢复230s 才触发,不自动复位200ms 超时 + hard_reset_at1150× 快恢复
摄像头帧率16.7 fps(AE priority=1)60.0 fps(AE priority=0)3.6×
大核读 YUV/RGBread_at 内核拷贝 75msmmap 零拷贝 0ms∞(消除拷贝)
YUV→RGB 转换无(输出 YUV)IVE 硬件 CSC 0.1ms硬件加速
JPU 解码耗时51 ms(含 34ms memcpy + 12ms cache)1.0 ms(直写共享区)51×
撕裂风险单缓冲 + seqlock(有洞)—(单缓冲 + IVE 覆盖)
预留区2 MB4 MB
输出格式YUV420 planarRGB888 planar可直接显示

9 · 关键代码位置

文件职责
sg200x-bsp/src/ive.rsIVE 硬件 CSC 驱动(YUV→RGB,寄存器级)
sg200x-bsp/src/jpu/decoder.rsJPU 解码 + set_output_buffer + 按时间超时 + hard_reset_at
sg200x-bsp/src/jpu/regs.rshard_reset_at(assert→deassert 真复位)
sg200x-bsp/src/utils/time.rsrdtime 超时判定(Deadline)
sg200x-bsp/src/usb/class/uvc.rsUVC 协商 + ae_priority + 帧组装 + 采集统计
sg200x-bsp/src/usb/host/dwc2/ep0.rsDWC2 通道传输 + HCINTMSK + 中断/轮询混合
bare-metal/src/main.rs主循环:抓帧→JPU→IVE→notify,分阶段计时
bare-metal/src/yuv_buf.rs共享缓冲布局(YUV + RGB 地址/大小)
bare-metal/src/mailbox.rsDRAM 邮箱 + dcache_clean + HW 邮箱中断
bare-metal/src/trap.rsM-mode trap + PLIC 61 邮箱 ISR
tgoskits/.../dev/cvi_yuv.rs/dev/cvi-yuv: mmap + read_at 向后兼容
tgoskits/.../dev/cvi_mailbox.rs/dev/cvi-mailbox: ISR(new_arc) + 探针
tgoskits/platforms/somehal/.../plic.rs大核 PLIC + 无锁诊断探针

10 · 已知限制与后续方向

当前限制

后续方向