Drivers

為什麼 USB 影片會在 Realtime Linux 中丟幀?

  • January 26, 2022

在應用了實時 Linux 更新檔的四個 USB 攝像頭連接到 Ubuntu 20.04 時,我們遇到了每 60 秒左右失去一幀的問題。從使用者程式碼ioctl(VIDIOC_DQBUF)呼叫級別,我們看到v4l2_buffer.sequence跳過了一個緩衝區,但沒有報告錯誤。奇怪的是,一個攝像頭不會跳過,但三個會跳過,即使它們都在單獨的 USB 埠上。

查看核心調試資訊,我們看到如下資訊:

Jan 21 08:48:52 kernel: [ 612.290354] uvcvideo: frame 1955 stats: 0/151/151 packets, 0/0/151 pts (!early initial), 0/151 scr, last pts/stc/sof 0/0/0
Jan 21 08:48:52 kernel: [ 612.291017] uvcvideo: frame 1940 stats: 0/151/151 packets, 0/0/151 pts (!early initial), 0/151 scr, last pts/stc/sof 0/0/0
Jan 21 08:48:52 kernel: [ 612.294264] uvcvideo: frame 1956 stats: 0/9/9 packets, 0/0/9 pts (!early initial), 0/9 scr, last pts/stc/sof 0/0/0
Jan 21 08:48:52 kernel: [ 612.294269] uvcvideo: Marking buffer as bad (error bit set).
Jan 21 08:48:52 kernel: [ 612.294270] uvcvideo: Frame complete (FID bit toggled).
Jan 21 08:48:52 kernel: [ 612.294270] uvcvideo: frame 1957 stats: 0/1/1 packets, 0/0/0 pts (!early !initial), 0/1 scr, last pts/stc/sof 0/1217480818/18547
Jan 21 08:48:52 kernel: [ 612.294272] uvcvideo: Marking buffer as bad (error bit set).
Jan 21 08:48:52 kernel: [ 612.294678] uvcvideo: frame 1958 stats: 0/2/2 packets, 0/0/0 pts (!early !initial), 0/1 scr, last pts/stc/sof 0/1217480818/18547
Jan 21 08:48:52 kernel: [ 612.294682] uvcvideo: Marking buffer as bad (error bit set).
Jan 21 08:48:52 kernel: [ 612.294682] uvcvideo: Frame complete (FID bit toggled).
Jan 21 08:48:52 kernel: [ 612.294683] uvcvideo: frame 1959 stats: 0/1/1 packets, 0/0/0 pts (!early !initial), 0/1 scr, last pts/stc/sof 0/1267616628/19316
Jan 21 08:48:52 kernel: [ 612.294685] uvcvideo: Marking buffer as bad (error bit set).
Jan 21 08:48:52 kernel: [ 612.294686] uvcvideo: Frame complete (EOF found).
Jan 21 08:48:52 kernel: [ 612.294888] uvcvideo: Dropping payload (out of sync).
Jan 21 08:48:52 kernel: [ 612.295094] uvcvideo: Marking buffer as bad (error bit set).
Jan 21 08:48:52 kernel: [ 612.295094] uvcvideo: Dropping payload (out of sync).
Jan 21 08:48:52 kernel: [ 612.295299] uvcvideo: Dropping payload (out of sync).
Jan 21 08:48:52 kernel: [ 612.295509] uvcvideo: Marking buffer as bad (error bit set).
Jan 21 08:48:52 kernel: [ 612.295510] uvcvideo: Dropping payload (out of sync).
Jan 21 08:48:52 kernel: [ 612.295715] uvcvideo: frame 1960 stats: 0/5/5 packets, 2/4/3 pts (!early !initial), 2/3 scr, last pts/stc/sof 1284525428/1284525171/19827

查看原始碼,Frame complete (FID bit toggled)意味著 USB 驅動程序尚未發送完整的幀(否則我們會收到一條(EOF found)消息),這由顯示的日誌0/2/2 packets而不是0/151/151.

我現在該如何進行調試?我很難相信 USB 驅動程序有問題,但是堆棧中是否有一些不太適合 RTLinux 的組件?

是否有更高優先級的任務或執行緒干擾您的 USB 攝像頭/埠?

預設情況下,在 PREEMPT_RT 上(或在主線 linux 上使用執行緒中斷時)所有 IRQ 執行緒將以 SCHED_FIFO 的 50 prio 執行。因此,除非您將這些執行緒/任務設置為更高的優先級,否則它們很可能會被其他東西搶占。

例如,linux proaudio 使用者將始終將他們的音頻介面設置為系統上的最高優先級,以避免它被其他任務/執行緒搶占或中斷……您將希望為您的相機和重要任務做類似的事情。

另一種可能性是您在一個/一些 USB 埠上共享中斷 - 這也可能導致間歇性下降。您應該能夠通過查看 procfs 中的中斷來判斷。您在 3 個攝像頭上而不是在一個攝像頭上丟球的事實讓我覺得有些東西是共享的/在後台被戳…

除此之外,您可以使用 ftrace 更好地了解正在發生的事情以及導致延遲的功能/可能是罪魁禍首。如果您發現某些東西確實不合適,可能latencytop也可能會給出一些提示。

編輯:

並且這些“uvcvideo: Marking buffer as bad (error bit set)”消息看起來很可疑。– 您可能需要為您的相機設置一些適當的值,如此處所述;

https://stackoverflow.com/questions/17155738/uvcvideo-marking-buffer-as-bad-error-bit-set

做不到這一點,我在這裡發現了一個錯誤報告;https://bugzilla.kernel.org/show_bug.cgi?id=207045有一個連結更新檔應該可以解決這個問題……

它仍然適用於 linux-5.16.2;https://lore.kernel.org/lkml/20200420191506.664877-1-julianmeyer2000@gmail.com/

如果您的硬體存在此問題,可能會有所幫助。你永遠不知道。

引用自:https://unix.stackexchange.com/questions/687945