Linux 視頻設備驅動 V4L2常用的控制命令說明

設置視頻設備屬性通過ioctl來進行設置 long video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg)

ioctl有三個參數,分別是fd(設備描述符), cmd(控制命令)和parameter(控制命令參數)。
下面根據控制命令,分別進行介紹

1. 控制命令VIDIOC_QUERYCAP
功能:     查詢設備驅動的功能 ;
參數說明: 參數類型爲V4L2的能力描述類型struct v4l2_capability;
struct v4l2_capability {
        __u8    driver[16];     /* i.e. "bttv" */            //驅動名稱,
        __u8    card[32];       /* i.e. "Hauppauge WinTV" */        //
        __u8    bus_info[32];   /* "PCI:" + pci_name(pci_dev) */    //PCI總線信息
        __u32   version;        /* should use KERNEL_VERSION() */
        __u32   capabilities;   /* Device capabilities */        //設備能力
        __u32   reserved[4];
};
返回值說明: 執行成功時,函數返回值爲 0;
函數執行成功後,struct v4l2_capability 結構體變量中的返回當前視頻設備所支持的功能;
例如支持視頻捕獲功能V4L2_CAP_VIDEO_CAPTURE、 V4L2_CAP_STREAMING等。
使用舉例:
-------------------------------------------------------------------------------------------------------
struct v4l2_capability cap;
iret = ioctl(fd_usbcam, VIDIOC_QUERYCAP, &cap);
if(iret < 0){
        printf("get vidieo capability error,error code: %d \n", errno);
        return ;
}
------------------------------------------------------------------------------------------------------
執行完VIDIOC_QUERYCAP命令後,cap變量中包含了該視頻設備的能力信息,程序中通過檢查cap中的設備能力信息來判斷設備是否支持某項功能。


2. 控制命令 VIDIOC_ENUM_FMT
功能: 獲取當前視頻設備支持的視頻格式 。
參數說明:參數類型爲V4L2的視頻格式描述符類型 struct v4l2_fmtdesc
struct v4l2_fmtdesc {
        __u32               index;             /* Format number      */
        enum v4l2_buf_type  type;              /* buffer type        */
        __u32               flags;
        __u8                description[32];   /* Description string */
        __u32               pixelformat;       /* Format fourcc      */
        __u32               reserved[4];
};
返回值說明: 執行成功時,函數返回值爲 0;
struct v4l2_fmtdesc 結構體中的 .pixelformat和 .description 成員返回當前視頻設備所支持的視頻格式;
使用舉例:
-------------------------------------------------------------------------------------------------
struct v4l2_fmtdesc fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.index = 0;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while ((ret = ioctl(dev, VIDIOC_ENUM_FMT, &fmt)) == 0) 
{
        fmt.index++;
        printf("{ pixelformat = ''%c%c%c%c'', description = ''%s'' }\n",
                  fmt.pixelformat & 0xFF, (fmt.pixelformat >> 8) & 0xFF, (fmt.pixelformat >> 16) & 0xFF, 
                  (fmt.pixelformat >> 24) & 0xFF, fmt.description);
}
-------------------------------------------------------------------------------------------------------




3. 控制命令VIDIOC_S_FMT
功能: 設置視頻設備的視頻數據格式,例如設置視頻圖像數據的長、寬,圖像格式(JPEG、YUYV格式);
參數說明:參數類型爲V4L2的視頻數據格式類型 struct v4l2_format;
struct v4l2_format {
        enum v4l2_buf_type type;    //數據流類型,必須永遠是V4L2_BUF_TYPE_VIDEO_CAPTURE
        union {
                struct v4l2_pix_format          pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
                struct v4l2_window              win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
                struct v4l2_vbi_format          vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
                struct v4l2_sliced_vbi_format   sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
                __u8    raw_data[200];                   /* user-defined */
        } fmt;
};
struct v4l2_pix_format {
        __u32                   width;         // 寬,必須是16的倍數
        __u32                   height;        // 高,必須是16的倍數
        __u32                   pixelformat;   // 視頻數據存儲類型,例如是YUV4:2:2還是RGB
        enum v4l2_field       field;
        __u32                   bytesperline;
        __u32                   sizeimage;
        enum v4l2_colorspace colorspace;
        __u32                   priv;
};
返回值說明: 執行成功時,函數返回值爲 0;
使用舉例:
----------------------------------------------------------------------------------------------------------
struct v4l2_format tv4l2_format;


tv4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tv4l2_format.fmt.pix.width = img_width;
tv4l2_format.fmt.pix.height = img_height;
tv4l2_format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
tv4l2_format.fmt.pix.field = V4L2_FIELD_INTERLACED;


iret = ioctl(fd_usbcam, VIDIOC_S_FMT, &tv4l2_format);
-----------------------------------------------------------------------------------------------------------
注意:如果該視頻設備驅動不支持你所設定的圖像格式,視頻驅動會重新修改struct v4l2_format結構體變量的值爲該視頻設備所支持的圖像格式,所以在程序設計中,設定完所


有的視頻格式後,要獲取實際的視頻格式,要重新讀取 struct v4l2_format結構體變量。
使用VIDIOC_G_FMT設置視頻設備的視頻數據格式,VIDIOC_TRY_FMT驗證視頻設備的視頻數據格式。


4. 控制命令VIDIOC_REQBUFS
功能: 請求V4L2驅動分配視頻緩衝區(申請V4L2視頻驅動分配內存),V4L2是視頻設備的驅動層,位於內核空間,所以通過VIDIOC_REQBUFS控制命令字申請的內存位於內核空間,應


用程序不能直接訪問,需要通過調用mmap內存映射函數把內核空間內存映射到用戶空間後,應用程序通過訪問用戶空間地址來訪問內核空間。
參數說明:參數類型爲V4L2的申請緩衝區數據結構體類型struct v4l2_requestbuffers;
struct v4l2_requestbuffers {
        u32                   count;        //緩存數量,也就是說在緩存隊列裏保持多少張照片
        enum v4l2_buf_type    type;         //數據流類型,必須永遠是V4L2_BUF_TYPE_VIDEO_CAPTURE
        enum v4l2_memory      memory;       //V4L2_MEMORY_MMAP或V4L2_MEMORY_USERPTR
        u32                   reserved[2];
};
返回值說明: 執行成功時,函數返回值爲 0,V4L2驅動層分配好了視頻緩衝區;
使用舉例:
-----------------------------------------------------------------------------------------------------
struct v4l2_requestbuffers tV4L2_reqbuf;


memset(&tV4L2_reqbuf, 0, sizeof(struct v4l2_requestbuffers ));


tV4L2_reqbuf.count = 1;             //申請緩衝區的個數
tV4L2_reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2_reqbuf.memory = V4L2_MEMORY_MMAP;        //mmap方式


iret = ioctl(fd_usbcam, VIDIOC_REQBUFS, &tV4L2_reqbuf);
-----------------------------------------------------------------------------------------------------
注意:VIDIOC_REQBUFS會修改tV4L2_reqbuf的count值,tV4L2_reqbuf的count值返回實際申請成功的視頻緩衝區數目;


5. 控制命令VIDIOC_QUERYBUF

功能: 查詢已經分配的V4L2的視頻緩衝區的相關信息,包括視頻緩衝區的使用狀態、在內核空間的偏移地址、緩衝區長度等。在應用程序設計中通過調 VIDIOC_QUERYBUF來獲取內


核空間的視頻緩衝區信息,然後調用函數mmap把內核空間地址映射到用戶空間,這樣應用程序才能夠訪問位於內核空間的視頻緩衝區。
參數說明:參數類型爲V4L2緩衝區數據結構類型 struct v4l2_buffer;
struct v4l2_buffer {
        __u32                   index;
        enum v4l2_buf_type      type;
        __u32                   bytesused;
        __u32                   flags;
        enum v4l2_field         field;
        struct timeval          timestamp;
        struct v4l2_timecode    timecode;
        __u32                   sequence;
        /* memory location */
        enum v4l2_memory        memory;
        union {
                __u32           offset;
                unsigned long   userptr;
        } m;
        __u32                   length;
        __u32                   input;
        __u32                   reserved;
};
返回值說明: 執行成功時,函數返回值爲 0;
struct v4l2_buffer結構體變量中保存了指令的緩衝區的相關信息;一般情況下,應用程序中調用VIDIOC_QUERYBUF取得了內核緩衝區信息後,緊接着調用mmap函數把內核空間地址


映射到用戶空間,方便用戶空間應用程序的訪問。
使用舉例:
-------------------------------------------------------------------------------------------------------
struct v4l2_buffer tV4L2buf;


memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));
tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2buf.memory = V4L2_MEMORY_MMAP;
tV4L2buf.index = i; // 要獲取內核視頻緩衝區的信息編號


iret = ioctl(fd_usbcam, VIDIOC_QUERYBUF, &tV4L2buf);


// 把內核空間緩衝區映射到用戶空間緩衝區
AppBufLength = tV4L2buf.length;
AppBufStartAddr = mmap( NULL,                   /* start anywhere */
                        tV4L2buf.length,
                        PROT_READ | PROT_WRITE, /* access privilege */
                        MAP_SHARED,             /* recommended */
                        fd_usbcam,
                        tV4L2buf.m.offset);
-------------------------------------------------------------------------------------------------------
上述代碼在通過調用VIDIOC_QUERYBUF取得內核空間的緩衝區信息後,接着調用mmap函數把內核空間緩衝區映射到用戶空間;




6. 控制命令VIDIOC_QBUF
功能: 投放一個空的視頻緩衝區到視頻緩衝區輸入隊列中 ;
參數說明:參數類型爲V4L2緩衝區數據結構類型 struct v4l2_buffer;
返回值說明: 執行成功時,函數返回值爲 0;
函數執行成功後,指令(指定)的視頻緩衝區進入視頻輸入隊列,在啓動視頻設備拍攝圖像時,相應的視頻數據被保存到視頻輸入隊列相應的視頻緩衝區中。
使用舉例:
-------------------------------------------------------------------------------------------------------
struct v4l2_buffer tV4L2buf;


memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));


tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2buf.memory = V4L2_MEMORY_MMAP;
tV4L2buf.index = i; //指令(指定)要投放到視頻輸入隊列中的內核空間視頻緩衝區的編號;


iret = ioctl(fd_usbcam, VIDIOC_QBUF, &tV4L2buf);
-------------------------------------------------------------------------------------------------------


7. 控制命令VIDIOC_DQBUF
功能: 從視頻緩衝區的輸出隊列中取得一個已經保存有一幀視頻數據的視頻緩衝區;
參數說明:參數類型爲V4L2緩衝區數據結構類型 struct v4l2_buffer;
返回值說明: 執行成功時,函數返回值爲 0;函數執行成功後,相應的內核視頻緩衝區中保存有當前拍攝到的視頻數據,應用程序可以通過訪問用戶空間來讀取該視頻數據。(前面


已經通過調用函數 mmap做了用戶空間和內核空間的內存映射).
使用舉例:
----------------------------------------------------------------------------------------------------------
struct v4l2_buffer tV4L2buf;


memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));


tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2buf.memory = V4L2_MEMORY_MMAP;


iret = ioctl(fd_usbcam, VIDIOC_DQBUF, &tV4L2buf);
-------------------------------------------------------------------------------------------------
說明: VIDIOC_DQBUF命令結果, 使從隊列刪除的緩衝幀信息傳給了此tVL2buf。
V4L2_buffer結構體的作用就相當於申請的緩衝幀的代理,找緩衝幀的都要先問問它,通過它來聯繫緩衝幀,起了中間橋樑的作用。


8. 控制命令VIDIOC_STREAMON
功能: 啓動視頻採集命令,應用程序調用VIDIOC_STREAMON啓動視頻採集命令後,視頻設備驅動程序開始採集視頻數據,並把採集到的視頻數據保存到視頻驅動的視頻緩衝區中。
參數說明:參數類型爲V4L2的視頻緩衝區類型 enum v4l2_buf_type ;
enum v4l2_buf_type {
        V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,
        V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,
        V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,
        V4L2_BUF_TYPE_VBI_CAPTURE          = 4,
        V4L2_BUF_TYPE_VBI_OUTPUT           = 5,
        V4L2_BUF_TYPE_SLICED_VBI_CAPTURE   = 6,
        V4L2_BUF_TYPE_SLICED_VBI_OUTPUT    = 7,
#if 1
        /* Experimental */
        V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
#endif
        V4L2_BUF_TYPE_PRIVATE              = 0x80,
};
返回值說明: 執行成功時,函數返回值爲 0;函數執行成功後,視頻設備驅動程序開始採集視頻數據,此時應用程序一般通過調用select函數來判斷一幀視頻數據是否採集完成,


當視頻設備驅動完成一幀視頻數據採集並保存到視頻緩衝區中時,select函數返回,應用程序接着可以讀取視頻數據;否則select函數阻塞直到視頻數據採集完成。 Select函數的


使用請讀者參考相關資料。
使用舉例:
----------------------------------------------------------------------------------------------------------
enum v4l2_buf_type v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fd_set fds ;
struct timeval tv;


iret = ioctl(fd_usbcam, VIDIOC_STREAMON, &v4l2type);


FD_ZERO(&fds);
FD_SET(fd_usbcam, &fds);
tv.tv_sec = 2; /* Timeout. */
tv.tv_usec = 0;
iret = select(fd_usbcam+ 1, &fds, NULL, NULL, &tv);
----------------------------------------------------------------------------------------------------------


9. 控制命令VIDIOC_STREAMOFF
功能: 停止視頻採集命令,應用程序調用VIDIOC_ STREAMOFF停止視頻採集命令後,視頻設備驅動程序不在採集視頻數據。
參數說明:參數類型爲V4L2的視頻緩衝區類型 enum v4l2_buf_type;
返回值說明: 執行成功時,函數返回值爲 0;函數執行成功後,視頻設備停止採集視頻數據。
使用舉例:
----------------------------------------------------------------------------------------------------------
enum v4l2_buf_type v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE;


iret = ioctl(fd_usbcam, VIDIOC_STREAMOFF, &v4l2type);
-----------------------------------------------------------------------------------------------------------


10. 控制命令VIDIOC_QUERYSTD
功能:在亞洲,一般使用PAL(720X576)制式的攝像頭,而歐洲一般使用NTSC(720X480),使用VIDIOC_QUERYSTD來檢測:
參數說明:
返回值說明:
typedef __u64 v4l2_std_id;
使用舉例:
-----------------------------------------------------------------------------------------------------------
v4l2_std_id std;
do{
    ret= ioctl(fd, VIDIOC_QUERYSTD, &std);
} while(ret== -1 && errno== EAGAIN);
switch(std) {
    caseV4L2_STD_NTSC:
    //……
    caseV4L2_STD_PAL:
    //……
}
-----------------------------------------------------------------------------------------------------------
以上就是Linux 視頻設備驅動V4L2最常用的控制命令使用說明,通過使用以上控制命令,可以完成一幅視頻數據的採集過程。
V4L2更多的控制命令使用說明請參考:http://v4l2spec.bytesex.org/spec/book1.htm




下面是damo程序(經過實際驗證,修改了網上的例程的錯誤)
-----------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>           
#include <fcntl.h>            
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>


#include <asm/types.h>        
#include <linux/videodev2.h>


#define CAMERA_DEVICE "/dev/video0"
#define CAPTURE_FILE "frame.jpg"


#define VIDEO_WIDTH 640
#define VIDEO_HEIGHT 480
#define VIDEO_FORMAT V4L2_PIX_FMT_YUYV
#define BUFFER_COUNT 4


typedef struct VideoBuffer {
    void   *start;
    size_t  length;
} VideoBuffer;
VideoBuffer framebuf[BUFFER_COUNT];   //修改了錯誤,2012-5.21


int main()
{
    int i, ret;

    // 打開設備
    int fd;
    fd = open(CAMERA_DEVICE, O_RDWR, 0);
    if (fd < 0) {
        printf("Open %s failed\n", CAMERA_DEVICE);
        return -1;
    }

    // 獲取驅動信息
    struct v4l2_capability cap;
    ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (ret < 0) {
        printf("VIDIOC_QUERYCAP failed (%d)\n", ret);
        return ret;
    }
    // Print capability infomations
    printf("Capability Informations:\n");
    printf(" driver: %s\n", cap.driver);
    printf(" card: %s\n", cap.card);
    printf(" bus_info: %s\n", cap.bus_info);
    printf(" version: %08X\n", cap.version);
    printf(" capabilities: %08X\n", cap.capabilities);

    // 設置視頻格式
    struct v4l2_format fmt;
    memset(&fmt, 0, sizeof(fmt));
    fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width       = VIDEO_WIDTH;
    fmt.fmt.pix.height      = VIDEO_HEIGHT;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if (ret < 0) {
        printf("VIDIOC_S_FMT failed (%d)\n", ret);
        return ret;
    }

    // 獲取視頻格式
    ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
    if (ret < 0) {
        printf("VIDIOC_G_FMT failed (%d)\n", ret);
        return ret;
    }
    // Print Stream Format
    printf("Stream Format Informations:\n");
    printf(" type: %d\n", fmt.type);
    printf(" width: %d\n", fmt.fmt.pix.width);
    printf(" height: %d\n", fmt.fmt.pix.height);
    char fmtstr[8];
    memset(fmtstr, 0, 8);
    memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);
    printf(" pixelformat: %s\n", fmtstr);
    printf(" field: %d\n", fmt.fmt.pix.field);
    printf(" bytesperline: %d\n", fmt.fmt.pix.bytesperline);
    printf(" sizeimage: %d\n", fmt.fmt.pix.sizeimage);
    printf(" colorspace: %d\n", fmt.fmt.pix.colorspace);
    printf(" priv: %d\n", fmt.fmt.pix.priv);
    printf(" raw_date: %s\n", fmt.fmt.raw_data);

    // 請求分配內存
    struct v4l2_requestbuffers reqbuf;
    
    reqbuf.count = BUFFER_COUNT;
    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    reqbuf.memory = V4L2_MEMORY_MMAP;
    
    ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf);
    if(ret < 0) {
        printf("VIDIOC_REQBUFS failed (%d)\n", ret);
        return ret;
    }

    // 獲取空間
    VideoBuffer*  buffers = calloc( reqbuf.count, sizeof(*buffers) );
    struct v4l2_buffer buf;

    for (i = 0; i < reqbuf.count; i++) 
    {
        buf.index = i;
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(fd , VIDIOC_QUERYBUF, &buf);
        if(ret < 0) {
            printf("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);
            return ret;
        }

        // mmap buffer
        framebuf[i].length = buf.length;
        framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
        if (framebuf[i].start == MAP_FAILED) {
            printf("mmap (%d) failed: %s\n", i, strerror(errno));
            return -1;
        }
    
        // Queen buffer
        ret = ioctl(fd , VIDIOC_QBUF, &buf);
        if (ret < 0) {
            printf("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);
            return -1;
        }

        printf("Frame buffer %d: address=0x%x, length=%d\n", i, (unsigned int)framebuf[i].start, framebuf[i].length);
    }

    // 開始錄製
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd, VIDIOC_STREAMON, &type);
    if (ret < 0) {
        printf("VIDIOC_STREAMON failed (%d)\n", ret);
        return ret;
    }

    // Get frame
    ret = ioctl(fd, VIDIOC_DQBUF, &buf);
    if (ret < 0) {
        printf("VIDIOC_DQBUF failed (%d)\n", ret);
        return ret;
    }

    // Process the frame
    FILE *fp = fopen(CAPTURE_FILE, "wb");
    if (fp < 0) {
        printf("open frame data file failed\n");
        return -1;
    }
    fwrite(framebuf[buf.index].start, 1, buf.length, fp);
    fclose(fp);
    printf("Capture one frame saved in %s\n", CAPTURE_FILE);

    // Re-queen buffer
    ret = ioctl(fd, VIDIOC_QBUF, &buf);
    if (ret < 0) {
        printf("VIDIOC_QBUF failed (%d)\n", ret);
        return ret;
    }

    // Release the resource
    for (i=0; i< 4; i++) 
    {
        munmap(framebuf[i].start, framebuf[i].length);
    }

    close(fd);
    printf("Camera test Done.\n");
    return 0;
}
-----------------------------------------------------------------------------------------------------------




附件:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *start, size_t length);
參數說明:
——start:映射區的開始地址。
——length:映射區的長度。
——prot:期望的內存保護標誌,不能與文件的打開模式衝突。是以下的某個值,可以通過or運算合理地組合在一起
      —PROT_EXEC //頁內容可以被執行
      —PROT_READ //頁內容可以被讀取
      —PROT_WRITE //頁可以被寫入
        —PROT_NONE //頁不可訪問
——flags:指定映射對象的類型,映射選項和映射頁是否可以共享。它的值可以是一個或者多個以下位的組合體
     —MAP_FIXED //使用指定的映射起始地址,如果由start和len參數指定的內存區重疊於現存的映射空間,重疊部分將會被丟棄。如果指定的起始地址不可用,操作將會失


敗。並且起始地址必須落在頁的邊界上。
     —MAP_SHARED //與其它所有映射這個對象的進程共享映射空間。對共享區的寫入,相當於輸出到文件。直到msync()或者munmap()被調用,文件實際上不會被更新。
     —MAP_PRIVATE //建立一個寫入時拷貝的私有映射。內存區域的寫入不會影響到原文件。這個標誌和以上標誌是互斥的,只能使用其中一個。
     —MAP_DENYWRITE //這個標誌被忽略。
     —MAP_EXECUTABLE //同上
     —MAP_NORESERVE //不要爲這個映射保留交換空間。當交換空間被保留,對映射區修改的可能會得到保證。當交換空間不被保留,同時內存不足,對映射區的修改會引起


段違例信號。
     —MAP_LOCKED //鎖定映射區的頁面,從而防止頁面被交換出內存。
     —MAP_GROWSDOWN //用於堆棧,告訴內核VM系統,映射區可以向下擴展。
     —MAP_ANONYMOUS //匿名映射,映射區不與任何文件關聯。
     —MAP_ANON //MAP_ANONYMOUS的別稱,不再被使用。
     —MAP_FILE //兼容標誌,被忽略。
     —MAP_32BIT //將映射區放在進程地址空間的低2GB,MAP_FIXED指定時會被忽略。當前這個標誌只在x86-64平臺上得到支持。
     —MAP_POPULATE //爲文件映射通過預讀的方式準備好頁表。隨後對映射區的訪問不會被頁違例阻塞。
     —MAP_NONBLOCK //僅和MAP_POPULATE一起使用時纔有意義。不執行預讀,只爲已存在於內存中的頁面建立頁表入口。
——fd:有效的文件描述詞。如果MAP_ANONYMOUS被設定,爲了兼容問題,其值應爲-1。
——offset:被映射對象內容的起點。


返回值:
    成功執行時,mmap()返回被映射區的指針,munmap()返回0。
    失敗時,mmap()返回MAP_FAILED[其值爲(void *)-1],munmap返回-1。errno被設爲以下的某個值。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章