1.1. 開啟和關閉裝置¶
1.1.1. 透過 V4L2 控制硬體外設¶
使用 V4L2 uAPI 支援的硬體通常由多個裝置或外設組成,每個裝置或外設都有自己的驅動程式。
橋接驅動程式暴露一個或多個 V4L2 裝置節點(參見V4L2 裝置節點命名)。
還有其他驅動程式提供對硬體其他元件的支援,這些元件也可能暴露裝置節點,稱為 V4L2 子裝置。
當這些 V4L2 子裝置被暴露時,它們允許控制那些其他硬體元件——通常透過序列匯流排(如 I²C、SMBus 或 SPI)連線。根據橋接驅動程式的不同,這些子裝置可以透過橋接驅動程式間接控制,或透過媒體控制器以及V4L2 子裝置顯式控制。
需要使用媒體控制器的裝置稱為 MC-中心型 裝置。透過 V4L2 裝置節點完全控制的裝置稱為 影片節點中心型。
使用者空間可以透過呼叫ioctl VIDIOC_QUERYCAP並檢查device_caps 欄位來檢查 V4L2 硬體外設是否為 MC-中心型。
如果裝置在 device_caps 中返回 V4L2_CAP_IO_MC 標誌,則它是 MC-中心型,否則,它是影片節點中心型。
對於 MC-中心型驅動程式,在使用外設之前,需要識別 V4L2 子裝置並透過媒體控制器 API配置管道。此外,子裝置的配置應透過子裝置 API控制。
注意
影片節點中心型裝置仍可能提供媒體控制器和子裝置介面。
然而,在這種情況下,媒體控制器和子裝置介面是隻讀的,並且僅提供裝置資訊。實際配置是透過影片節點完成的。
1.1.2. V4L2 裝置節點命名¶
V4L2 驅動程式作為核心模組實現,由系統管理員手動載入,或在首次發現裝置時自動載入。驅動程式模組插入 videodev 核心模組。它提供了本檔案中指定的輔助函式和通用應用程式介面。
每個載入的驅動程式都會註冊一個或多個主編號為 81 的裝置節點。除非核心以 CONFIG_VIDEO_FIXED_MINOR_RANGES 核心選項編譯,否則次編號是動態分配的。在這種情況下,次編號會根據裝置節點型別按範圍分配。
Video4Linux 子系統支援的裝置節點是
預設裝置節點名稱 |
用途 |
|---|---|
|
用於捕獲/輸出裝置的影片和元資料 |
|
垂直消隱資料(即隱藏字幕、圖文電視) |
|
無線電調諧器和調製器 |
|
軟體定義無線電調諧器和調製器 |
|
觸控感測器 |
|
影片子裝置(由感測器和硬體外設的其他元件使用)[1] |
其中 X 是一個非負整數。
注意
實際的裝置節點名稱取決於系統,因為 udev 規則可能適用。
不能保證
X對於同一裝置保持不變,因為該數字取決於裝置驅動程式的探測順序。如果您需要一個唯一的名稱,udev 預設規則會生成包含可唯一標識 V4L2 裝置節點的連結的/dev/v4l/by-id/和/dev/v4l/by-path/目錄$ tree /dev/v4l /dev/v4l ├── by-id │ └── usb-OmniVision._USB_Camera-B4.04.27.1-video-index0 -> ../../video0 └── by-path └── pci-0000:00:14.0-usb-0:2:1.0-video-index0 -> ../../video0
許多驅動程式支援“video_nr”、“radio_nr”或“vbi_nr”模組選項來選擇特定的影片/廣播/VBI 節點編號。這允許使用者請求裝置節點被命名為例如 /dev/video5,而不是任其隨機。當驅動程式支援多個同類型裝置時,可以分配多個裝置節點編號,用逗號分隔
# modprobe mydriver video_nr=0,1 radio_nr=0,1
在 /etc/modules.conf 中,這可以寫成
options mydriver video_nr=0,1 radio_nr=0,1
當沒有將裝置節點編號作為模組選項給出時,驅動程式會提供一個預設值。
通常,udev 會自動為您在 /dev 中建立裝置節點。如果未安裝 udev,則需要啟用 CONFIG_VIDEO_FIXED_MINOR_RANGES 核心選項,以便能夠正確地將次編號與裝置節點編號關聯起來。即,您需要確定次編號 5 對映到裝置節點名稱 video5。使用此核心選項,不同裝置型別具有不同的次編號範圍。這些範圍列在介面中。
建立字元特殊檔案(使用 mknod)是一項特權操作,並且裝置不能透過主編號和次編號開啟。這意味著應用程式無法可靠地掃描已載入或已安裝的驅動程式。使用者必須輸入裝置名稱,或者應用程式可以嘗試傳統的裝置名稱。
1.1.4. 多次開啟¶
V4L2 裝置可以多次開啟。[2] 當驅動程式支援此功能時,使用者可以例如啟動一個“面板”應用程式來更改亮度或音量等控制元件,而另一個應用程式則捕獲影片和音訊。換句話說,面板應用程式可與 ALSA 音訊混音器應用程式相媲美。僅僅開啟一個 V4L2 裝置不應改變裝置的狀態。[3]
一旦應用程式分配了流資料所需的記憶體緩衝區(透過呼叫ioctl VIDIOC_REQBUFS或ioctl VIDIOC_CREATE_BUFS ioctl,或透過呼叫read()或write()函式隱式分配),該應用程式(檔案控制代碼)就成為裝置的所有者。它不再允許進行會影響緩衝區大小的更改(例如,透過呼叫VIDIOC_S_FMT ioctl),並且其他應用程式不再允許分配緩衝區或啟動或停止流。此時將返回 EBUSY 錯誤程式碼。
僅僅開啟一個 V4L2 裝置並不能授予獨佔訪問許可權。[4] 但是,發起資料交換會將讀取或寫入所請求資料型別以及更改相關屬性的許可權分配給此檔案描述符。應用程式可以使用應用程式優先順序中描述的優先順序機制請求額外的訪問許可權。
1.1.6. 函式¶
為了開啟和關閉 V4L2 裝置,應用程式分別使用open()和close()函式。裝置使用ioctl()函式進行程式設計,如以下章節所述。
仍然有一些陳舊且不常見的驅動程式尚未更新以允許多次開啟。這意味著對於此類驅動程式,當裝置已被佔用時,open()可能會返回 EBUSY 錯誤程式碼。
不幸的是,在許多驅動程式中,開啟無線電裝置通常會將裝置狀態切換到無線電模式。這種行為最終應該得到修復,因為它違反了 V4L2 規範。
驅動程式可以識別 O_EXCL 開啟標誌。目前這不是必需的,因此應用程式無法知道它是否真的有效。