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_bufferlength欄位中返回的值相同,並且與驅動程式在多平面 API 的 structv4l2_planelength欄位中返回的值相同。protprot引數描述了所需的記憶體保護。無論裝置型別和資料交換的方向如何,都應將其設定為PROT_READ|PROT_WRITE,允許讀取和寫入影像緩衝區。驅動程式應至少支援此標誌組合。注意
Linux
videobuf核心模組(某些驅動程式使用它)僅支援PROT_READ|PROT_WRITE。當驅動程式不支援所需的保護時,mmap()函式將失敗。與主記憶體訪問相比,裝置記憶體訪問(例如,具有影片捕獲硬體的圖形卡上的記憶體)可能會導致效能損失,或者讀取速度可能明顯慢於寫入速度,反之亦然。在這種情況下,其他 I/O 方法可能更有效。
flagsflags引數指定了對映物件的型別、對映選項以及對頁面的對映副本所做的修改是程序私有的還是與其他引用共享。MAP_FIXED請求驅動程式不選擇除指定地址以外的其他地址。如果無法使用指定的地址,則mmap()將失敗。如果指定了MAP_FIXED,則start必須是頁面大小的倍數。不鼓勵使用此選項。必須設定
MAP_SHARED或MAP_PRIVATE標誌之一。MAP_SHARED允許應用程式與其他(例如,子)程序共享對映的記憶體。注意
某些驅動程式使用的 Linux
videobuf模組僅支援MAP_SHARED。MAP_PRIVATE請求寫時複製語義。V4L2 應用程式不應設定MAP_PRIVATE、MAP_DENYWRITE、MAP_EXECUTABLE或MAP_ANON標誌。fd由
open()返回的檔案描述符。offset裝置記憶體中緩衝區的偏移量。這必須與驅動程式在單平面 API 的 struct
v4l2_bufferm聯合體offset欄位中返回的值相同,並且與驅動程式在多平面 API 的 structv4l2_planem聯合體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
start或length或offset不合適。(例如,它們太大或未對齊在PAGESIZE邊界上。)不支援
flags或prot值。尚未透過 ioctl VIDIOC_REQBUFS ioctl 分配緩衝區。
- ENOMEM
沒有足夠的物理或虛擬記憶體來完成請求。