CSI/GMSL、Argus/V4L2
支援 MIPI CSI-2,並可透過 GMSL(Gigabit Multimedia Serial Link)接遠距離多感測器。
| 框架 | 用途 | 調校角色 |
|---|---|---|
| V4L2 | 標準介面(v4l2-ctl、GStreamer) | 感測器控制 |
| Argus(libargus) | NVIDIA 原生相機 API | 進階控制 + ISP |
Orin Nano 常搭配 OV9281(global shutter)、OV5640、官方 Camera Module(IMX219/477)。
MIPI CSI-2 是點對點串列介面。Orin Nano 的 CSI 控制器收 D-PHY:4 條 data lane + 1 條 clock lane,每條 lane 是差動對(HS 高速傳資料、LP 低功耗傳控制)。
| 名詞 | 說明 | 對除錯的意義 |
|---|---|---|
| lane | 差動資料通道 | lane 數不足 → 頻寬不足 → 掉幀 |
| HS / LP | 高速資料 / 低功耗控制態 | HS 才傳影像,LP 管喚醒與開機 |
| data type | packet 標記內容(RAW8/RAW10/YUV…) | 格式宣告錯 → 畫面全錯 |
| virtual channel | 同一介面分多邏輯通道 | 多感測器共用 CSI 時依賴此機制 |
時序上:感測器送 frame start → 逐列 line → frame end。列與列間的空檔(blanking)留給時脈裕度與曝光調度;Orin 的 RTCPU 負責依 DTB 的時序參數收 frame。
GMSL(Gigabit Multimedia Serial Link)把 MIPI 訊號「串列化」後走同軸電纜,拉長距離後再由 deserializer 還原成 MIPI。
# 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. 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 出圖 → ✅
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
| 項目 | 值 / 指令 |
|---|---|
| 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 |
# 一幀資料量 = 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 ⚠ 接近上限
# 算出來逼近可用頻寬 → 掉幀風險,需降解析度/幀率/位元深場景:自駕小車需要同時使用前(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。
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 instance | NVIDIA ISP 一次可處理的 pipeline 數 | 多路同時走 ISP 時可能降速(bandwidth sharing) |
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| 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 編號與實體排線 |
場景:你拿到一張新載板,上面只有一顆 OV9281(CSI-2 直連、2-lane、I2C 0x36、MCLK 24MHz),JetPack 已刷好但相機完全未設定。這個專案把單元 1–6 的知識串成端到端流程:從「零」到「第一張圖 + 第一份 RAW」,並留下可重複的專案腳本。
cat /etc/nv_tegra_release # 記錄 JetPack 版本 dmesg | grep -i tegra-camera-rtcpu # 預期:rtcpu 正常載入、無 error ls /boot/dtb/ # 記錄現有 DTB / overlay
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/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 完整鏈路
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。
目的:確認這張板子的相機能力與規格聲明相符,留下可對比的基線。換硬體或重刷 JetPack 後重跑。
cat /etc/nv_tegra_release;dmesg | grep -i rtcpu → RTCPU 正常載入。v4l2-ctl --list-devices → 記錄 /dev/videoN 與 subdev 數量。media-ctl -p -d /dev/media0 → 記錄感測器→CSI→VI 鏈路完整性。v4l2-ctl -d /dev/video0 --list-formats-ext → 記錄 fourcc、尺寸、幀率。argus_camera --list-cameras + argus_camera --mode 0 --capture-auto 1 --duration 1 出圖。W×H×bits×fps(回顧 1.13),記錄餘裕比例。| 面向 | Orin Nano | RPi5 | Orange Pi | Thor |
|---|---|---|---|---|
| CSI 輸入 | MIPI CSI-2 + GMSL | MIPI CSI-2(22-pin) | MIPI CSI-2(部分型號) | MIPI CSI-2 + GMSL(HSB) |
| GMSL 多感測器 | ✅(MAX96712 類) | ❌(需外接) | ❌ | ✅ 內建 |
| ISP 形態 | NVIDIA ISP(自動化) | libcamera(開源) | 感測器內建(陽春) | Blackwell + Holoscan |
| 相機框架 | Argus / V4L2 | libcamera / V4L2 | V4L2 | Argus / Holoscan |
| VI/擷取通道 | 3 個 VI channel | 1-2 路 | 1-2 路 | 多路 |
| 步驟 | 操作 | 暫存器 | Bit Field | Mask | Expected |
|---|---|---|---|---|---|
| 1. 讀 lock 狀態 | i2cget | 0x0013 | link0_lock | 0x01 | 0x01 |
| 2. 讀 link1 lock | i2cget | 0x0013 | link1_lock | 0x02 | 0x02 |
| 3. 讀 link2 lock | i2cget | 0x0013 | link2_lock | 0x04 | 0x04 |
| 4. 讀 link3 lock | i2cget | 0x0013 | link3_lock | 0x08 | 0x08 |
# 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"
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 / 色彩空間 └─ 正常 → ✅
1. argus 同時開 N 路失敗? ├─ 是 ┐ │ 2. dmesg 有 "resource busy"? │ ├─ 是 → VI channel 用盡(Orin Nano 最多 3 個) │ │ 方案:降單路解析度 / bypass ISP / 外部 ISP │ └─ 否 ┐ │ 3. ISP bandwidth 超限? │ ├─ 是 → 降單路幀率或解析度 │ └─ 否 → DTB lane / VC 分配錯誤 └─ 否 → 逐路驗證後再嘗試同時開
cat /etc/nv_tegra_release;記錄 JetPack 版本。dmesg | grep -i rtcpu → 預期:firmware loaded, 無 error。v4l2-ctl --list-devices → 記錄 /dev/videoN 數量。media-ctl -p -d /dev/media0 → 記錄感測器→CSI→VI 鏈路;確認 lane 數與 DTB 一致。i2cget -y 0 0x36 0x300a → 預期 0x92(OV9281)。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 → 預期:width × height × 2 bytes。W×H×bits×fps,記錄餘裕比例。| 面向 | Orin Nano | RPi5 | Orange Pi | Thor | 推薦 |
|---|---|---|---|---|---|
| CSI 輸入 | MIPI CSI-2 + GMSL | MIPI CSI-2(22-pin) | MIPI CSI-2(部分型號) | MIPI CSI-2 + GMSL | GMSL → Orin/Thor |
| GMSL 多感測器 | ✅(MAX96712) | ❌ | ❌ | ✅ 內建 | 工業多路 → Orin |
| ISP 形態 | NVIDIA ISP | libcamera 開源 | 感測器內建 | Blackwell + Holoscan | 自動化 → Orin/Thor |
| 相機框架 | Argus / V4L2 | libcamera / V4L2 | V4L2 | Argus / Holoscan | 全平台 V4L2 共通 |
| VI 通道數 | 3 VI channel | 1-2 路 | 1-2 路 | 多路 | 多路 → Orin/Thor |
| RTCPU 韌體 | ✅ 需確認 | 無 | 無 | ✅ 需確認 | Orin/Thor 開機必查 |
| 學習曲線 | 中高 | 中 | 低 | 高 | 初學 → RPi5 |
| 量產適用性 | ✅✅ | ✅ | ⚠️ | ✅✅ | 量產 → Orin |