SoC 差異、V4L2、CSI 現況
Orange Pi 涵蓋多種 SoC(RK3588、H618、H616 等),相機支援因 SoC 而異。
| SoC | 代表板卡 | CSI/ISP |
|---|---|---|
| Rockchip RK3588 | Orange Pi 5 系列 | 有 CSI、有 Rockchip ISP |
| Allwinner H618 | Orange Pi Zero 3 | CSI 依 BSP |
| Allwinner H616 | Orange Pi Zero 2W | CSI 有限 |
Orange Pi 社群最常見的 OmniVision 感測器是 OV5640(驅動 ov5640.c 已在 Linux mainline)。
「能不能接相機」最終由 SoC 的硬體 IP 區塊決定,而不是板卡品牌。Orange Pi 常見的兩條路線各有一套硬體結構:
| SoC | CSI-2 接收器 | ISP | 頻道/VC |
|---|---|---|---|
| RK3588 | 4× MIPI CSI-2 D-PHY(可達 2.5 Gbps/lane) | 有(Rockchip ISP3) | 多 virtual channel |
| H618 / H616 | 1× MIPI CSI-2 D-PHY | 多無完整平台 ISP | 單一主要 channel |
關鍵名詞:CSI-2 的資料以一組 lanes(資料通道)傳輸,每個 frame 內可帶 virtual channel(VC) 標籤以多工多顆感測器。RK3588 的 4 組接收器讓它「理論上」能同時接多顆相機——這就是單元 16 多相機的硬體前提。
在 Linux 中,這些硬體區塊不是直接存取,而是透過 media controller 曝光成一個圖(graph):每個硬體區塊是一個 entity,實體之間的連線是 link。kernel 會建立 /dev/media0,並在 probe 成功時把感測器掛上圖。
拿到任何一片 Orange Pi,第一步是「盤點生態」:知道 kernel 有沒有內建相機支援、I2C 有哪些 bus、video 節點存在與否。下面從登入到列管的完整流程:
uname -a # 看架構與 kernel 版本 cat /etc/os-release | head -3 # 確認發行版(Armbian / Orange Pi OS…)
ls /dev/video* 2>/dev/null # 有 /dev/video0 代表有 video device ls /dev/v4l-subdev* 2>/dev/null # subdev 節點(感測器/CSI) dmesg | grep -i -E "ov5640|csi|camera|mipi"
ls /dev/i2c-* # 找相機掛在哪個 bus sudo i2cdetect -l # 每個 bus 的編號與種類
media-ctl -p -d /dev/media0 2>/dev/null || echo "無 /dev/media0"
| 節點 | 問題 | 下一步 |
|---|---|---|
有 /dev/video0 | 相機節點已存在 | 直接看單元 5 取流 |
無 /dev/video0,dmesg 有 probe 失敗 | 驅動/DT 有問題 | 單元 6 dmesg 除錯 |
| 無節點、dmesg 完全沒有相機字樣 | DT 未啟用相機節點 | 查 BSP 的 overlay / config,啟動 CSI + I2C |
有節點但 media-ctl -p 空 | 管線未連結 | 單元 5 media-ctl 建 link |
uname -a、ls /dev/video*、I2C bus 清單。dmesg 找出你板卡 kernel 中與相機相關的三條訊息,寫出它們的意義。media-ctl -p 輸出。場景:RK3588 板卡(如 Orange Pi 5 Plus)同時接 OV5640 + OV9281(IR),在啟動後快速盤點兩顆感測器的生態位置。
cat /proc/device-tree/compatible | tr '\0' '\n' | head -1
ls /dev/media* # RK3588 可能有多個 media devicev4l2-ctl --list-devices ls /dev/v4l-subdev*
sudo i2cdetect -y 3 # OV5640 應在 0x3c sudo i2cdetect -y 4 # OV9281 應在 0x60 sudo i2cget -y 3 0x3c 0x300a # → 0x56 sudo i2cget -y 4 0x60 0x300a # → 0x92(OV9281 ID)
media-ctl -p -d /dev/media0 2>/dev/null | grep -E "ov5640|ov9281|csi" media-ctl -p -d /dev/media1 2>/dev/null | grep -E "ov5640|ov9281|csi"
Orange Pi 的 ISP 生態有兩條截然不同的硬體路線:
| SoC | 影像處理 IP | 關鍵差異 |
|---|---|---|
| RK3588 | RGA(Raster Graphic Acceleration)+ ISP3 | RGA 可做即時旋轉/縮放/color space 轉換;ISP3 有完整 3A 管線 |
| Allwinner H618 | CIF(Camera Interface) | CIF 只負責接收 MIPI 資料,無獨立 ISP 模組——色彩校正全靠感測器端 |
容易忽略的邊界案例:RK3588 的 RGA 模組雖然是硬體加速,但它不在 V4L2 media graph 內——而是透過 /dev/rga 獨立的 IOCTL 介面操作。這意味著你不能用 media-ctl 管理 RGA,必須在 userspace 另外串接。這是在 RK3588 上做即時後處理時最常忽略的架構限制。
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
media-ctl -p 顯示 entity 但 link 全斷 | DT overlay 未啟用 media controller | 確認 boot config 有 media_controller=1,或手動 media-ctl -l |
RK3588 多顆感測器但只有一個 /dev/video0 | DT 只 probe 一顆;第二顆的 I2C/CLOCK 未設定 | 檢查 DT overlay 是否為兩顆感測器都加了 clock-gpios 和 i2c 節點 |
Allwinner H618 media-ctl -p 完全空白 | BSP 未啟用 media controller 框架 | 改用 v4l2-ctl --list-devices 直接查;H618 多數 BSP 用 legacy V4L2 |
i2cdetect 掃到多顆相同位址 | 多顆感測器共享同一 I2C bus 且未改 address strap | 改其中一顆的 SCCB_ID 腳,或分開到不同 I2C bus |
dmesg 有 probe success 但 /dev/video* 不存在 | video device node 未註冊(kernel config 缺 V4L2_VIDEO_DEVICE) | 確認 kernel .config 有 CONFIG_VIDEO_V4L2=y 和 CONFIG_VIDEO_V4L2_SUBDEV_API=y |
把單元 1–6 的知識串成一個端到端專案:從一片空白板卡開始,完成「DT overlay → probe → 管線 → 第一張圖」。這是你在這門課第一個可交付的里程碑。
uname -a ls /dev/video* /dev/v4l-subdev* 2>/dev/null sudo i2cdetect -l
# 最小 overlay:啟用 I2C3 + 感測器節點
/dts-v1/;
/plugin/;
&i2c3 {
status = "okay";
ov5640: ov5640@3c {
compatible = "ovti,ov5640";
reg = <0x3c>;
clocks = <&clk_cam0>;
clock-frequency = <24000000>;
pinctrl-names = "default";
pinctrl-0 = <&camera_pwr_en>;
};
};dmesg | grep -i -E "ov5640|probe"
sudo i2cget -y 3 0x3c 0x300a # 預期 0x56media-ctl -d /dev/media0 -r
media-ctl -d /dev/media0 -l "'ov5640 3-003c':0->'csi2':0[1]"
media-ctl -d /dev/media0 -V "'ov5640 3-003c':0[fmt:UYVY8_2X8/1280x720]"
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=YUYV \
--stream-mmap=3 --stream-count=1 --stream-to=first.yuv
ls -l first.yuv # 1,843,200 bytes在動手接任何鏡頭之前,先用固定 SOP 把板卡的相機生態「量」清楚,避免盲目投資。
| 步驟 | 指令 | 通過判據 |
|---|---|---|
| 1. 確認 SoC | cat /proc/device-tree/compatible | tr '\0' '\n' | 清楚寫出 RK3588 / H618 / H616 |
| 2. 列 video 節點 | ls /dev/video* /dev/v4l-subdev* | 節點存在;數量與預期相符 |
| 3. 列 I2C bus | sudo i2cdetect -l | 知道相機該掛哪個 bus |
| 4. media graph | media-ctl -p -d /dev/media0 | entity 清單與 DT 一致 |
| 5. 讀感測器 ID | sudo i2cget -y 3 0x3c 0x300a | 回 0x56(OV5640) |
| 面向 | Orange Pi | RPi5 | Orin Nano | Thor |
|---|---|---|---|---|
| 代表 SoC | RK3588 / H618 | BCM2712 | Orin Nano(Ampere) | T5000(Blackwell) |
| CSI 接收器 | RK3588 4× CSI-2 / H618 1× | 2× CSI-2(4-lane) | CSI-2(最多 16-lane) | CSI-2 + 更高速介面 |
| 平台 ISP | RK3588 有 / H618 無 | 硬體 ISP(開源) | NVIDIA ISP | NVIDIA ISP + Blackwell |
| 控制介面 | V4L2 subdev / media-ctl | libcamera | tegracam / Argus | Holoscan / GXF |
| 常見感測器位址 | 0x3c(bus 3) | 0x3c(bus 22) | 0x36(bus 0) | 0x36(bus 0) |
| 生態「已知可用組合」 | BSP 社群 overlay | libcamera 支援清單 | NVIDIA 相容表 | Holoscan 套件 |
- [ ] 我能背出我板卡的 SoC、CSI 數量、有無平台 ISP。 - [ ] 我能用 media-ctl -p 畫出板卡完整的 media graph。 - [ ] 我已跑完 1.14 SOP 並產出「平台盤點表」。 - [ ] 我能解釋「感測器位址 0x3c vs 0x36」的由來。 - [ ] 我能指出 RK3588 與 H618 在「調校能力」上的本質差異。 - [ ] 我已開始 1.13 專案,至少完成階段 1 盤點。
單元 1 的「register 操作」集中在 media controller 與 I2C device discovery。以下是以 OV5640 為例的「讀→改→寫→驗證」完整位元級序列:
| 步驟 | 暫存器/位址 | 位元欄位 | 操作 | 預期值 |
|---|---|---|---|---|
| 1. 掃描 I2C | bus 3 全位址 | — | i2cdetect -y 3 | 0x3c 出現 |
| 2. 讀感測器 ID | 0x300A | [7:0] = chip ID high | i2cget -y 3 0x3c 0x300a | 0x56 |
| 3. 讀感測器 ID | 0x300B | [7:0] = chip ID low | i2cget -y 3 0x3c 0x300b | 0x40 |
| 4. 驗證 PLL 準備 | 0x3035 | [7:4] PLL Prediv | i2cget ... 0x3035 | 依 DT clock 設定 |
| 5. 確認 reset 釋放 | GPIO debug | reset-gpios level | cat /sys/kernel/debug/gpio | grep reset | high(active-low 釋放) |
| 6. media-ctl 建 link | /dev/media0 | entity 0 pad 0 → entity 1 pad 0 | media-ctl -l "...:0->...:0[1]" | link 設為 active |
決策樹 A:板卡完全找不到相機
dmesg 無任何相機字樣? ├─ 是 → DT 未啟用相機 → 檢查 overlay 是否含 i2c + sensor 節點 │ └─ DT overlay 已載入但無字樣 → compatible 字串不對(查 ov5640.c) └─ 否 → 有 probe 字樣 ├─ probe failure → 依 dmesg 錯誤: │ ├─ "no chip id" → I2C 通但 ID 錯 → 位址/模組型號問題 │ ├─ "clk prepare" → clock 未就緒 → DT clock-frequency 設定 │ └─ "reset" → reset GPIO 極性/時序 → 檢查 reset-gpios └─ probe success → 檢查 /dev/video* 是否存在
決策樹 B:有 probe 但沒畫面
ls /dev/video* 有節點?
├─ 否 → media controller 未綁定 → 檢查 DT 的 video device 節點
└─ 是 → v4l2-ctl --list-devices 有對應?
├─ 否 → subdev 未 probe → dmesg 看 csi/entity 錯誤
└─ 是 → media-ctl -p 有完整管線?
├─ link 缺失 → media-ctl -l 手動建 link
├─ format 缺失 → media-ctl -V 設定 pad format
└─ 管線完整 → v4l2-ctl 取流(回單元 5)| 步驟 | 指令 | 預期輸出 | 判讀標準 |
|---|---|---|---|
| 1. SoC 確認 | cat /proc/device-tree/compatible | tr '\0' '\n' | rk3588 / allwinner,h618 | 清楚寫出型號 |
| 2. Video 節點 | ls /dev/video* /dev/v4l-subdev* | video0, v4l-subdev0..N | 數量與 DT 預期一致 |
| 3. I2C bus | sudo i2cdetect -l | 列出所有 bus 編號 | 知道相機掛哪個 bus |
| 4. I2C 掃描 | sudo i2cdetect -y 3 | 0x3c 出現 | 感測器 I2C 可達 |
| 5. 讀感測器 ID | sudo i2cget -y 3 0x3c 0x300a | 0x56 | ID 與 datasheet 相符 |
| 6. dmesg probe | dmesg | grep -i ov5640 | "probe success" | 無 error/warning |
| 7. media graph | media-ctl -p -d /dev/media0 | sensor → csi → video entities | link 與 DT 一致 |
| 8. 取一幀 | v4l2-ctl --stream-mmap=1 --stream-count=1 | 成功產出 YUV 檔 | sizeimage 正確 |
| 面向 | Orange Pi | RPi5 | Orin Nano | Thor | 推薦 |
|---|---|---|---|---|---|
| 代表 SoC | RK3588 / H618 | BCM2712 | Orin Nano | T5000 | 依需求 |
| CSI 接收器 | 4× / 1× | 2× (4-lane) | 多路 CSI | 多路 CSI | 多相機→RK3588 |
| 平台 ISP | RK3588 有 / H618 無 | 硬體 ISP | NVIDIA ISP | Blackwell ISP | 畫質→NVIDIA |
| 控制介面 | V4L2 subdev | libcamera | Argus | Holoscan | 底層→Orange Pi |
| media controller | ✅ 開放 | libcamera 抽象 | 封閉 | 封閉 | 學習→Orange Pi |
| I2C 工具 | i2c-tools 全支援 | i2c-tools | 需權限 | 需權限 | Orange Pi 最自由 |
| DT overlay | dtbo + dtoverlay | config.txt | Board config | Holoscan | Orange Pi 最透明 |
| 除錯深度 | 完全可見 | 高 | 低(封閉) | 低(封閉) | 除錯→Orange Pi |
- [ ] 確認 SoC 型號(RK3588 / H618 / H616) - [ ] 列出所有 /dev/video* 與 /dev/v4l-subdev* 節點 - [ ] 執行 i2cdetect -l 列出所有 I2C bus - [ ] 在正確 bus 上掃描到 0x3c(OV5640 位址) - [ ] 讀取 0x300A 確認回 0x56(OV5640 ID) - [ ] 讀取 0x300B 確認回 0x40 - [ ] dmesg 確認 "probe success" 無 error - [ ] media-ctl -p 確認 sensor → csi → video 完整管線 - [ ] 用 media-ctl -l 建立 link 並 -V 設定格式 - [ ] v4l2-ctl 取一幀 YUV 並驗證 sizeimage - [ ] 產出「平台盤點表」文件(SoC/I2C/media/格式) - [ ] 確認 BSP「已知可用組合」與你的硬體一致 - [ ] 若有多顆感測器,逐一確認各自的 bus/位址/video node