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
没有足够的物理或虚拟内存来完成请求。