單元 1 · 平台相機生態總覽

SoC 差異、V4L2、CSI 現況

Orange Pi 不是「一顆」感測器平台

Orange Pi 涵蓋多種 SoC(RK3588H618H616 等),相機支援因 SoC 而異。

SoC代表板卡CSI/ISP
Rockchip RK3588Orange Pi 5 系列有 CSI、有 Rockchip ISP
Allwinner H618Orange Pi Zero 3CSI 依 BSP
Allwinner H616Orange Pi Zero 2WCSI 有限

相機框架:V4L2 / media controller

感測器 subdevCSI-2 接收器(ISP)video devicev4l2-ctl
核心概念:Linux 用 media controller 描述「感測器→接收器→ISP→video」管線;用 V4L2 subdev 控制感測器。這是所有 Linux 相機調適的共通語言。

感測器支援現況

Orange Pi 社群最常見的 OmniVision 感測器是 OV5640(驅動 ov5640.c 已在 Linux mainline)。

先確認:查你板卡 BSP / 社群 overlay 的「已知可用組合」再動手。

1.5 深入原理:CSI-2 與 ISP 硬體區塊

「能不能接相機」最終由 SoC 的硬體 IP 區塊決定,而不是板卡品牌。Orange Pi 常見的兩條路線各有一套硬體結構:

SoCCSI-2 接收器ISP頻道/VC
RK35884× MIPI CSI-2 D-PHY(可達 2.5 Gbps/lane)有(Rockchip ISP3)多 virtual channel
H618 / H6161× 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 成功時把感測器掛上圖。

為什麼要懂這一層:所有「沒畫面」的除錯,最後都要回到「硬體區塊有沒有被 kernel 建立並連結」。理解 media graph 就等於拿到一張「相機系統的電路圖」。

1.6 完整 Worked Example:盤點你手上的板卡

拿到任何一片 Orange Pi,第一步是「盤點生態」:知道 kernel 有沒有內建相機支援、I2C 有哪些 bus、video 節點存在與否。下面從登入到列管的完整流程:

步驟 1|確認 SoC 與 kernel
uname -a                          # 看架構與 kernel 版本
cat /etc/os-release | head -3     # 確認發行版(Armbian / Orange Pi OS…)
步驟 2|找相機相關節點與驅動
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"
步驟 3|列出 I2C bus
ls /dev/i2c-*                     # 找相機掛在哪個 bus
sudo i2cdetect -l                 # 每個 bus 的編號與種類
步驟 4|media graph 一覽
media-ctl -p -d /dev/media0 2>/dev/null || echo "無 /dev/media0"
完成標準:你能回答三件事:① 是哪顆 SoC;② 系統有沒有建立相機節點;③ 相機 I2C 掛在哪個 bus。這三題就是單元 6 bring-up 的起點。

1.7 疑難排解決策樹:這片板卡能不能做相機?

節點問題下一步
/dev/video0相機節點已存在直接看單元 5 取流
/dev/video0,dmesg 有 probe 失敗驅動/DT 有問題單元 6 dmesg 除錯
無節點、dmesg 完全沒有相機字樣DT 未啟用相機節點查 BSP 的 overlay / config,啟動 CSI + I2C
有節點但 media-ctl -p管線未連結單元 5 media-ctl 建 link
常見錯誤與陷阱:許多人一拿到板卡就急著買鏡頭、看「能不能拍照」。真正的檢查順序是 節點 → 驅動 → I2C → 出圖。BSP 的「已知可用組合」是最短捷徑——先確認你要接的模組與官方支援清單一致,否則第一步就卡住。

1.8 練習

  1. 在真機上執行 Worked Example 的四步驟,記錄 uname -als /dev/video*、I2C bus 清單。
  2. dmesg 找出你板卡 kernel 中與相機相關的三條訊息,寫出它們的意義。
  3. 查你板卡 BSP 的「已知可用相機組合」,把它貼進你的筆記。
  4. 畫出你板卡的 media graph 草圖(感測器 → CSI → video),對照 media-ctl -p 輸出。

1.9 進階真實情境 Worked Example:RK3588 雙感測器盤點

場景:RK3588 板卡(如 Orange Pi 5 Plus)同時接 OV5640 + OV9281(IR),在啟動後快速盤點兩顆感測器的生態位置。

步驟 1|確認 SoC 與 media device 數量
cat /proc/device-tree/compatible | tr '\0' '\n' | head -1
ls /dev/media*          # RK3588 可能有多個 media device
步驟 2|列出所有 video device 與 subdev
v4l2-ctl --list-devices
ls /dev/v4l-subdev*
步驟 3|逐顆掃 I2C 並讀 ID
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)
步驟 4|media graph 雙管線確認
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"
設計決策:RK3588 有 4 組 MIPI CSI-2 接收器,可同時接多顆感測器。盤點時要確認每顆的 I2C bus、media device、video node 一一對應——這是多相機系統的基礎架構。

1.10 深入原理擴充:RK3588 RGA 與 Allwinner CIF 差異

Orange Pi 的 ISP 生態有兩條截然不同的硬體路線:

SoC影像處理 IP關鍵差異
RK3588RGA(Raster Graphic Acceleration)+ ISP3RGA 可做即時旋轉/縮放/color space 轉換;ISP3 有完整 3A 管線
Allwinner H618CIF(Camera Interface)CIF 只負責接收 MIPI 資料,無獨立 ISP 模組——色彩校正全靠感測器端

容易忽略的邊界案例:RK3588 的 RGA 模組雖然是硬體加速,但它不在 V4L2 media graph 內——而是透過 /dev/rga 獨立的 IOCTL 介面操作。這意味著你不能用 media-ctl 管理 RGA,必須在 userspace 另外串接。這是在 RK3588 上做即時後處理時最常忽略的架構限制。

實務影響:如果你的管線需要「ISP 出 YUV → RGA 旋轉 → 編碼」,這段鏈路不能用 media-ctl 一鍵設定,需要 GStreamer 或自寫程式分段串接。

1.11 診斷式疑難排解表

症狀可能原因解決方案
media-ctl -p 顯示 entity 但 link 全斷DT overlay 未啟用 media controller確認 boot config 有 media_controller=1,或手動 media-ctl -l
RK3588 多顆感測器但只有一個 /dev/video0DT 只 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=yCONFIG_VIDEO_V4L2_SUBDEV_API=y

1.12 進階挑戰題

  1. 在 RK3588 板卡上同時接 OV5640 與 OV9281,手動建立兩條 media pipeline(含 link 與 format),驗證兩路可同時取流。畫出你的 media graph 圖,標註每條路徑的 entity 與 link。
  2. 對比 RK3588 與 Allwinner H618 在「media controller 支援度」上的差異:列出三項可用工具、三項不可用工具,並解釋原因。
  3. 假設你的 DT overlay 誤將 OV5640 的 clock-frequency 設為 12MHz(正確為 24MHz),從 dmesg 到 i2cdetect 到 media-ctl,逐步寫出你會看到什麼症狀、以及如何定位到 clock 錯誤。

1.13 專案級 Worked Example:完整感光元件 bring-up 專案 — 從 DT overlay 到第一張圖

把單元 1–6 的知識串成一個端到端專案:從一片空白板卡開始,完成「DT overlay → probe → 管線 → 第一張圖」。這是你在這門課第一個可交付的里程碑。

階段 1|盤點平台(單元 1)
uname -a
ls /dev/video* /dev/v4l-subdev* 2>/dev/null
sudo i2cdetect -l
階段 2|寫 DT overlay(單元 6)
# 最小 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>;
  };
};
階段 3|probe 驗證 + 讀 ID(單元 3)
dmesg | grep -i -E "ov5640|probe"
sudo i2cget -y 3 0x3c 0x300a    # 預期 0x56
階段 4|建管線取第一張圖(單元 5)
media-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 文件上寫出「這片板卡 + 這顆鏡頭」的已知可用組合:SoC、I2C bus、位址、clock、lane、格式。這就是你所有後續調校的基石。

1.14 量測/驗證 SOP:板卡相機生態驗收

在動手接任何鏡頭之前,先用固定 SOP 把板卡的相機生態「量」清楚,避免盲目投資。

步驟指令通過判據
1. 確認 SoCcat /proc/device-tree/compatible | tr '\0' '\n'清楚寫出 RK3588 / H618 / H616
2. 列 video 節點ls /dev/video* /dev/v4l-subdev*節點存在;數量與預期相符
3. 列 I2C bussudo i2cdetect -l知道相機該掛哪個 bus
4. media graphmedia-ctl -p -d /dev/media0entity 清單與 DT 一致
5. 讀感測器 IDsudo i2cget -y 3 0x3c 0x300a回 0x56(OV5640)
SOP 產出:驗收結果寫成一頁「平台盤點表」,作為 bring-up 專案(1.13)的前置文件。之後每次換板卡都重跑一遍。

1.15 平台間對照:相機生態總覽

面向Orange PiRPi5Orin NanoThor
代表 SoCRK3588 / H618BCM2712Orin Nano(Ampere)T5000(Blackwell)
CSI 接收器RK3588 4× CSI-2 / H618 1×2× CSI-2(4-lane)CSI-2(最多 16-lane)CSI-2 + 更高速介面
平台 ISPRK3588 有 / H618 無硬體 ISP(開源)NVIDIA ISPNVIDIA ISP + Blackwell
控制介面V4L2 subdev / media-ctllibcamerategracam / ArgusHoloscan / GXF
常見感測器位址0x3c(bus 3)0x3c(bus 22)0x36(bus 0)0x36(bus 0)
生態「已知可用組合」BSP 社群 overlaylibcamera 支援清單NVIDIA 相容表Holoscan 套件
跨平台要點:四平台都走「感測器 → CSI-2 → (ISP) → userspace」同一條物理路徑,差異只在抽象層。Orange Pi 學到的 V4L2/media-ctl 知識,搬到 RPi5 是 libcamera、搬到 NVIDIA 是 Argus——但 register 與時序是同一套。

1.16 互動式檢核清單:本單元進階驗收

checklist
- [ ] 我能背出我板卡的 SoC、CSI 數量、有無平台 ISP。
- [ ] 我能用 media-ctl -p 畫出板卡完整的 media graph。
- [ ] 我已跑完 1.14 SOP 並產出「平台盤點表」。
- [ ] 我能解釋「感測器位址 0x3c vs 0x36」的由來。
- [ ] 我能指出 RK3588 與 H618 在「調校能力」上的本質差異。
- [ ] 我已開始 1.13 專案,至少完成階段 1 盤點。

1.17 Register 位元級完整工作流

單元 1 的「register 操作」集中在 media controller 與 I2C device discovery。以下是以 OV5640 為例的「讀→改→寫→驗證」完整位元級序列:

步驟暫存器/位址位元欄位操作預期值
1. 掃描 I2Cbus 3 全位址i2cdetect -y 30x3c 出現
2. 讀感測器 ID0x300A[7:0] = chip ID highi2cget -y 3 0x3c 0x300a0x56
3. 讀感測器 ID0x300B[7:0] = chip ID lowi2cget -y 3 0x3c 0x300b0x40
4. 驗證 PLL 準備0x3035[7:4] PLL Predivi2cget ... 0x3035依 DT clock 設定
5. 確認 reset 釋放GPIO debugreset-gpios levelcat /sys/kernel/debug/gpio | grep resethigh(active-low 釋放)
6. media-ctl 建 link/dev/media0entity 0 pad 0 → entity 1 pad 0media-ctl -l "...:0->...:0[1]"link 設為 active
位元級關鍵:I2C read 結果 0xFF = 無裝置回應(上拉/位址問題);0x00 = reset 未釋放。這兩個值是所有 I2C 除錯的起點。

1.18 多層疑難排解決策樹

決策樹 A:板卡完全找不到相機

決策樹 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 但沒畫面

決策樹 B
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.19 量測驗證完整 SOP

步驟指令預期輸出判讀標準
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 bussudo i2cdetect -l列出所有 bus 編號知道相機掛哪個 bus
4. I2C 掃描sudo i2cdetect -y 30x3c 出現感測器 I2C 可達
5. 讀感測器 IDsudo i2cget -y 3 0x3c 0x300a0x56ID 與 datasheet 相符
6. dmesg probedmesg | grep -i ov5640"probe success"無 error/warning
7. media graphmedia-ctl -p -d /dev/media0sensor → csi → video entitieslink 與 DT 一致
8. 取一幀v4l2-ctl --stream-mmap=1 --stream-count=1成功產出 YUV 檔sizeimage 正確

1.20 四平台終極對照

面向Orange PiRPi5Orin NanoThor推薦
代表 SoCRK3588 / H618BCM2712Orin NanoT5000依需求
CSI 接收器4× / 1×2× (4-lane)多路 CSI多路 CSI多相機→RK3588
平台 ISPRK3588 有 / H618 無硬體 ISPNVIDIA ISPBlackwell ISP畫質→NVIDIA
控制介面V4L2 subdevlibcameraArgusHoloscan底層→Orange Pi
media controller✅ 開放libcamera 抽象封閉封閉學習→Orange Pi
I2C 工具i2c-tools 全支援i2c-tools需權限需權限Orange Pi 最自由
DT overlaydtbo + dtoverlayconfig.txtBoard configHoloscanOrange Pi 最透明
除錯深度完全可見低(封閉)低(封閉)除錯→Orange Pi

1.21 完整 Bring-up 專案 Checklist

checklist
- [ ] 確認 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
看完這單元你應該能說出:
  • Orange Pi 的 SoC 決定相機能力。
  • V4L2 / media controller 管線。
  • OV5640 是 Linux 上最常見 OV 感測器。
  • 先確認板卡 BSP 支援。
  • media graph 中 entity/link 的意義。
  • 用四步 Worked Example 盤點板卡相機生態。

延伸閱讀