7.67. V4L2 mmap()

7.67.1. 名稱

v4l2-mmap - 將裝置記憶體對映到應用程式地址空間

7.67.2. 概要

#include <unistd.h>
#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)

7.67.3. 引數

start

將緩衝區對映到應用程式地址空間中的此地址。如果指定了 MAP_FIXED 標誌,則 start 必須是頁面大小的倍數,並且當無法使用指定的地址時,mmap 將失敗。不鼓勵使用此選項;應用程式應該在此處僅指定一個 NULL 指標。

length

要對映的記憶體區域的長度。這必須與驅動程式在單平面 API 的 struct v4l2_buffer length 欄位中返回的值相同,並且與驅動程式在多平面 API 的 struct v4l2_plane length 欄位中返回的值相同。

prot

prot 引數描述了所需的記憶體保護。無論裝置型別和資料交換的方向如何,都應將其設定為 PROT_READ | PROT_WRITE,允許讀取和寫入影像緩衝區。驅動程式應至少支援此標誌組合。

注意

  1. Linux videobuf 核心模組(某些驅動程式使用它)僅支援 PROT_READ | PROT_WRITE。當驅動程式不支援所需的保護時,mmap() 函式將失敗。

  2. 與主記憶體訪問相比,裝置記憶體訪問(例如,具有影片捕獲硬體的圖形卡上的記憶體)可能會導致效能損失,或者讀取速度可能明顯慢於寫入速度,反之亦然。在這種情況下,其他 I/O 方法可能更有效。

flags

flags 引數指定了對映物件的型別、對映選項以及對頁面的對映副本所做的修改是程序私有的還是與其他引用共享。

MAP_FIXED 請求驅動程式不選擇除指定地址以外的其他地址。如果無法使用指定的地址,則 mmap() 將失敗。如果指定了 MAP_FIXED,則 start 必須是頁面大小的倍數。不鼓勵使用此選項。

必須設定 MAP_SHAREDMAP_PRIVATE 標誌之一。MAP_SHARED 允許應用程式與其他(例如,子)程序共享對映的記憶體。

注意

某些驅動程式使用的 Linux videobuf 模組僅支援 MAP_SHAREDMAP_PRIVATE 請求寫時複製語義。V4L2 應用程式不應設定 MAP_PRIVATEMAP_DENYWRITEMAP_EXECUTABLEMAP_ANON 標誌。

fd

open() 返回的檔案描述符。

offset

裝置記憶體中緩衝區的偏移量。這必須與驅動程式在單平面 API 的 struct v4l2_buffer m 聯合體 offset 欄位中返回的值相同,並且與驅動程式在多平面 API 的 struct v4l2_plane m 聯合體 mem_offset 欄位中返回的值相同。

7.67.4. 描述

mmap() 函式請求將 length 位元組從 fd 指定的裝置記憶體中的 offset 開始對映到應用程式地址空間中,最好位於地址 start。後一個地址僅是一個提示,通常指定為 0。

可以使用 ioctl VIDIOC_QUERYBUF ioctl 查詢合適的 length 和 offset 引數。必須先使用 ioctl VIDIOC_REQBUFS ioctl 分配緩衝區,然後才能查詢它們。

要取消對映緩衝區,可以使用 munmap() 函式。

7.67.5. 返回值

成功時,mmap() 返回指向對映緩衝區的指標。出錯時,返回 MAP_FAILED (-1),並適當地設定 errno 變數。可能的錯誤程式碼為

EBADF

fd 不是有效的檔案描述符。

EACCES

fd 沒有開啟以進行讀取和寫入。

EINVAL

startlengthoffset 不合適。(例如,它們太大或未對齊在 PAGESIZE 邊界上。)

不支援 flagsprot 值。

尚未透過 ioctl VIDIOC_REQBUFS ioctl 分配緩衝區。

ENOMEM

沒有足夠的物理或虛擬記憶體來完成請求。