赞
踩
1.内存映射的概念
把文件的一个区间映射到进程的虚拟地址空间 ,获得一段虚拟地址, 实现文件磁盘地址和这一段虚拟地址的一一对映关系。(即往这段虚拟地址写入数据,就相当于往这个文件中写入数据)
2.内存映射与普通文件IO的区别
例如:想把一些数据写入到文件中。
普通文件IO:
open()访问文件 -> 得到一个文件描述符fd -> 直接往文件描述符fd写入数据就可以了 -> 关闭文件描述符fd。
内存映射:
open()访问文件 -> 得到一个文件描述符fd -> 根据文件描述符fd去内存空间上映射一块空间,得到一个地址p -> 用户只需要将数据拷贝到内存空间上就可以了 -> 对应的文件就会有相应的变化 -> 撤销映射 -> 关闭文件描述符fd。
使用内存映射刷图片的优点:相对普通文件IO虽然代码步骤增加了,但是刷图的速度会更快。
3.内存映射相关函数
内存映射函数 mmap的用法
man 2 mmap
头文件:
#include <sys/mman.h>
函数原型:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
返回值类型:void *
返回值:
成功:返回指向映射空间首地址的指针
失败:MAP_FAILED
形参一:
addr:映射空间首地址,一般设置NULL,让系统决定
形参二:
length:设置映射空间的大小 在这里我们是800 * 480 * 4字节
形参三:
prot:映射空间权限
PROT_READ 可读
PROT_WRITE 可写
常用这两个,如果需要可读可写,只需要将两个或上即可
形参四:
flags:映射空间属性
MAP_SHARED:共享属性 (打开文件方式需要可读可写)
形参五:
fd:想要映射的文件对应文件描述符(先打开文件,才可以映射)
形参六:
offset:被映射文件的映射位置的偏移量(相对于映射空间的首地址),设置0
取消映射函数 munmap的用法
头文件:
#include <sys/mman.h>
函数原型:
int munmap(void *addr, size_t length);
返回值类型:int
返回值:
成功:0
失败:-1
形参一:
addr:需要取消的映射空间的首地址
形参二:
length:需要取消的映射空间的大小 在这里我们是800 * 480 * 4字节
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <sys/mman.h>
-
- int main(int argc, char *argv[])
- {
- // 1、打开fb0、bmp文件
- int lcd_fd = open("/dev/fb0", O_RDWR);
- if (lcd_fd == -1)
- {
- printf("open lcd error!\n");
- return -1;
- }
- int bmp_fd = open("./123.bmp", O_RDONLY);
- if (bmp_fd == -1)
- {
- printf("open bmp error!\n");
- return -1;
- }
- // 2、读取bmp文件的数据
- char bmp_buf[800*480*3];
- lseek(bmp_fd, 54, SEEK_SET); // 跳过bmp文件头和信息头
- read(bmp_fd, bmp_buf, 800*480*3); // 读取bmp文件数据到bmp_buf
-
- //3、数据处理
- int lcd_buf[800*480];
- int x,y;
- for (y = 0; y < 480; y++)
- {
- for (x = 0; x < 800; x++)
- {
- lcd_buf[800*(479-y)+x] = bmp_buf[3*(800*y+x)] | bmp_buf[3*(800*y+x)+1]<<8 | bmp_buf[3*(800*y+x)+2]<<16;
- }
- }
-
- //4、内存映射
- int *p = (int *)mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
- if (p == MAP_FAILED)
- {
- printf("mmap error!\n");
- return -1;
- }
-
- // 5、将数据拷贝到映射空间
- int n;
- for(n=0;n<800*480;n++)
- {
- *(p+n) = lcd_buf[n];
- }
-
- /*
- p ---> lcd_buf[0]
- p+1 ---> lcd_buf[1]
- p+2 ---> lcd_buf[2]
-
- p+n ---> lcd_buf[n]
- */
-
- // 6、关闭fb0、bmp文件、取消映射
- munmap(p, 800*480*4);
- close(lcd_fd);
- close(bmp_fd);
- return 0;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。