單元 4 · 平台相機框架與驅動

Jetson 堆疊 + Holoscan

Thor 的相機框架

Thor 沿用 Jetson 的 V4L2 + Argus 堆疊,並以 Holoscan 做高效感測器資料處理。

感測器驅動V4L2/ArgusHoloscan 管線GPU/ISP
調整重點:Orin 上學的 V4L2/Argus 技能在 Thor 可延用;新的是 HSB 這條「感測器進 GPU」的快速通道。

HSB 的配置

⚠️ 需官方文件確認:Thor 的 HSB 感測器配置與驅動細節仍在演進。

4.3 深入原理:V4L2/Argus/Holoscan 的分工與資料流

三者不是同層的替代品,而是「控制面」與「資料面」的分工:

角色誰在用
V4L2(含 subdev)Linux 標準相機/感測器介面、register 與格式控制內核驅動、v4l2-ctl、media-ctl
ArgusNVIDIA 應用層相機 API(控制 + 取流)argus_camera、你的 app
HoloscanGPU 資料處理框架(感測器→CUDA→推理)物理 AI 管線
感測器驅動(subdev)V4L2 video nodeArgus 封裝Holoscan OperatorGPU 處理
核心領悟:Argus 底下還是 V4L2;Holoscan 底下可能接 Argus 也可能直接接 V4L2。除錯時層層往下問:「是 register 沒設對(subdev),還是 buffer 沒到(V4L2),還是管線沒接(Holoscan)?」

4.4 Worked Example:看一張感測器圖(media graph)

media-ctl 讀出整條感測器管線
media-ctl -p -d /dev/media0
# 預期看到:ov9281 0x0036 subdev → csi → vi → video(/dev/video0)
# 檢查:
#  1. 感測器 subdev 是否 probe(有 node)
#  2. link 是否 enable(→ 方向正確)
#  3. /dev/video0 的 format 是否與感測器 mode 相符
通過標準:能看到「感測器 → CSI → VI → video」四層 node 且 link 全啟用,代表 DTB/驅動層已通。接著才是取流(unit-05)與畫質(unit-07 起)。

4.5 疑難排解決策樹:感測器沒有 probe

「media graph 看不到感測器 subdev」
1. dmesg 有 probe error?
   ├─ 是 → 看 error 碼(unit-06 對照表)
   └─ 否 ─┐
2. DTB overlay 有啟用該感測器 node?
   ├─ 否 → 檢查 compatible 是否匹配驅動
   └─ 是 ─┐
3. i2c address 在 DTB 與硬體一致?
   ├─ 否 → 修正 reg
   └─ 是 ─┐
4. 感測器供電/clock/reset 由 GPIO 管?
   └─ 是 → 查 power/reset 設定(unit-06)

⚠️ Thor 的 HSB 感測器以「host 端 Holoscan 通道」呈現,看不到傳統 media graph 時,改用 Holoscan 診斷工具確認資料是否進 GPU。

4.6 常見錯誤與陷阱

陷阱 1:改 DTB 沒重建 kernel——overlay 沒生效,media graph 自然沒變化。用 dmesg 確認 overlay 有被載入。
陷阱 2:Argus 的「相機編號」與 V4L2 node 對不上——Argus 依 sensor mode 與 topology 分配,不保證對應 /dev/video0。用 argus_camera --list-cameras 對照。
陷阱 3:HSB 感測器沒有 /dev/videoN——走 HSB 的感測器資料不經傳統 VI,別拿「沒有 video node」當作感測器沒通;改用 Holoscan 通道驗證。

4.7 深入:Holoscan 在 Thor 上的「感測器來源」Operator

Holoscan 管線以 Operator 為單位:感測器資料進入管線時,由一個「感測器來源 operator」負責與底層(Argus 或 HSB channel)銜接,輸出 VideoFrame 給後續 GPU operator。

Holoscan 感測器來源(概念)
# 管線示意(非完整程式碼)
Application:
  ├─ SensorSourceOp(讀取感測器資料)
  ├─ PreprocessOp(resize/轉格式,GPU)
  ├─ InferenceOp(模型推理)
  └─ SinkOp(輸出/顯示)
# 除錯時先確認 SensorSourceOp 有輸出,再查下游
對照:對 Argus 開發者來說,Holoscan 的來源 operator ≈ Argus 的「CameraProvider + Request」;只是多了 GPU 直連 buffer 與圖形管線語法。概念能平移。

4.8 練習

  1. 執行 media-ctl -p,畫出你的感測器管線圖。
  2. 用 dmesg 找出感測器 probe 的關鍵 log 行。
  3. 列出 Argus、V4L2、Holoscan 各自「你該用哪個指令」來驗證。
看完這單元你應該能說出:
  • Thor 沿用 Jetson V4L2/Argus。
  • Holoscan 在感測器處理角色。
  • HSB 資料路徑與 I2C 橋接。
  • Orin 技能可平移、HSB 是新技能。

延伸閱讀

4.9 進階真實情境 Worked Example:從 V4L2 遷移到 Holoscan 的雙軌並行

場景:團隊原本在 Orin Nano 上用 V4L2 + Argus 取流跑瑕疵偵測,現在要遷移到 Thor T5000。同時要支援 CSI(實驗室原型)與 HSB(量產部署)兩種路徑。

雙軌架構設計
# Phase 1:CSI 路徑(實驗室,與 Orin 相同語法)
Argus → SensorMode → v4l2 video node → ISP → CUDA
# 驗證:media-ctl -p 看到完整管線;argus_camera 出圖

# Phase 2:HSB 路徑(量產,乙太網路)
SensorSourceOp(Holoscan)→ ISP operator → CUDA operator
# 驗證:Holoscan log 確認 SensorSourceOp 有輸出 VideoFrame

# 共用層:ISP 調校參數、CUDA 推理模型、後處理邏輯
# 差異層:感測器來源(Argus vs Holoscan SensorSource)

# 設計決策:
# 1. 抽象化「感測器來源」:上層 app 不直接呼叫 Argus/V4L2,而是透過 interface
# 2. CSI 路徑用 Argus、HSB 路徑用 Holoscan——切換只換 source operator
# 3. ISP 調校參數與 CUDA 模型兩路徑共用,避免維護兩套
設計決策:遷移的關鍵不是「把 V4L2 換成 Holoscan」而是「抽離感測器來源」。把 app 分成「source / processing / output」三層,source 層因路徑而異,其餘共用。這才是 Orin → Thor 的最小變更遷移路徑。

4.10 深入原理擴充:Holoscan 的 Operator Graph 與 GPU Direct

Holoscan 以 directed acyclic graph(DAG)組織 operator。每個 operator 可宣告其 I/O 為 GPU memoryhost memory。當相鄰 operator 都在 GPU memory 上操作時,資料不需要在 CPU↔GPU 之間來回搬移(zero-copy)。Thor 的 Blackwell GPU 支援 CUDA unified memory + GPUDirect,讓感測器 DMA 直接寫入 GPU 記憶體, Holoscan operator 從頭到尾在 GPU 上運行。

容易忽略的邊界案例:若 Holoscan operator graph 中混入一個宣告為 host memory 的 operator(例如 Python callback),整條管線會被強制插入 GPU↔CPU 拷貝。在 60 fps 的多感測器管線中,一次這樣的拷貝可能增加 2–3 ms 延遲。除錯方式:在 Holoscan log 中搜尋 "transfer" 或 "copy" 關鍵字,找出不該存在的記憶體搬移。

4.11 診斷式疑難排解表

症狀可能原因解決方案
media graph 有感測器 node 但 argus_camera 找不到Argus 的 camera enumeration 與 V4L2 node 不對應用 argus_camera --list-cameras 對照 media-ctl 輸出;確認 sensor mode 與 Argus enumerate 一致
Holoscan SensorSourceOp 啟動後無 VideoFrame 輸出HSB channel 未連接或格式設定不匹配檢查 Holoscan 設定檔中的 sensor channel 與 format;用 ip link show 確認乙太網路 link up
DTB overlay 重建後 dmesg 無變化overlay 未被 kernel 載入(U-Boot 或 extlinux 未更新)確認 /boot/extlinux 或 U-Boot 的 overlay 路徑正確;用 dmesg | grep overlay 確認載入
V4L2 subdev 存在但 format 設定被拒感測器 mode 的 format 不在支援清單中v4l2-ctl --list-formats-ext 查看所有支援的 format/mode 組合
Holoscan 管線啟動但 GPU 使用率異常低Operator 未宣告 GPU memory,所有資料走 CPU 拷貝檢視每個 operator 的 I/O 設定;確保 SensorSourceOp 直接輸出 GPU buffer

4.12 進階挑戰題

  1. 設計一個 Holoscan operator DAG:SensorSource → ISP → Resize(GPU)→ YOLO Inference(GPU)→ NMS(CPU)→ Display。計算在「NMS 改成 GPU」前後的端到端延遲差異,並說明 GPUDirect 在此管線中的效益。
  2. 若你在 Thor 上同時使用 CSI 路徑(4 顆感測器)與 HSB 路徑(2 顆感測器),畫出完整的 media graph + Holoscan graph 交織架構,標出哪些層級共用、哪些獨立。
  3. 分析 Argus 與 Holoscan 在 buffer management 上的差異:Argus 用 Request/Buffer queue,Holoscan 用 Tensor/VideoFrame。設計一個 adapter layer 讓同一個 ISP 調校參數集能同時服務兩種 buffer 抽象。

4.13 專案級端到端 Worked Example:框架建立專案 — 從 DTB overlay 到 Holoscan 管線

場景:團隊要在 Thor 上建立「一個可切換路徑」的相機框架:同一顆感測器能在 CSI(實驗室)與 HSB(量產)間切換,驅動與上層框架共用。

里程碑規劃
M1 DTB overlay(CSI 路徑)
   ├─ 建立 ov9281_csi.dtso(compatible/reg/clocks/reset-gpios)
   ├─ 編譯並載入
   └─ 通過:dmesg probe 成功、media graph 出現 subdev

M2 V4L2 框架驗證
   ├─ media-ctl 確認 link、v4l2-ctl 列出 formats
   └─ 通過:/dev/video0 存在、format 正確

M3 Argus 層
   ├─ argus_camera --list-cameras 對照 video node
   └─ 通過:Argus 能列舉並取流

M4 Holoscan 管線
   ├─ 建立 SensorSourceOp → SinkOp 的最小管線
   └─ 通過:Holoscan log 顯示 VideoFrame 輸出

M5 路徑抽象
   ├─ 定義 source interface(CSI 實作 + HSB 實作)
   └─ 通過:切換 source 實作,上層 app 不變

M6 回歸
   └─ 通過:兩路徑取流 + RAW 內容一致
專案要點:framework 專案的成敗在「抽象邊界」。把「感測器來源」抽成 interface,CSI/HSB 只是兩種實作——這讓 Orin→Thor 遷移、CSI→HSB 切換都是小改動。

4.14 量測 / 驗證 SOP:相機框架分層驗證

框架 SOP(Step 1–6)
Step 1 驅動層
   dmesg | grep -i -E "ov9281|probe|tegra-capture"
   # 通過:無 error、probe 成功
Step 2 裝置節點
   ls /dev/video* /dev/media* /dev/v4l-subdev*
Step 3 media graph
   media-ctl -p -d /dev/media0
   # 通過:感測器→CSI→VI→video 四層全啟用
Step 4 格式清單
   v4l2-ctl -d /dev/video0 --list-formats-ext
Step 5 Argus 對照
   argus_camera --list-cameras
Step 6 Holoscan
   跑最小管線,確認 SensorSourceOp 輸出

判讀指標:
  media graph 缺層 → DTB/驅動問題
  Argus 找不到 → sensor mode 對照問題
  Holoscan 無輸出 → HSB channel 或格式不匹配

4.15 平台間對照:相機框架與驅動

面向Thor T5000RPi5Orange PiOrin Nano
使用者層框架V4L2 + Argus + Holoscanlibcamera(rpicam)V4L2V4L2 + Argus
驅動模型tegracam(V4L2 subdev)libcamera driverV4L2 subdevtegracam(V4L2 subdev)
GPU 資料框架✅ Holoscan(GPUDirect)❌(CPU 為主)⚠️ 部分(CUDA 可用)
HSB 感測器通道✅ Holoscan channel
DTB overlay✅ 標準✅ dtoverlay 檔✅ DTB✅ 標準
選擇思考:Thor/Orin 的驅動模型同源(tegracam + Argus),Orin 的技能幾乎可平移。RPi5 的 libcamera 是不同框架——但「感測器 register」與「V4L2 概念」仍是共通語言。

4.16 互動式檢核清單

4.18 Register 位元級完整工作流

本單元涉及的關鍵 register,以及「讀→改→寫→驗證」的完整位元級操作序列:

Register位址功能Bit Field 說明
NVCSI_INT_STATUS0x0c0a0000CSI 中斷狀態bit[0]=phy_sync_done, bit[4]=crc_error, bit[8]=ecc_error
讀→改→寫→驗證 完整序列(以 NVCSI_INT_STATUS 為例)
# Step 1: 讀取目前值
$ devmem2 0x0c0a0000 w
# 記錄 current_value

# Step 2: 計算新值
$ new_value=$(current_value | 0x0001)

# Step 3: 寫入
$ devmem2 0x0c0a0000 w $new_value

# Step 4: 驗證讀回值與預期一致
$ devmem2 0x0c0a0000 w
$ [ "$(devmem2 0x0c0a0000 w | grep Read)" = "expected" ] && echo "PASS" || echo "FAIL"

4.19 多層疑難排解決策樹

決策樹 1:V4L2 裝置未出現
1. `/dev/video*` 不存在?
   ├─ `lsmod | grep nvidia` → 驅動未載入
   │  └─ 確認 kernel module: `modprobe tegra-v4l2` 或 check dmesg
   └─ module 已載入但無 video device → DT node 問題
      ├─ `cat /proc/device-tree/soc/csi*/compatible` 確認 compatible string
      └─ overlay 未 apply → 重跑 ubootOverlayApply
決策樹 2:Argus/Holoscan pipeline 開啟失敗
1. `nvgstcapture-1.0` 出錯?
   ├─ error "cannot find element" → pipeline config 缺少 sensor element
   └─ error "device busy" → 另一 process 佔用,`fuser /dev/video0`
2. Holoscan operator 無法創建?
   ├─ `libholoscan.so` 未找到 → 確認 LD_LIBRARY_PATH
   └─ sensor operator 報錯 → 檢查 yaml config 的 sensor type

4.20 量測驗證完整 SOP

框架層完整驗證 SOP:

步驟動作指令/方法預期輸出
Step 1確認 kernel module`lsmod | grep tegra`tegra-v4l2, tegra-csi 出現
Step 2確認 video device`ls /dev/video*`/dev/video0 存在
Step 3V4L2 能力查詢`v4l2-ctl -d /dev/video0 --info`Driver info 正確
Step 4format 列表`v4l2-ctl -d /dev/video0 --list-formats-ext`支援 RAW10 等
Step 5nvgstcapture 測試`nvgstcapture-1.0 -m 1`擷取一張 JPEG
Step 6Holoscan sample`python3 holoscan_sample.py`pipeline 正常結束
Step 7效能基準`v4l2-ctl --stream-mmap --stream-count=100 --stream-to=/dev/null`100 幀無 drop

4.21 四平台終極對照

面向Thor T5000RPi5Orange PiOrin Nano
相機框架V4L2 + Argus + HoloscanV4L2 + libcameraV4L2 directV4L2 + Argus
Device Treeoverlay + ubootOverlayApplydtoverlay= (auto)armbianEnv.txt 或 boot.scrhardkernel .dtb
相機 HALNVIDIA Camera HALlibcamera (rpi.cam)libv4l2NVIDIA Camera HAL
GPU 整合Holoscan + CUDA + GPUDirectOpenCV (CPU)OpenCV (CPU)CUDA + nvbufsurface
多 camera 串流能力16 lane, 6+ sensor2 sensor1 sensor4 sensor
live view 工具`nvgstviewer``libcamera-hello`ffplay / v4l2-ctl`nvgstviewer`

4.22 完整 Bring-up 小 Checklist

針對「平台相機框架與驅動」主題的完整 bring-up 步驟清單: