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

CSI/GMSL、Argus/V4L2

Orin Nano 的相機能力

支援 MIPI CSI-2,並可透過 GMSL(Gigabit Multimedia Serial Link)接遠距離多感測器。

感測器serdes(GMSL)deserializer(MAX96712)CSINVIDIA ISP

雙相機框架

框架用途調校角色
V4L2標準介面(v4l2-ctl、GStreamer)感測器控制
Argus(libargus)NVIDIA 原生相機 API進階控制 + ISP
重點:Argus 是「完整調校」的入口——串起感測器控制、NVIDIA ISP 與輸出。

常見感測器模組

Orin Nano 常搭配 OV9281(global shutter)、OV5640、官方 Camera Module(IMX219/477)。

看完這單元你應該能說出:
  • Orin Nano 的 CSI + GMSL 架構。
  • V4L2 與 Argus 的分工。
  • GMSL serdes 在工業相機的角色。
  • 常見 OmniVision 感測器模組。

1.4 深入原理:MIPI CSI-2 位元流

MIPI CSI-2 是點對點串列介面。Orin Nano 的 CSI 控制器收 D-PHY:4 條 data lane + 1 條 clock lane,每條 lane 是差動對(HS 高速傳資料、LP 低功耗傳控制)。

名詞說明對除錯的意義
lane差動資料通道lane 數不足 → 頻寬不足 → 掉幀
HS / LP高速資料 / 低功耗控制態HS 才傳影像,LP 管喚醒與開機
data typepacket 標記內容(RAW8/RAW10/YUV…)格式宣告錯 → 畫面全錯
virtual channel同一介面分多邏輯通道多感測器共用 CSI 時依賴此機制

時序上:感測器送 frame start → 逐列 line → frame end。列與列間的空檔(blanking)留給時脈裕度與曝光調度;Orin 的 RTCPU 負責依 DTB 的時序參數收 frame。

1.5 深入原理:GMSL 的時序角色

GMSL(Gigabit Multimedia Serial Link)把 MIPI 訊號「串列化」後走同軸電纜,拉長距離後再由 deserializer 還原成 MIPI。

感測器 MIPIserializer(如 MAX96717)同軸線deserializer(MAX96712)Orin CSI
關鍵概念:GMSL 加了一層「link 建立」——serializer 與 deserializer 要先 lock(頻率對齊),資料才通。這就是為什麼 GMSL 除錯第一步永遠是「確認 lock」,而不是直接讀感測器。

1.6 Worked Example:從上電到看到第一張圖

Orin Nano + IMX219 / OV9281 第一次開機
# 1. 確認系統版本
cat /etc/nv_tegra_release
# 2. 確認相機驅動有 probe
dmesg | grep -i -E "imx219|ov9281|vi5|tegra-camera"
# 3. 列出 V4L2 裝置
v4l2-ctl --list-devices
# 4. 用 Argus 出圖(鏈路通的終極證明)
argus_camera --mode 0 --capture-auto 1 --duration 1

四步走完看到檔案 = 感測器 → CSI → NVIDIA ISP → 輸出 整條鏈路打通。之後才進入「控制」與「調校」。

1.7 疑難排解決策樹:argus 看不到相機

決策樹
1. dmesg 有 tegra-camera-rtcpu 嗎?
   ├─ 無 ─→ RTCPU firmware / DTB 問題
   └─ 有 ┐
2. 感測器驅動 probe 成功?
   ├─ 無 ─→ (GMSL) serdes lock?→ 線材/電源/overlay
   └─ 有 ┐
3. v4l2-ctl --list-devices 出現 /dev/video0?
   ├─ 無 ─→ media 管線沒接好(tegracam graph)
   └─ 有 ┐
4. argus_camera 出圖 → ✅

1.8 常見錯誤 / 陷阱

陷阱 ①:IMX219 與 OV9281 的 I2C 位址不同(IMX219=0x10、OV9281=0x36)——DTB 或 i2cdetect 用錯位址就會「找不到裝置」。
陷阱 ②:GMSL 模組在 Orin 上若沒先載入 deserializer 的 I2C alias,即使實體感測器正常也讀不到——這不是感測器壞,是「I2C 通道還沒切」。
陷阱 ③:Orin Nano 開發套件的 22-pin CSI 連接器是 4-lane,若使用其他板載配置,lane 數 / 電源腳位必須對齊,接錯可能燒模組。

1.9 練習

  1. 在 Orin 上跑完整「上電 → 列舉 → 出圖」流程並記錄輸出。
  2. 寫下你的平台:CSI lane 數、感測器型號、I2C 位址。
  3. 模擬一次 GMSL 模組:「先確認 lock、再讀 ID」的口訣背一遍。

1.10 進階:CSI 多通道與虛擬通道(VC)

Orin 的 CSI 支援 virtual channel:多顆感測器可共用同一個物理 CSI 介面,靠 packet 裡的 VC 標記區分。GMSL deserializer 通常把每一路 link 對應到一個 VC 或一個獨立 CSI 介面。

判斷你用的是哪種
# 看 media 拓撲:獨立介面 vs 共享 VC
media-ctl -p -d /dev/media0
# 多 VC 時每個 VC 有獨立的 /dev/videoN
v4l2-ctl --list-devices
除錯影響:若 DTB 把某路對到錯誤的 VC/lane,畫面會「串頻」或取到別顆的資料——先畫出拓撲再談問題。

1.11 快速參考:Orin Nano 相機小抄

項目值 / 指令
CSI 連接器22-pin,4-lane D-PHY
長距離多感測器GMSL + MAX96712 類 deserializer
出圖驗證argus_camera --mode 0 --capture-auto 1 --duration 1
列舉裝置v4l2-ctl --list-devices
感測器控制v4l2-ctl -d /dev/v4l-subdev0 -C exposure
官方模組IMX219 / IMX477

1.12 看完本單元該記住的三件事

Orin Nano 是「工業級」相機平台:CSI-2 + GMSL + NVIDIA ISP。
Argus 是完整調校入口,V4L2 是標準介面——兩者都要會。
「出圖成功」是鏈路通的終極證明,之後才談控制與調校。

1.13 Worked Example:估算 CSI 頻寬是否足夠

頻寬粗算
# 一幀資料量 = W × H × bits/pixel × 3/2(若 YUV420)
# 4-lane D-PHY 典型可用頻寬 ~2-4 Gbps(依 HS 時脈)
# 例:1280x800 RAW10 @ 120fps
1280 * 800 * 10 * 120 = 1,228,800,000 bps ≈ 1.2 Gbps ✓
# 例:3280x2464 RAW10 @ 30fps
3280 * 2464 * 10 * 30 = 2,424,576,000 bps ≈ 2.4 Gbps ⚠ 接近上限
# 算出來逼近可用頻寬 → 掉幀風險,需降解析度/幀率/位元深
除錯連結:「掉幀」不一定是感測器壞——先算頻寬(本單元),再看是否真的超限(回顧單元 11 幀率/頻寬)。

1.14 看完本單元該記住的三件事

Orin Nano = CSI-2 + GMSL + NVIDIA ISP,工業級平台。
Argus 完整調校入口,V4L2 標準介面。
出圖成功是鏈路通的終極證明。

延伸閱讀

1.15 進階真實情境 Worked Example:GMSL 四感測器同時串流啟用

場景:自駕小車需要同時使用前(OV9281)、後(OV9281)、左(IMX219)、右(IMX219)四顆感測器。前後走 GMSL 同軸線(15m),左右走 CSI 排線(短距)。

四路同時啟用工作流
# 1. 確認 MAX96712 四路 link 全部 lock
i2cget -y 0 0x48 0x13   # link0 lock bit
i2cget -y 0 0x48 0x14   # link1 lock bit
# 2. 確認 DTB 四個 camera 節點(含 lane/VC 分配)
dtc -I dtb -O dts -o /dev/stdout /boot/dtb/nv.dtb | grep -A20 "camera"
# 3. 逐路出圖驗證
v4l2-ctl -d /dev/video0 --stream-mmap=1 --stream-count=1 --stream-to=front.raw
v4l2-ctl -d /dev/video1 --stream-mmap=1 --stream-count=1 --stream-to=rear.raw
v4l2-ctl -d /dev/video2 --stream-mmap=1 --stream-count=1 --stream-to=left.raw
v4l2-ctl -d /dev/video3 --stream-mmap=1 --stream-count=1 --stream-to=right.raw
# 4. 用 Argus 同時開四路(確認 ISP pipeline 資源夠用)
argus_camera --camera 0,1,2,3 --mode 0 --duration 5

設計決策:GMSL 路走 OV9281(global shutter,遠距低延遲);CSI 短距走 IMX219(色彩較好,近距安裝)。四路共用 ISP pipeline 時要注意:Orin Nano 的 ISP bandwidth 有限,若四路全開高解析度會撞上限,需降單路解析度或 binning。

1.16 深入原理擴充:VI channel 與 Orin ISP 資源模型

Orin Nano 的影像擷取子系統(VI)有多個 channel,每個 channel 對應一個 /dev/videoN。VI channel 數量是硬體限制(Orin Nano 最多 3 個 VI channel),不是「介面夠不夠」的問題。

概念說明陷阱
VI channel硬體擷取通道數上限超出 → 某路無法開,但 dmesg 可能只報「resource busy」
CSI 介面物理連接數CSI 介面多不代表 VI channel 多,DTB 中的 port 節點要對齊
ISP instanceNVIDIA ISP 一次可處理的 pipeline 數多路同時走 ISP 時可能降速(bandwidth sharing)
大家以為沒問題但其實是陷阱:「DTB 宣告了四顆 camera,dmesg 都 probe 成功,但 argus 只能同時開三路」——原因不是驅動壞了,而是 VI channel 用盡。第四路需要走 bypass(不做 ISP 直接送 V4L2),或降單路解析度釋放 ISP 資源。

1.17 診斷式疑難排解表

症狀可能原因解決方案
argus_camera 回傳錯誤 code 但 v4l2-ctl 正常Argus 要求 ISP 但資源不足(VI channel 佔滿)先用 v4l2-ctl 確認幾路可用,再決定 Argus 同時開幾路
GMSL 模組上電後 dmesg 完全無感測器 probe 訊息deserializer I2C alias 未設定 或 DTB 缺少 serdes 節點檢查 DTB 的 i2c-mux / alias 節點;用 i2cdetect 掃描 deserializer 位址
多路同時串流時其中一路掉幀CSI 頻寬不足或 VI channel bandwidth 分配不均計算總頻寬(參照 1.13);降低其他路的解析度或幀率
argus 出圖全黑但 v4l2-ctl 出圖正常Argus 設定了錯誤的 output format(要求 YUV 但 ISP 未啟動)確認 Argus 的 output format 與 ISP pipeline 設定一致;用 nvarguscamerasrc 指定正確 format
感測器 I2C 讀得到 ID 但出圖色彩全錯DTB 中 lane assignment 或 virtual channel 設定與實際接線不符用 media-ctl -p 確認拓撲;比對 DTB lane 編號與實體排線

1.18 進階挑戰題

  1. 若你需要在 Orin Nano 上同時接 5 顆感測器(超過 VI channel 上限),設計一個「硬體 + 軟體」方案使 5 路都能出圖(提示:考慮 VI channel 限制、bypass 模式、外部 ISP)。
  2. 畫出你的 GMSL 多感測器系統的完整 I2C 拓撲圖:哪些位址是 serializer、哪些是 deserializer、哪些是感測器本身?標出每個 remap 的邏輯位址。
  3. 撰寫一個 bash script,自動化驗證 Orin Nano 上所有 `/dev/videoN` 是否都能正常串流,並輸出每路的「通過/失敗 + 幀數」。

1.19 專案級端到端 Worked Example:新載板 bring-up 專案 — 從 DT overlay 到第一張圖

場景:你拿到一張新載板,上面只有一顆 OV9281(CSI-2 直連、2-lane、I2C 0x36、MCLK 24MHz),JetPack 已刷好但相機完全未設定。這個專案把單元 1–6 的知識串成端到端流程:從「零」到「第一張圖 + 第一份 RAW」,並留下可重複的專案腳本。

Phase 0 · 事前盤點(10 分鐘)
cat /etc/nv_tegra_release          # 記錄 JetPack 版本
dmesg | grep -i tegra-camera-rtcpu # 預期:rtcpu 正常載入、無 error
ls /boot/dtb/                      # 記錄現有 DTB / overlay
Phase 1 · 建立 DT overlay(30 分鐘)
cat > ov9281-custom.dts <<'EOF'
/dts-v1/;
/plugin/;
/ {
    overlay-name = "ov9281 custom cam0";
    fragment@0 {
        target = <&i2c8>;
        __overlay__ {
            ov9281@36 {
                compatible = "ovti,ov9281";
                reg = <0x36>;
                clocks = <&clk_ext_cam 24000000>;
                clock-frequency = <24000000>;
                reset-gpios = <&gpio 132 0>;
                port {
                    ov9281_out: endpoint {
                        remote-endpoint = <&csi_in0>;
                        data-lanes = <1 2>;
                        clock-lanes = <0>;
                    };
                };
            };
        };
    };
};
EOF
dtc -@ -I dts -O dtb -o ov9281-custom.dtbo ov9281-custom.dts
sudo cp ov9281-custom.dtbo /boot/dtb/overlays/
Phase 2 · 套用並驗證(20 分鐘)
sudo reboot
dmesg | grep -i ov9281        # 預期:probe success + 讀到 chip ID
v4l2-ctl --list-devices       # 預期:出現 /dev/video0 + /dev/v4l-subdev0
media-ctl -p -d /dev/media0   # 預期:ov9281 → csi → vi 完整鏈路
Phase 3 · 出圖 + RAW 驗證(10 分鐘)
argus_camera --mode 0 --capture-auto 1 --duration 1   # 預期:成功存圖
v4l2-ctl -d /dev/video0 --stream-mmap=1 --stream-count=1 --stream-to=first.raw
ls -l first.raw   # 預期:1280x800x2 = 2,048,000 B(10-bit 以 16-bit 存)
# 第一張圖到手 = 專案里程碑 1 完成

專案驗收標準:① overlay 套用後 dmesg 無 error ② argus 出圖成功 ③ RAW 大小正確。失敗時回到對應單元:DTB → 單元 4、I2C → 單元 3、出圖 → 單元 5、時序 → 單元 6。

1.20 量測/驗證 SOP:平台相機生態能力驗證

目的:確認這張板子的相機能力與規格聲明相符,留下可對比的基線。換硬體或重刷 JetPack 後重跑。

  1. 系統與韌體cat /etc/nv_tegra_releasedmesg | grep -i rtcpu → RTCPU 正常載入。
  2. 列舉v4l2-ctl --list-devices → 記錄 /dev/videoN 與 subdev 數量。
  3. 拓撲media-ctl -p -d /dev/media0 → 記錄感測器→CSI→VI 鏈路完整性。
  4. 能力v4l2-ctl -d /dev/video0 --list-formats-ext → 記錄 fourcc、尺寸、幀率。
  5. 功能argus_camera --list-cameras + argus_camera --mode 0 --capture-auto 1 --duration 1 出圖。
  6. 頻寬:對最高模式算 W×H×bits×fps(回顧 1.13),記錄餘裕比例。
驗收指標:出圖成功、列舉完整、最高模式頻寬估算 < 可用頻寬 80%。結果寫入 team 基線文件。

1.21 平台間對照:相機生態

面向Orin NanoRPi5Orange PiThor
CSI 輸入MIPI CSI-2 + GMSLMIPI CSI-2(22-pin)MIPI CSI-2(部分型號)MIPI CSI-2 + GMSL(HSB)
GMSL 多感測器✅(MAX96712 類)❌(需外接)✅ 內建
ISP 形態NVIDIA ISP(自動化)libcamera(開源)感測器內建(陽春)Blackwell + Holoscan
相機框架Argus / V4L2libcamera / V4L2V4L2Argus / Holoscan
VI/擷取通道3 個 VI channel1-2 路1-2 路多路
結論:Orin 與 Thor 走「工業多感測器」路線,RPi5 走「開源學習」路線,Orange Pi 走「最低成本」路線。選平台第一問:「要不要 GMSL、要幾路相機」。

1.22 互動式檢核清單:相機生態驗收

1.23 Register 位元級完整工作流:MAX96712 Deserializer Lock 確認

步驟操作暫存器Bit FieldMaskExpected
1. 讀 lock 狀態i2cget0x0013link0_lock0x010x01
2. 讀 link1 locki2cget0x0013link1_lock0x020x02
3. 讀 link2 locki2cget0x0013link2_lock0x040x04
4. 讀 link3 locki2cget0x0013link3_lock0x080x08
Read → Modify → Write → Verify 完整流程
# Step 1: Read — 讀目前 lock register
val=$(i2cget -y 0 0x48 0x0013)
echo "lock register = 0x$(printf '%02x' $val)"

# Step 2: Modify — 設定 link 0 的 I2C remap(把遠端 0x36 映到 local 0x36)
i2cset -y 0 0x48 0x0000 0x36   # alias = 0x36
i2cset -y 0 0x48 0x0001 0x36   # source = 0x36

# Step 3: Write — 寫入後等待 100ms(serializer PLL 穩定)
sleep 0.1

# Step 4: Verify — 回讀確認值已生效
readback=$(i2cget -y 0 0x48 0x0000)
[ "$readback" -eq 0x36 ] && echo "VERIFY OK" || echo "VERIFY FAIL"
鐵則:GMSL register 操作的 Read→Modify→Write→Verify 四步不可省略。Write 後不 Verify 是 GMSL 除錯的第一大死因。

1.24 多層疑難排解決策樹

決策樹 A:Argus 看不到相機(四層判斷)
1. [硬體層] dmesg 有 tegra-camera-rtcpu?
   ├─ 無 ─→ RTCPU firmware / DTB 缺料(刷 JetPack)
   └─ 有 ┐
2. [I2C 層] i2cdetect 讀得到感測器?
   ├─ 無 ─→ (GMSL) serdes lock?→ 線材/電源/overlay
   │         (CSI) 位址/上拉/reset
   └─ 有 ┐
3. [驅動層] v4l2-ctl --list-devices 出現 /dev/video0?
   ├─ 無 ─→ media 管線沒接好(tegracam graph)
   └─ 有 ┐
4. [出圖層] argus_camera 出圖?
   ├─ 全黑 → 曝光 0 / 感測器沒輸出
   ├─ 綠紫 → pixel format / 色彩空間
   └─ 正常 → ✅
決策樹 B:VI channel 不足導致無法同時開多路
1. argus 同時開 N 路失敗?
   ├─ 是 ┐
   │   2. dmesg 有 "resource busy"?
   │      ├─ 是 → VI channel 用盡(Orin Nano 最多 3 個)
   │      │       方案:降單路解析度 / bypass ISP / 外部 ISP
   │      └─ 否 ┐
   │      3. ISP bandwidth 超限?
   │         ├─ 是 → 降單路幀率或解析度
   │         └─ 否 → DTB lane / VC 分配錯誤
   └─ 否 → 逐路驗證後再嘗試同時開

1.25 量測驗證完整 SOP

  1. 系統確認cat /etc/nv_tegra_release;記錄 JetPack 版本。
  2. RTCPU 驗證dmesg | grep -i rtcpu → 預期:firmware loaded, 無 error。
  3. 列舉v4l2-ctl --list-devices → 記錄 /dev/videoN 數量。
  4. 拓撲media-ctl -p -d /dev/media0 → 記錄感測器→CSI→VI 鏈路;確認 lane 數與 DTB 一致。
  5. I2C 通訊i2cget -y 0 0x36 0x300a → 預期 0x92(OV9281)。
  6. Argus 出圖argus_camera --mode 0 --capture-auto 1 --duration 1 → 預期:成功存圖。
  7. RAW 驗證v4l2-ctl -d /dev/video0 --stream-mmap=1 --stream-count=1 --stream-to=first.rawls -l first.raw → 預期:width × height × 2 bytes。
  8. 頻寬估算:對最高模式算 W×H×bits×fps,記錄餘裕比例。
  9. GMSL(如適用):逐路確認 lock → remap → 出圖。
  10. 多路(如適用):同時開 N 路,記錄掉幀數與 ISP bandwidth。
判讀標準:Step 1-6 全 pass 且 Step 7 帳案大小正確 = 平台相機生態能力基線建立完成。

1.26 四平台终极對照

面向Orin NanoRPi5Orange PiThor推薦
CSI 輸入MIPI CSI-2 + GMSLMIPI CSI-2(22-pin)MIPI CSI-2(部分型號)MIPI CSI-2 + GMSLGMSL → Orin/Thor
GMSL 多感測器✅(MAX96712)✅ 內建工業多路 → Orin
ISP 形態NVIDIA ISPlibcamera 開源感測器內建Blackwell + Holoscan自動化 → Orin/Thor
相機框架Argus / V4L2libcamera / V4L2V4L2Argus / Holoscan全平台 V4L2 共通
VI 通道數3 VI channel1-2 路1-2 路多路多路 → Orin/Thor
RTCPU 韌體✅ 需確認✅ 需確認Orin/Thor 開機必查
學習曲線中高初學 → RPi5
量產適用性✅✅⚠️✅✅量產 → Orin

1.27 完整 Bring-up 專案 Checklist