当前位置:   article > 正文

粤嵌6818开发板嵌入式Linux开发之内存映射_linux 6818 开发板 智能家居

linux 6818 开发板 智能家居

一、内存映射

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字节

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <stdio.h>
  6. #include <sys/mman.h>
  7. int main(int argc, char *argv[])
  8. {
  9. // 1、打开fb0、bmp文件
  10. int lcd_fd = open("/dev/fb0", O_RDWR);
  11. if (lcd_fd == -1)
  12. {
  13. printf("open lcd error!\n");
  14. return -1;
  15. }
  16. int bmp_fd = open("./123.bmp", O_RDONLY);
  17. if (bmp_fd == -1)
  18. {
  19. printf("open bmp error!\n");
  20. return -1;
  21. }
  22. // 2、读取bmp文件的数据
  23. char bmp_buf[800*480*3];
  24. lseek(bmp_fd, 54, SEEK_SET); // 跳过bmp文件头和信息头
  25. read(bmp_fd, bmp_buf, 800*480*3); // 读取bmp文件数据到bmp_buf
  26. //3、数据处理
  27. int lcd_buf[800*480];
  28. int x,y;
  29. for (y = 0; y < 480; y++)
  30. {
  31. for (x = 0; x < 800; x++)
  32. {
  33. 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;
  34. }
  35. }
  36. //4、内存映射
  37. int *p = (int *)mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
  38. if (p == MAP_FAILED)
  39. {
  40. printf("mmap error!\n");
  41. return -1;
  42. }
  43. // 5、将数据拷贝到映射空间
  44. int n;
  45. for(n=0;n<800*480;n++)
  46. {
  47. *(p+n) = lcd_buf[n];
  48. }
  49. /*
  50. p ---> lcd_buf[0]
  51. p+1 ---> lcd_buf[1]
  52. p+2 ---> lcd_buf[2]
  53. p+n ---> lcd_buf[n]
  54. */
  55. // 6、关闭fb0、bmp文件、取消映射
  56. munmap(p, 800*480*4);
  57. close(lcd_fd);
  58. close(bmp_fd);
  59. return 0;
  60. }

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号