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

CSI-2 位元層、libcamera 堆疊、感測器選擇

1.1 MIPI CSI-2 標準:分層模型

MIPI CSI-2(Camera Serial Interface 2)由 MIPI Alliance 制定,是嵌入式相機最普遍的介面。它分四層,每一層解決一類問題:

職責關鍵概念除錯焦點
PHY(D-PHY)電氣:差分訊號、時脈、兩種模式HS / LP、1.2V 差動示波器看波形、眼圖
Lane 管理多 lane 對齊、去歪斜lane 數、byte clocklane 數設定是否一致
Low Level Protocol封包化:long/short packetSOF/EOF、ECC、CRCECC 錯誤計數
應用層frame 資料與 metadatapixel format、embedded data格式/尺寸匹配

1.1.1 D-PHY 的兩種模式(很重要)

工程直覺:「相機沒有畫面」若出現在「剛接上」階段,多半是 PHY/LP(電源、reset 順序);若「接上好了一陣子才斷」,多為 HS 訊號完整性問題。

1.2 RPi5 的 CSI-2 硬體資源

項目規格工程意義
連接器15-pin × 2(Camera 0 / 1)可同時接兩顆
每連接器 lane4-laneOV5647 只用 2-lane
最高資料率~1.5 Gbps/lane決定最高解析度/幀率
時脈感測器提供 HS clockDDR:雙沿取樣

1.2.1 15-pin 連接器腳位(必須背)

由外而內(有鎖扣的那邊朝外) 1 GND 2 GND 3 CAM_GPIO 4 MIPI_D0P 5 MIPI_D0N 6 MIPI_D1P 7 MIPI_D1N 8 GND 9 MIPI_D2P 10 MIPI_D2N 11 GND 12 MIPI_D3P 13 MIPI_D3N 14 GND 15 CAMERA_CLOCK(XCLK)
排線檢查 SOP(第一優先): ① 金手指方向:有金屬接點的面朝向連接器彈片; ② 插入到底後鎖扣壓平(聽到「卡」); ③ 重插後 dmesg | grep -i -E "unicam|ov5647" 應無 error。 統計上約半數「相機沒畫面」源於排線——先排除再碰軟體。

1.3 libcamera 四層堆疊(每一層你操作什麼)

應用:rpicam-apps / picamera2libcamera(管線/控制/tuning)內核:unicam + ov5647.c硬體:OV5647 → BCM2712 ISP
元件你操作什麼原始碼/文件位置
應用rpicam-stillpicamera2拍照、錄影、設控制/usr/bin、pypi
框架libcamera曝光/增益/AWB、載入 tuning 檔libcamera.org(開源)
內核unicam + ov5647.cCSI 接收、感測器 registerdrivers/media/platform/raspberrypi
硬體OV5647 → BCM2712 ISPRAW 產出與校正datasheet
為什麼理解四層:調校時錯誤可能發生在任何一層——例:控制設了但驅動沒寫進 register(框架/內核層)、register 寫了但感測器沒套用(硬體層)。知道「問題在哪一層」是調校的第一能力。

1.4 感測器選擇:三個決定性問題

  1. 官方 vs 客製:官方 Camera Module v1 = OV5647,免寫 overlay。
  2. 接口:15-pin、2-lane MIPI、I2C 0x36。
  3. 驅動drivers/media/i2c/ 有無對應(ov5647/ov5640/ov9281 皆有 mainline 驅動)。
感測器解析度快門RPi5定位
OV56475 MPRolling官方 v1 ✅本課主例(公開 datasheet)
OV56405 MPRolling驅動 ✅教育/客製板
OV92811 MPGlobal驅動 ✅機器視覺

1.5 本章最小驗收

驗證介面與 overlay
# 查看可用 overlay
sudo dtoverlay -a | grep -E "ov5647|ov9281"
# 檢查 FPC 後 CSI 錯誤
dmesg | grep -i -E "unicam|csi|ov5647" | tail -5
通過標準:① dmesg 無 CSI/unicam error ② overlay 清單可看到 ov5647。兩者皆過 → 硬體層就緒,可進單元 2。

1.6 常見誤解澄清

1.6 深入:CSI-2 D-PHY 的 HS/LP 電氣

除錯「訊號層」問題時,D-PHY 的電氣參數是關鍵:

參數HS(高速)LP(低功耗)
訊號差動(D±)單端(CMOS 1.2V)
擺幅約 200 mV(100–300)0–1.2 V
用途傳 pixel 資料控制(BTA/reset)
時脈DDR 雙沿低速
常見 HS 問題:① 排線過長/折到 → 眼圖閉合、掉幀 ② 電源不乾淨 → HS 電平抖動 ③ 接地不良 → 共模雜訊。沒有示波器時,用「dmesg 是否出現 CSI 錯誤」與「幀率是否穩定」當間接指標。

1.7 深入了解 libcamera 的 PipeLine 初始化順序

偵測 media 節點列舉 subdevmatch sensor driver建立 Camera載入 tuning可設定控制

libcamera 啟動時依 media graph 找出「感測器 + ISP」並組 Camera;tuning 檔在首次使用該 Camera 時載入。若 list-cameras 看得到相機,代表這一串都成功。

1.8 練習:確認你的硬體就緒

  1. 列出本機 2 個相機連接器:sudo dtoverlay -a | grep cam
  2. 確認 overlay 清單含 ov5647。
  3. dmesg | grep -i -E 'unicam|ov5647' 確認無 error。
  4. 把結果記錄下來(寫入你的 bring-up log)。
看完這單元你應該能說出:
  • CSI-2 四層模型與 D-PHY HS/LP。
  • RPi5 15-pin 腳位與排線 SOP。
  • libcamera 四層與各層操作對象。
  • 感測器選擇三問題與可用性。
  • 常見誤解澄清。

進階真實情境 Worked Example:雙攝影機同時串流的管線配置

場景:RPi5 同時接 OV5647(Camera 0)與 OV9281(Camera 1),要同時錄影用於雙目視覺。

雙鏡頭同時串流
# 1. 確認兩顆都被 libcamera 偵測
rpicam-hello --list-cameras
# 顯示:0: ov5647  1: ov9281

# 2. 用 picamera2 同時串流(雙 stream)
python3 - <<'EOF'
from picamera2 import Picamera2
import time

cam0 = Picamera2(0)   # OV5647
cam1 = Picamera2(1)   # OV9281

cfg0 = cam0.create_video_configuration(
    main={"size": (1280, 720), "format": "RGB888"})
cfg1 = cam1.create_video_configuration(
    main={"size": (640, 480), "format": "RGB888"})

cam0.configure(cfg0)
cam1.configure(cfg1)
cam0.start()
cam1.start()
time.sleep(3)
cam0.stop()
cam1.stop()
print("雙鏡頭串流完成")
EOF

# 3. 檢查 DMA buffer 分配
dmesg | grep -i "dma\|buffer\|cma" | tail -5
為什麼選這條路徑:RPi5 的 BCM2712 ISP 只有一條硬體管線,但 libcamera 可以透過 software pipeline 同時處理多個 Camera 節點。用 picamera2 而非 rpicam-apps 是因為前者允許更精細的 buffer 配置與雙 stream 控制。注意 OV9281 用 global shutter、OV5647 用 rolling——兩者的曝光控制邏輯完全不同,不能共用同一組 tuning。

深入原理擴充:CSI-2 D-PHY 的 HS/LP 切換與通道佔用

CSI-2 D-PHY 的 HS(High-Speed)與 LP(Low-Power)模式之間的切換,不是「瞬間」完成的:

大家以為沒問題但其實是陷阱:很多人以為「排線插好、i2c 通了就沒問題」,但 D-PHY 的 HS 訊號完整性取決於排線阻抗(差動 100Ω ±10%)。一條 15cm 的廉價排線在 1.5 Gbps 下可能導致眼圖閉合——症状是「偶爾掉幀」而非「完全沒畫面」,很容易被忽略。

診斷式疑難排解表

症狀可能原因解決方案
dmesg 出現「unicam: frame sync timeout」D-PHY HS 切換超時,排線訊號完整性差更換短排線(≤10cm)、確認金手指接觸、用示波器量 HS 眼圖
rpicam-hello --list-cameras 只看到一顆另一顆的 I2C 位址衝突或 DT overlay 未啟用sudo i2cdetect -y 22 和 -y 10 分別檢查;確認 /boot/firmware/config.txt 有兩筆 dtoverlay
雙鏡頭同時串流時帧率明顯下降DMA buffer/CMA 不足,ISP 管線排程瓶頸加大 CMA(/boot/firmware/cmdline.txt 加 cma=256M)、降低單顆解析度
Camera 1 預覽有畫面但色彩全錯OV9281 是黑白感測器,被誤判為彩色確認 tuning 檔對應 OV9281(無 CCM 區塊);不要套 OV5647 的 tuning
開機後 dmesg 無任何 ov5647 訊息DT overlay 未載入或 compatible 字串不匹配sudo dtoverlay -a | grep ov5647;檢查 /boot/firmware/config.txt 的 dtoverlay=ov5647 行

進階挑戰題

  1. media-ctl -p -d /dev/media0 畫出完整的 media graph,標出每個 entity 的 role(source/sink)與 pad format。若把 OV5647 的 lane 數從 2 改成 4(假設硬體支援),media graph 會有何變化?
  2. 設計一個「排線品質快速篩選」腳本:連續拍 100 張 RAW,統計每張的 frame CRC 錯誤數。若任何一張 CRC 錯誤 > 0,判定排線不合格。
  3. RPi5 同時接 OV5647 + OV9281 時,兩顆的 XCLK 頻率是否必须相同?查 datasheet 說明原因。

延伸閱讀

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

場景:這是一顆全新的 OV5647 模組 + RPi5 開發板。目標是走完「硬體 → overlay → 媒體節點 → 第一張 RAW」的完整端到端流程,驗證整個相機生態鏈就緒。這個專案整合單元 1(CSI-2/生態)、3(I2C)、4(overlay/驅動)、5(出圖)的知識。

端到端 bring-up:DT overlay → 第一張圖
# 階段 0:硬體安裝(單元 1 排線 SOP)
# 金手指朝彈片、插入到底、鎖扣壓平

# 階段 1:確認 overlay 就緒
sudo dtoverlay -a | grep -E "ov5647|ov9281"
# 預期:ov5647 在清單中

# 階段 2:確認 probe 與媒體節點
dmesg | grep -i -E "ov5647|unicam|csi" | tail -10
# 預期:ov5647 0-0036: Probing / Chip ID 0x5647,無 error
ls /dev/media* /dev/video*

# 階段 3:I2C 驗證感測器 ID(單元 3)
sudo i2cdetect -y 22 | grep 36          # 預期看到 0x36
sudo i2ctransfer -y 22 w2@0x36 0x30 0x0a r1   # 預期 0x56
sudo i2ctransfer -y 22 w2@0x36 0x30 0x0b r1   # 預期 0x47

# 階段 4:libcamera 偵測(單元 4/5)
rpicam-hello --list-cameras
# 預期:0 : ov5647 [2592x1944 10-bit RGGB] + Modes 清單

# 階段 5:產出第一張 RAW
rpicam-still --raw --shutter 20000 --gain 1.0 --awb off --awbgains 1.0,1.0 -o first.dng
ls -la first.dng
# 預期:first.dng 存在(RAW 檔)
專案規模與跨單元整合:這是單元 1-6 的最小整合驗證——每個階段都對應一個先前單元的「最小驗收」。若任一階段失敗,回該單元的診斷表:階段 2 失敗回單元 1(排線/生態)、階段 3 失敗回單元 3(I2C)、階段 4 失敗回單元 4(overlay/驅動)。「從 overlay 到第一張圖」就是整個課程的骨架。

量測/驗證 SOP:平台相機生態就緒驗證

  1. 排線重插(金手指朝彈片、壓平鎖扣),記錄插拔次數。
  2. sudo dtoverlay -a | grep ov5647 確認 overlay 清單。
  3. dmesg | grep -i -E "unicam|ov5647|csi" 確認無 error(回看最後 10 行)。
  4. sudo i2cdetect -y 22 確認 0x36 回應。
  5. rpicam-hello --list-cameras 確認 camera 0 出現。
  6. 拍一張 RAW 並用 rawpy 讀出 shape(2592×1944 且非全黑)。
判讀指標:六步全過 = 生態就緒;dmesg 有任何 CSI/unicam error = 硬體層問題優先;list-cameras 空 = overlay 或 probe 層。把六步結果寫入 bring-up log。

平台間對照:相機生態與 CSI 介面

面向RPi5Orange PiOrin NanoThor
CSI 連接器15-pin ×2,4-laneMIPI 排針,2-lane 常見15-pin / 22-pin,GMSL 選配HSB(乙太網路感測器)
感測器驅動來源mainline 內核(ov5647/5640/9281)廠商 BSP,版本雜NVIDIA 自帶 + 社群NVIDIA + Holoscan
overlay/DT 機制config.txt + dtoverlayoverlays + 手改 dtbdevice tree + kernel patchdevice tree + YAML 描述
框架libcamera(開源)V4L2 / gst 陽春Argus(閉源)Argus / Holoscan
生態坑排線品質敏感BSP 驅動版本混亂感測器支援需 NDA新、文件少

互動式檢核清單


第 3 輪深度加深

① Register 位元級完整工作流:RPi5 CSI-2 通道啟用

步驟操作位元級細節
1. 讀sudo devmem2 0x7e801004 w讀取 CSI2_NAND2 設定暫存器,確認 bit[0] PHY_EN 狀態
2. 改OR 0x00000007bit[0]=1(PHY_EN) bit[1]=1(CSI_EN) bit[2]=1(IRQ_EN)
3. 寫sudo devmem2 0x7e801004 w 0x00000007啟用 CSI-2 PHY + 控制器 + 中斷
4. 驗證sudo devmem2 0x7e801004 w確認回讀值 bit[2:0] = 0b111
Mask 說明:0x00000007 mask 保留 bit[2:0],其餘 bit 以 OR 方式合併,避免影響其他功能設定。

② 多層疑難排解決策樹

決策樹 A:相機完全無畫面

相機無畫面
├─ 檢查 A:dmesg 有無 ov5647 probe 訊息
│  ├─ 無 → overlay 未啟用 → /boot/firmware/config.txt 加 dtoverlay=ov5647
│  └─ 有 → probe 成功,繼續
├─ 檢查 B:i2cdetect 0x3C 是否有回應
│  ├─ 無 → I2C 通道未開 / 排線問題 / 供電異常
│  └─ 有 → I2C 正常,繼續
├─ 檢查 C:rpicam-hello --list-cameras 是否出現 camera 0
│  ├─ 無 → libcamera 管線未正確綁定 → 檢查 /etc/libcamera/ipa_rpi.yaml
│  └─ 有 → 硬體層 OK,問題在應用層
└─ 檢查 D:測試擷取 RAW 是否為全黑
   ├─ 全黑 → sensor 曝光設定異常 / MIPI 訊號未到達 ISP
   └─ 有資料 → 基本功能 OK

決策樹 B:i2cdetect 有回應但畫面異常

i2cdetect 有回應但畫面異常
├─ 檢查 A:dmesg 有無 CSI error / frame sync error
│  ├─ 有 → MIPI 時序問題 → 檢查 clock lane 頻率設定
│  └─ 無 → 繼續
├─ 檢查 B:曝光時間是否合理
│  ├─ 0 或最大值 → AE 未收斂 → 檢查 tuning 檔案
│  └─ 正常 → 繼續
└─ 檢查 C:是否只在特定解析度下異常
   ├─ 是 → 該解析度 lane 數/時序不匹配 → 調整 MIPI config
   └─ 否 → 軟體管線問題

③ 量測驗證完整 SOP:CSI-2 訊號完整性

  1. 工具準備:示波器(≥200MHz)、SMA 探棒、15-pin 排線 breakout 板
  2. 接線:探棒接至 CSI connector 的 DATA0+ 與 GND
  3. 觸發設定:示波器觸發於 HS 模式進入(Voltage threshold ≈ 200mV)
  4. 量測項目:
    a. HS 模式差動振幅:預期 100–300mV
    b. LP→HS 切換時間:預期 <100ns
    c. Clock frequency:150MHz (2-lane) / 300MHz (4-lane)
  5. 重複量測:每條件量 10 次,計算平均值與 ±σ
  6. 判讀標準:振幅 <80mV = 訊號衰減(排線品質差);時序抖動 >50ps = EMI 干擾
  7. 常見偏差:排線彎折半徑太小 → 阻抗不連續 → 振幅下降;接地不良 → 共模雜訊

④ 四平台終極對照

面向RPi5Orange PiOrin NanoThor推薦
CSI 介面15-pin ×2, 4-laneMIPI 排針, 2-lane15/22-pin, GMSL 可選HSB 乙太網路RPi5 最易上手
感測器驅動mainline 內核廠商 BSPNVIDIA + 社群NVIDIA + HoloscanRPi5 mainline 最穩定
Overlay 機制config.txt dtoverlayoverlays + dtbdevice tree + patchDT + YAMLRPi5 最簡潔
相機框架libcamera 開源V4L2 陽春Argus 閉源Argus / HoloscanRPi5 生態最完整
多感測器2 port 官方支援1-2 port多 port + GMSL乙太網路天生分散Orin 規模最大
上手難度★★☆★★★★★★★★★★★★RPi5 入門首選

⑤ 完整 Bring-up 專案 Checklist