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,此值必须与驱动程序在 v4l2_buffer 结构体的 length 字段中返回的值相同,对于多平面 API,此值必须与驱动程序在 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,此值必须与驱动程序在 v4l2_buffer 结构的 m 联合体 offset 字段中返回的值相同,对于多平面 API,此值必须与驱动程序在 v4l2_plane 结构的 m 联合体 mem_offset 字段中返回的值相同。

7.67.4. 描述

mmap() 函数请求将设备(由 fd 指定)内存中从 offset 开始的 length 个字节映射到应用程序地址空间中,最好是在地址 start 处。后一个地址只是一个提示,通常指定为 0。

合适的 length 和 offset 参数通过 ioctl VIDIOC_QUERYBUF ioctl 查询。必须先使用 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

没有足够的物理或虚拟内存来完成请求。