試:MIPI CSI-2 Virtual Channel機制與實戰(zhàn))
最近在調(diào)一塊Jetson Orin NX開發(fā)板遇到一個挺有意思的現(xiàn)象板子接了兩路MIPI攝像頭/dev/video0注冊正常/dev/video1卻經(jīng)常時有時無。最開始以為是硬件接觸不良查來查去最后發(fā)現(xiàn)是Virtual Channel的配置問題。如果你也在Jetson上做多路視覺采集或者看過設(shè)備樹和media-ctl -p打印后一頭霧水這篇文章應(yīng)該對你有用。我不會把Virtual Channel Driver當成一個高深莫測的模塊來寫而是按我自己的理解從硬件通道、內(nèi)核驅(qū)動、用戶態(tài)配置和實際排錯四個層面把它拆開講清楚。這篇文章適合兩類人一類是用Jetson做多路相機采集但又沒系統(tǒng)看過驅(qū)動鏈路的開發(fā)者另一類是遇到video0、video1節(jié)點亂跳或者虛擬顯示配置不生效想搞清楚背后機制的嵌入式Linux工程師。1. 一個物理連接塞進多路數(shù)據(jù)MIPI CSI-2的Virtual Channel機制1.1 先從CSI-2物理層說起MIPI CSI-2是Jetson板載攝像頭接口最常用的協(xié)議它對應(yīng)的是板上那排FPC排線座Sensor通過排線連接到SoC的CSI控制器。很多人把CSI接口理解成“一根線傳一路攝像頭”這么理解在低速時代沒問題但在多路高清攝像頭場景下就有點不夠了。在CSI-2協(xié)議里物理通道和邏輯通道是兩個不同層級的概念。物理層看的是差分信號線lane一條CSI接口由時鐘lane和若干數(shù)據(jù)lane組成數(shù)據(jù)lane數(shù)量通常是1、2或4條這個數(shù)量決定了帶寬上限。而邏輯層有一個機制叫Virtual Channel簡稱VC在數(shù)據(jù)包頭部有一個2bit的VC ID取值0到3。接收端拿到數(shù)據(jù)包后根據(jù)這個ID把數(shù)據(jù)分發(fā)到不同的邏輯通道所以同一條物理CSI接口最多能傳4路獨立的視頻流。用大白話說這就好比一條物理公路CSI接口路上跑著4輛不同顏色的車VC 0/1/2/3每輛車車頭上都寫著目的地編號收費站CSI控制器看一眼編號就把車分到對應(yīng)車道。1.2 “虛擬通道”虛擬的到底是什么Virtual Channel“虛擬”的是數(shù)據(jù)流歸屬而不是物理連接。Sensor端在發(fā)送數(shù)據(jù)的時候會在每個幀的包頭上打上自己的VC ID接收端CSI控制器解析包頭按VC ID把數(shù)據(jù)放到對應(yīng)的FIFO里。Jetson的驅(qū)動再把每個FIFO對應(yīng)成一個獨立的V4L2 video節(jié)點這就是你在用戶空間看到的/dev/video0、/dev/video1。這帶來一個很直接的影響在硬件上幾路攝像頭可以共用同一個CSI端口只需要把多路Sensor的信號通過Deserializer解串器匯流到同一條CSI鏈路上。很多車載和工業(yè)視覺方案里一個CSI口接4路甚至8路攝像頭靠的就是VC機制。Jetson的驅(qū)動里每個VC對應(yīng)一個獨立的channel驅(qū)動層層往下注冊時會把它們拆成不同的視頻設(shè)備。實際項目中還有個非常容易踩的坑VC ID必須與Sensor側(cè)的配置一致。有些Sensor的VC ID是通過硬件引腳配置的有些是通過I2C寄存器配置的如果Sensor實際發(fā)出的VC ID和驅(qū)動里設(shè)置的不一致表現(xiàn)就是video0能采到圖但畫面是花的或者干脆不出流。1.3 為什么這個機制對Jetson尤其重要Jetson的CSI接口數(shù)量是有限的以O(shè)rin NX為例可用CSI端口就那么幾個。如果每個攝像頭都獨占一個物理接口那最多只能接四路左右。但很多場景比如無人機環(huán)繞視覺、機器人頭部多目、VR手勢識別需要6路、8路甚至更多攝像頭這時候就必須借助VC在一路物理CSI上串多路Sensor。另外Jetson的ISP和VIVideo Input硬件在設(shè)計上也是按channel來管理的每個channel有獨立的內(nèi)存地址和buffer管理邏輯。這也是為什么在用戶空間每個VC看起來就像一路完全獨立的攝像頭打開、出流、關(guān)閉互不影響。驅(qū)動層面實際做的事情就是把硬件上按VC劃分好的通路通過V4L2框架暴露給應(yīng)用。2. 從硬件到節(jié)點Jetson媒體子系統(tǒng)對虛擬通道的逐層映射2.1 Jeston采集鏈路里都有哪些角色一套標準的Jetson攝像頭采集鏈路涉及的角色比很多人想象得多。最前端是Sensor本身它通過I2C和GPIO與SoC通信然后是CSI控制器負責接收MIPI數(shù)據(jù)包做VC識別、數(shù)據(jù)解析再往后是VIVideo Input負責把數(shù)據(jù)搬運到內(nèi)存最后是ISPImage Signal Processor負責做Bayer去馬賽克、降噪、色彩校正等圖像處理。在內(nèi)核驅(qū)動層面每一個角色都是一個獨立的內(nèi)核模塊。Sensor對應(yīng)tegra-camera-platform下的驅(qū)動CSI和VI對應(yīng)tegra-vi4、tegra-capture等模塊。這些模塊在設(shè)備樹里通過端口連接關(guān)系組成一張圖media graph用戶空間的media-ctl工具就是用來查看和操作這張圖的。Virtual Channel Driver這個名字嚴格說不是指某一個單一驅(qū)動文件而是指一整套讓虛擬通道生效的軟件機制從設(shè)備樹的VC ID聲明、到CSI驅(qū)動的通道解析、再到VI驅(qū)動的buffer管理串起來才是完整的Virtual Channel Driver。2.2 media graph理解虛擬通道的最佳入口在Jetson上做多路攝像頭開發(fā)第一時間應(yīng)該打開的就是media graph。執(zhí)行media-ctl -p /dev/media0會看到一長串拓撲信息里面會列出所有注冊的實體entity和它們之間的連接link。每個Sensor是一個entityCSI控制器是另一個entityVI接收端又是幾個entity它們之間通過pad連接。我剛開始調(diào)多路攝像頭時不理解為什么video0不能直接對應(yīng)某個Sensor后來看media graph才明白video0只是整個流水線的入口真正決定數(shù)據(jù)從哪里來的是它下游的subdev鏈路。具體來說一個V4L2 video節(jié)點后面通常會掛一個VI的subdevVI再連到CSI控制器CSI再連到某個Sensor。數(shù)據(jù)是逐級往上流的每一級都有自己的格式配置。在media graph里虛擬通道的體現(xiàn)就是CSI控制器有多個sink pad每個sink pad對應(yīng)一個VC ID。比如CSI控制器有4個sink pad分別連接四個來自不同VC ID的Sensor entity那么你就能在拓撲里清楚看到每個VC被路由到了哪個video節(jié)點。這是調(diào)試多路攝像頭時最有價值的參考信息。2.3 用戶空間的video節(jié)點是如何一一對應(yīng)的很多人以為/dev/video0、/dev/video1這些節(jié)點號是固定的其實不是。在Jetson上video節(jié)點號是由驅(qū)動注冊順序決定的而注冊順序又和設(shè)備樹里節(jié)點的排列順序、模塊加載順序有關(guān)。如果你改過設(shè)備樹、重新編譯過內(nèi)核或者換了SDK版本節(jié)點號完全可能變。真正穩(wěn)定的是節(jié)點對應(yīng)的名字或者media graph里的拓撲關(guān)系。通過v4l2-ctl --list-devices可以看到每個video節(jié)點的名字比如vi-output idx 0。判斷一個節(jié)點到底對應(yīng)哪個VC最靠譜的方法是看media-ctl -p里面從該video節(jié)點往下沿著鏈路找到末端Sensor的名稱和地址。這里有個經(jīng)驗在實際項目中不要依賴/dev/video0這樣的硬編碼而是應(yīng)該通過/sys/class/video4linux/下面的符號鏈接或者media graph里的名字來匹配設(shè)備。Jetson上不同的JetPack版本對節(jié)點的命名規(guī)則都有過調(diào)整硬編碼節(jié)點號是給自己埋坑。3. 調(diào)試虛擬通道必須掌握的三條命令以及我翻車過的兩次3.1 確認當前拓撲media-ctl在Jetson上調(diào)試任何與視頻通道相關(guān)的問題第一步永遠是查看media graph。執(zhí)行sudo media-ctl -p /dev/media0這條命令會打印完整的實體和pad信息。重點看CSI控制器的sink pad連接到了哪些Sensor實體每個Sensor的名稱后面會帶上I2C地址。比如- entity 7: imx219 6-0010 (1 pad, 1 link)這個信息說明在I2C總線6地址0x10上有一顆IMX219 Sensor。如果你是第一次接觸這個工具建議先用-p參數(shù)看一下所有實體之間的上下游關(guān)系再結(jié)合設(shè)備樹確認每個Sensor配置的VC ID。拓撲清晰了后面很多問題都不用猜。3.2 查看和設(shè)置格式v4l2-ctlv4l2-ctl是用來配置和控制video節(jié)點的工具。多路虛擬通道調(diào)試中最常用的子命令包括v4l2-ctl --list-devices v4l2-ctl --list-formats-ext -d /dev/video0 v4l2-ctl --set-fmt-videowidth1920,height1080,pixelformatNV12 -d /dev/video0 v4l2-ctl --stream-mmap --stream-count1 -d /dev/video0有一個很關(guān)鍵的細節(jié)在虛擬通道架構(gòu)下光設(shè)置video節(jié)點的格式還不夠sensor的subdev格式也要單獨設(shè)置。因為video節(jié)點的格式?jīng)Q定的是VI輸出到內(nèi)存的格式而Sensor的格式?jīng)Q定的是CSI鏈路上傳輸?shù)腞AW數(shù)據(jù)格式。兩層格式脫節(jié)最典型的表現(xiàn)是v4l2-ctl --stream-mmap能出流但畫面顏色完全不對或者圖像邊緣有奇怪的綠色條紋。正確的設(shè)置方式是通過media-ctl設(shè)置subdev的format比如media-ctl -V imx219 6-0010:0[fmt:SRGGB10_1X10/1920x1080]然后再用v4l2-ctl設(shè)置video節(jié)點的格式。很多項目跑不起來就是因為只配了video節(jié)點沒配subdev。3.3 翻車案例一只開一個channel另一個不出流我有一次調(diào)試雙目相機兩個sensor配置了不同的VC ID設(shè)備樹也加好了。上電后兩個video節(jié)點都注冊出來了但只有video0能出流video1的STREAMON一直超時。用dmesg看只有一行CSI相關(guān)的超時日志沒有任何更詳細的錯誤。排查過程其實很曲折。我先懷疑是sensor配置問題用I2C工具讀sensor寄存器確認兩個sensor都在正常輸出。然后懷疑是VC ID不匹配又去看了設(shè)備樹配置發(fā)現(xiàn)兩個節(jié)點配置的VC分別是0和1沒有寫錯。最后拿著放大鏡檢查FPC排線才看到第二個sensor有一根差分信號線的焊點虛焊導(dǎo)致同步信號異常。這個問題的教訓(xùn)是在虛擬通道架構(gòu)下兩條通道共用物理鏈路一條鏈路的信號完整性問題會直接影響另一條通道的同步。排線虛焊、線序錯誤這類硬件問題在單攝方案里可能只是畫面異常但在多路VC方案里往往表現(xiàn)為另一路完全不出流排查難度大得多。3.4 翻車案例二media graph里出現(xiàn)了兩個相同的sensor名字另一個坑來自設(shè)備樹配置。我新加到一塊板子的設(shè)備樹時不小心把同一個sensor節(jié)點復(fù)制了兩份I2C地址和VC ID都完全相同只是名字改了后綴。編譯、燒錄一切正常但運行media-ctl -p時發(fā)現(xiàn)graph里出現(xiàn)了兩個拓撲完全一樣的entity分別接在CSI控制器的不同pad上??雌饋砗孟駴]問題但實際采集時兩個video節(jié)點出的畫面都來自同一顆sensor而且由于VC沖突兩個節(jié)點都時而花屏。我一開始還懷疑是驅(qū)動注冊邏輯的問題后來反復(fù)核實才發(fā)現(xiàn)是設(shè)備樹里重復(fù)定義了節(jié)點。在Jetson的L4T內(nèi)核中sensor的I2C地址加上VC ID才是唯一的標識。寫設(shè)備樹時這兩項必須跟實際硬件一一對應(yīng)不能出現(xiàn)兩個節(jié)點指向同一個硬件通路的情況。經(jīng)驗是寫完之后先在/proc/device-tree下面檢查對應(yīng)節(jié)點的內(nèi)容確認I2C地址和vc值再跑media-ctl -p做二次確認。4. 設(shè)備樹、驅(qū)動加載與常見告警虛擬通道驅(qū)動在系統(tǒng)里的落地方式4.1 設(shè)備樹里怎么聲明一個虛擬通道Jetson的攝像頭設(shè)備樹配置遵循標準V4L2設(shè)備樹綁定。每個sensor節(jié)點需要聲明regI2C地址、reset-gpios、mclk等屬性同時還要在port節(jié)點中聲明它連接到的CSI控制器端口。虛擬通道的ID在子節(jié)點中通常通過一個屬性來指定比如sensor1a { reg 0x1a; vc-id 0; port { sensor_out: endpoint { remote-endpoint csi_in0; }; }; };第二個sensor則是sensor1c { reg 0x1c; vc-id 1; port { sensor_out2: endpoint { remote-endpoint csi_in1; }; }; };CSI控制器節(jié)點里對應(yīng)地要有多個sink端點分別指向不同VC的sensor endpoint。這種聲明方式讓驅(qū)動在初始化時就能知道哪個sensor掛在哪個CSI端口、用的是哪個VC ID、對應(yīng)的遠端端點是誰。修改設(shè)備樹之后很多人會忘記一件事Jetson的設(shè)備樹是編譯成dtb文件燒錄的僅修改源碼還不夠要用dtc工具或JetPack自帶的編譯腳本重新生成dtb再燒到boot分區(qū)。我在早期調(diào)試時經(jīng)常改了設(shè)備樹但沒燒錄導(dǎo)致怎么查都跟源碼對不上。4.2 nvidia-uvm加載沖突和虛擬通道沒有直接關(guān)系但經(jīng)常一起出現(xiàn)在Jetson上做開發(fā)幾乎所有人都會遇到一條報錯信息An nvidia kernel module nvidia-uvm appears to be already loaded in your kernel這個信息跟Virtual Channel Driver沒什么關(guān)系它說的是NVIDIA的UVMUnified Virtual Memory模塊已經(jīng)被加載了。但在實際項目中這個報錯會干擾你判斷驅(qū)動加載狀態(tài)因為你可能為了排查video0不出流去了解驅(qū)動模塊結(jié)果看到滿屏的UVM警告以為哪個驅(qū)動加載順序出問題了。UVM模塊的作用是讓GPU和CPU共享虛擬內(nèi)存地址空間它由nvidia.ko在啟動時自動加載并在CUDA運行時被復(fù)用。如果你試圖在系統(tǒng)已經(jīng)運行的情況下手動modprobe nvidia-uvm就會看到這個提示。解決辦法很簡單要么不管它因為功能正常要么確認運行環(huán)境干凈后的狀態(tài)在干凈的L4T系統(tǒng)里它會在正常啟動流程中自動加載。排查多路攝像頭問題時判斷驅(qū)動模塊的方法應(yīng)該是lsmod | grep tegra lsmod | grep video lsmod | grep nvidia而不是盯著nvidia-uvm報錯看。tegra-capture、tegra-vi4這些模塊加載正常與否才是虛擬通道出流的關(guān)鍵。4.3 驅(qū)動加載順序與節(jié)點命名的不確定性Jetson的攝像頭相關(guān)內(nèi)核模塊之間是有依賴關(guān)系的。從底層往上大致是tegra-camera-platform管理sensor平臺設(shè)備→tegra-vi4VI控制器驅(qū)動→tegra-capture視頻采集驅(qū)動→nvgpu/nvhostGPU和圖形相關(guān)視平臺而定。模塊加載順序會影響/dev/videoX節(jié)點編號的分配順序。在標準L4T內(nèi)核里這些模塊通常在啟動階段由udev按依賴關(guān)系自動加載。但由于platform設(shè)備的注冊順序和設(shè)備樹中節(jié)點的排列順序有關(guān)如果你在設(shè)備樹中新加了一個sensor節(jié)點放在最前面那么它可能會被注冊為video0原有的video0變成video1這是正?,F(xiàn)象。開發(fā)階段我強烈建議做兩件事第一應(yīng)用層通過設(shè)備名稱或media graph來匹配設(shè)備而不是硬編碼節(jié)點號第二在發(fā)布版本里固定設(shè)備樹和內(nèi)核版本不要隨意升級JetPack或者更換dtb否則節(jié)點編號很可能改變影響系統(tǒng)穩(wěn)定性。4.4 lspci查不到NVIDIA設(shè)備那不是Bug很多人拿到Jetson Orin NX后習慣性地執(zhí)行l(wèi)spci | grep -i nvidia結(jié)果發(fā)現(xiàn)什么都沒有于是懷疑驅(qū)動沒裝好。其實Tegra系列芯片是SoC架構(gòu)GPU、ISP、視頻編解碼器都集成在同一顆芯片里不經(jīng)過PCIe總線。lspci只能看到PCIe外設(shè)比如NVMe SSD、WiFi網(wǎng)卡、外接的獨立GPU查不到SoC內(nèi)部集成的NVIDIA設(shè)備。這個在X86平臺上習慣了的查驅(qū)動方式放到Jetson上并不適用。Jetson上檢查GPU和顯示驅(qū)動是否正確加載正確做法是ls /dev/nvidia-uvm ls /dev/nvidiactl cat /proc/driver/nvidia/version另外也要提到一點熱詞里有“nvidia control panel下載”這樣的詞但在Jetson上并沒有X86平臺那種獨立的NVIDIA控制面板顯示配置是通過xrandr、/etc/X11/xorg.conf以及設(shè)備樹里的display節(jié)點來管理的。把X86的使用習慣投射到Jetson上容易繞彎路。5. 虛擬顯示與多通道帶寬規(guī)劃把Virtual Channel理解用在實戰(zhàn)里5.1 無頭設(shè)備的Xorg虛擬顯示和內(nèi)核Virtual Channel不是一回事Jetson Orin NX開發(fā)套件本身不帶顯示輸出是很常見的很多人在無頭環(huán)境下想要一個虛擬顯示器來做遠程桌面或者跑GUI程序于是在Xorg里配置xserver-xorg-video-dummy或者使用Xvfb。這套方案在用戶空間實現(xiàn)了一個“假顯示器”讓應(yīng)用程序認為存在一個顯示器但它和本文講的Virtual Channel Driver沒有關(guān)系。一個是內(nèi)核空間的視頻采集通道一個是用戶空間的虛擬顯示設(shè)備。在Jetson上設(shè)置Xorg虛擬顯示的正確姿勢是修改/etc/X11/xorg.conf加一個dummy驅(qū)動的Display段。比如Section Device Identifier dummy Driver dummy VideoRam 32768 EndSection同時聲明一個合適的分辨率范圍。這套方案跑GStreamer、OpenGL等圖形應(yīng)用都沒有問題但它消耗的是CPU和內(nèi)存資源不經(jīng)過Jetson的顯示控制器DC硬件模塊。這個區(qū)分很重要因為在調(diào)試多路攝像頭時你很可能會用到虛擬顯示來跑GUI工具看畫面。如果理解錯了層面就容易出現(xiàn)“為什么我配置了Virtual Channel但虛擬顯示不工作”這種跨層的困惑。5.2 多路虛擬通道場景下的帶寬估算規(guī)劃多路攝像頭方案時很多人只關(guān)注CSI端口的數(shù)量忽略了帶寬預(yù)算結(jié)果接上之后發(fā)現(xiàn)高幀率跑不滿。MIPI CSI-2鏈路的帶寬是有限的每路lane的速率取決于sensor輸出、Deserializer和SoC的CSI控制器能力。以常見的1080P60 RAW10為例單路數(shù)據(jù)速率大約是像素時鐘 × 位深 1920 × 1080 × 60 × 10 bit ≈ 1.2 Gbps這個速率需要至少1條數(shù)據(jù)lane按1.5Gbps/lane計算才勉強跑得動但實際項目中一般留20%左右余量所以單路1080P60 RAW10至少配2 lane比較穩(wěn)妥。4路這樣的流加起來接近5 Gbps對CSI控制器的總帶寬和內(nèi)存帶寬都是不小壓力。下面是我在項目中常用的參考表分辨率幀率位深單路數(shù)據(jù)率4路總速率建議CSI數(shù)據(jù)lane1280x72030RAW100.27 Gbps約1.1 Gbps1 lane/路1920x108030RAW100.60 Gbps約2.4 Gbps2 lane/路1920x108060RAW101.20 Gbps約4.8 Gbps2 lane/路3840x216030RAW102.40 Gbps約9.6 Gbps4 lane/路數(shù)據(jù)率只是傳輸層帶寬到了VI寫入內(nèi)存還會占用系統(tǒng)總線和內(nèi)存帶寬多路同時開啟時內(nèi)存帶寬往往成為瓶頸。我在Orin NX上跑4路720P60的時候CPU占用不高但內(nèi)存帶寬占用已經(jīng)比較明顯同時跑ISP和編解碼任務(wù)時會出現(xiàn)幀率抖動。5.3 多路開啟時的推薦流程與避坑習慣在Jetson上開啟多路虛擬通道采集我自己的習慣是啟動后先看dmesg | grep -E tegra|vi|csi|imx確認所有sensor都被正確探測和注冊再跑media-ctl -p確認拓撲完整每個VC ID都對應(yīng)正確的sensor然后逐個通道單獨出流確認每一路本身正常最后再同時開啟所有通道觀察是否有格式不匹配、帶寬不足導(dǎo)致的丟幀。多路同時開啟時最容易出的問題是某一路的圖像參數(shù)沒有設(shè)置完整。例如給兩個通道設(shè)置了不同的分辨率或幀率而CSI控制器還按同一個格式在解析數(shù)據(jù)就會出現(xiàn)畫面撕裂。另外所有通道的sensor幀率最好保持一致尤其是對同一顆Deserializer輸出來的多路流幀率不一致會導(dǎo)致同步信號互相干擾。還有一個小習慣不要在多路出流過程中反復(fù)開關(guān)單個video節(jié)點而不關(guān)閉其他節(jié)點這會讓VI的buffer分配狀態(tài)變得混亂偶爾會導(dǎo)致內(nèi)存泄漏。正確做法是先整體下電關(guān)閉所有stream再修改配置再整體上電。6. 回顧一次多路虛擬通道的完整調(diào)試過程為了幫你把這些知識點串起來我復(fù)盤一次實際調(diào)過的四路攝像頭項目看看Virtual Channel問題到底長什么樣。6.1 癥狀第四路圖像偶爾不刷新項目用了一顆四路Deserializer通過CSI接入Jetson Orin NX四路VC分別配置為0/1/2/3。剛接好時一切正常四路都能出流。但跑了一個小時后第四路圖像開始偶發(fā)不刷新大約每幾十秒卡一幀隨后自動恢復(fù)。一開始我懷疑是sensor過熱但讀sensor溫度完全正常。后來懷疑是CSI鏈路抗干擾能力不足查了FPC排線的屏蔽也正常。最后用media-ctl -p盯拓撲時發(fā)現(xiàn)問題第四路sensor的VC ID在設(shè)備樹里寫成了0和第一路重復(fù)了。按理說VC沖突會直接導(dǎo)致無法出流但實際表現(xiàn)是偶發(fā)卡頓這是因為Deserializer內(nèi)部對同ID的多路流做了某種仲裁導(dǎo)致了不穩(wěn)定的調(diào)度行為而不是完全報錯。6.2 定位鏈路從應(yīng)用到驅(qū)動的逐層排除這次問題的定位過程耗時最長的環(huán)節(jié)其實是確認“第四路到底走的是哪條通路”。我在應(yīng)用層用v4l2-ctl直接看video節(jié)點信息發(fā)現(xiàn)第四路對應(yīng)的video節(jié)點名和拓撲里的某條鏈路對不上。后面對照設(shè)備樹源碼才發(fā)現(xiàn)VC ID配重了。這讓我養(yǎng)成了一個習慣任何時候懷疑多路攝像頭有問題先做三件事——讀設(shè)備樹vc配置、跑media-ctl -p、看dmesg的錯誤日志。順序不能亂因為錯誤日志里報出的實體名稱能幫助你快速定位到底是哪一環(huán)出了問題而不是漫無目的地檢查硬件。6.3 修復(fù)與驗證把第四路sensor的vc-id改成3重新編譯dtb燒錄重啟。之后用media-ctl -p確認四個entity分別對應(yīng)四個VC再用v4l2-ctl對所有通道做了2小時壓力出流沒有再出現(xiàn)丟幀或卡頓。這次調(diào)試的經(jīng)驗對后續(xù)項目很有幫助。Virtual Channel Driver本身并不復(fù)雜它就是一套把MIPI CSI-2的VC機制暴露成多個V4L2視頻設(shè)備的驅(qū)動框架。但因為鏈路長、層級多任何一層的配置錯誤都會表現(xiàn)為出流異常排查起來特別考驗對整條鏈路的理解。我現(xiàn)在做Jetson上的多路采集第一步永遠是打開media graph和設(shè)備樹把通道身份確認清楚再做應(yīng)用層開發(fā)這套習慣幫我省掉了大量返工時間。