Jetson 堆疊 + Holoscan
Thor 沿用 Jetson 的 V4L2 + Argus 堆疊,並以 Holoscan 做高效感測器資料處理。
⚠️ 需官方文件確認:Thor 的 HSB 感測器配置與驅動細節仍在演進。
三者不是同層的替代品,而是「控制面」與「資料面」的分工:
| 層 | 角色 | 誰在用 |
|---|---|---|
| V4L2(含 subdev) | Linux 標準相機/感測器介面、register 與格式控制 | 內核驅動、v4l2-ctl、media-ctl |
| Argus | NVIDIA 應用層相機 API(控制 + 取流) | argus_camera、你的 app |
| Holoscan | GPU 資料處理框架(感測器→CUDA→推理) | 物理 AI 管線 |
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 相符
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。
dmesg 確認 overlay 有被載入。argus_camera --list-cameras 對照。Holoscan 管線以 Operator 為單位:感測器資料進入管線時,由一個「感測器來源 operator」負責與底層(Argus 或 HSB channel)銜接,輸出 VideoFrame 給後續 GPU operator。
# 管線示意(非完整程式碼) Application: ├─ SensorSourceOp(讀取感測器資料) ├─ PreprocessOp(resize/轉格式,GPU) ├─ InferenceOp(模型推理) └─ SinkOp(輸出/顯示) # 除錯時先確認 SensorSourceOp 有輸出,再查下游
場景:團隊原本在 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 模型兩路徑共用,避免維護兩套
Holoscan 以 directed acyclic graph(DAG)組織 operator。每個 operator 可宣告其 I/O 為 GPU memory 或 host memory。當相鄰 operator 都在 GPU memory 上操作時,資料不需要在 CPU↔GPU 之間來回搬移(zero-copy)。Thor 的 Blackwell GPU 支援 CUDA unified memory + GPUDirect,讓感測器 DMA 直接寫入 GPU 記憶體, Holoscan operator 從頭到尾在 GPU 上運行。
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| 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 |
場景:團隊要在 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 內容一致
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 或格式不匹配
| 面向 | Thor T5000 | RPi5 | Orange Pi | Orin Nano |
|---|---|---|---|---|
| 使用者層框架 | V4L2 + Argus + Holoscan | libcamera(rpicam) | V4L2 | V4L2 + Argus |
| 驅動模型 | tegracam(V4L2 subdev) | libcamera driver | V4L2 subdev | tegracam(V4L2 subdev) |
| GPU 資料框架 | ✅ Holoscan(GPUDirect) | ❌(CPU 為主) | ❌ | ⚠️ 部分(CUDA 可用) |
| HSB 感測器通道 | ✅ Holoscan channel | ❌ | ❌ | ❌ |
| DTB overlay | ✅ 標準 | ✅ dtoverlay 檔 | ✅ DTB | ✅ 標準 |
本單元涉及的關鍵 register,以及「讀→改→寫→驗證」的完整位元級操作序列:
| Register | 位址 | 功能 | Bit Field 說明 |
|---|---|---|---|
NVCSI_INT_STATUS | 0x0c0a0000 | CSI 中斷狀態 | bit[0]=phy_sync_done, bit[4]=crc_error, bit[8]=ecc_error |
# 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"
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 → 重跑 ubootOverlayApply1. `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
框架層完整驗證 SOP:
| 步驟 | 動作 | 指令/方法 | 預期輸出 |
|---|---|---|---|
| Step 1 | 確認 kernel module | `lsmod | grep tegra` | tegra-v4l2, tegra-csi 出現 |
| Step 2 | 確認 video device | `ls /dev/video*` | /dev/video0 存在 |
| Step 3 | V4L2 能力查詢 | `v4l2-ctl -d /dev/video0 --info` | Driver info 正確 |
| Step 4 | format 列表 | `v4l2-ctl -d /dev/video0 --list-formats-ext` | 支援 RAW10 等 |
| Step 5 | nvgstcapture 測試 | `nvgstcapture-1.0 -m 1` | 擷取一張 JPEG |
| Step 6 | Holoscan sample | `python3 holoscan_sample.py` | pipeline 正常結束 |
| Step 7 | 效能基準 | `v4l2-ctl --stream-mmap --stream-count=100 --stream-to=/dev/null` | 100 幀無 drop |
| 面向 | Thor T5000 | RPi5 | Orange Pi | Orin Nano |
|---|---|---|---|---|
| 相機框架 | V4L2 + Argus + Holoscan | V4L2 + libcamera | V4L2 direct | V4L2 + Argus |
| Device Tree | overlay + ubootOverlayApply | dtoverlay= (auto) | armbianEnv.txt 或 boot.scr | hardkernel .dtb |
| 相機 HAL | NVIDIA Camera HAL | libcamera (rpi.cam) | libv4l2 | NVIDIA Camera HAL |
| GPU 整合 | Holoscan + CUDA + GPUDirect | OpenCV (CPU) | OpenCV (CPU) | CUDA + nvbufsurface |
| 多 camera 串流能力 | 16 lane, 6+ sensor | 2 sensor | 1 sensor | 4 sensor |
| live view 工具 | `nvgstviewer` | `libcamera-hello` | ffplay / v4l2-ctl | `nvgstviewer` |
針對「平台相機框架與驅動」主題的完整 bring-up 步驟清單: