码迷,mamicode.com
首页 > 其他好文 > 详细

第二十天:mmap内存映射

时间:2014-11-02 23:54:51      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   color   ar   os   使用   for   

    可以说,一天的时间都在了解内存映射mmap这个函数,冯诺依曼结构中表示运算器不能直接对硬盘上的文件进行操作。mmap函数的功能就是将文件映射到某一段内存中,然后操作内存就相当与操作文件。这样的话对文件操作更加方便。mamp函数的定义如下:void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize);一共有六个参数,参数算是比较多了。第一个表示映射内存的起始地址,如果为NULL,那么操作系统会自动的找到空闲的内存映射。第二个参数是映射长度,第三个是映射区域的保护方式,第四个是影响映射区域的各种特性第五个为文件描述符,第六个文件映射的偏移量,通常设置为0。下面看代码来理解这个函数:

 1 #include<stdio.h>
 2 #include<fcntl.h>
 3 #include<sys/mman.h>
 4 #include<string.h>
 5 
 6 int main()
 7 {
 8     int fd = 0;
 9     int file_size = 0;
10     void *add = NULL;
11     
12     fd = open("hello",O_RDWR|O_CREAT,0644);
13     if(fd < 0){
14         perror("open");
15         return 1;
16     }
17     file_size = lseek(fd,0,SEEK_END);
18     lseek(fd,0,SEEK_SET);
19 
20     add = mmap(NULL,file_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
21     if(add ==(void *)-1){
22         perror("mmap");
23         return 1;
24     }
25     strcpy(add,"linrong ");
26     printf("%s\n",add);
27     close(fd);
28 }

 这个代码的作用就是将文件映射到add地址上,然后直接往内存中写内容,改变文件的值。

  后面花了比较多的时间来写三个函数,一个是用四个颜色将屏幕分成四份,一个是在屏幕中写“中”。还有一个是在屏幕中显示一张图片,还有作业为将rgb888转换成rgb565。

  直接贴出代码,就是对屏幕文件/dev/fb0进行操作。如果没有这个文件可以在/etc/grub.conf 的kernel最后中加入VGA=0x314。注意一点是:以下代码要在原始终端中运行才有效果,我的屏幕分辨率是1280*800 。如果不同要对代码里面的一些值进行更改。

bubuko.com,布布扣
 1 #include<stdio.h>
 2 #include<fcntl.h>
 3 #include<sys/mman.h>
 4 #include<string.h>
 5 #include<linux/fb.h> 
 6 
 7 void clean_srcean(unsigned long *add,int x,int y);
 8 void drawline(unsigned long *add ,int x0,int y0,int x1 ,int y1,int color);
 9 int main()
10 {
11     int fd = 0;
12     int file_size = 0;
13     void *add = NULL;
14     
15     fd = open("/dev/fb0",O_RDWR|O_CREAT,0644);
16     if(fd < 0){
17         perror("open");
18         return 1;
19     }
20     struct fb_var_screeninfo info;
21     int ret = ioctl(fd,FBIOGET_VSCREENINFO,&info);
22     if(ret < 0){
23         perror("loctl");
24         return 1;
25     }
26     file_size = info.xres * info.yres * info.bits_per_pixel >> 3 ;
27     printf("vga is %d * %d\n",info.xres,info.yres);
28     printf("bits_per_pixel is %d\n",info.bits_per_pixel);
29     add = mmap(NULL,file_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
30     if(add ==(void *)-1){
31         perror("mmap");
32         return 1;
33     }
34     clean_srcean(add,info.xres,info.yres);
35     drawline(add,0,0,400,640,0x00ff0000);
36     drawline(add,0,640,400,1280,0x000000ff);
37     drawline(add,400,0,800,640,0x00ff00ff);
38     drawline(add,400,640,800,1280,0x0000ff00);
39     close(fd);
40 }
41 
42 void clean_srcean(unsigned long *add,int x,int y){
43     int i;
44     for(i=0;i<x*y;i++)
45         add[i] = 0x0000ff00;
46 
47 }
48 void drawline(unsigned long *add ,int x0,int y0,int x1,int  y1,int color){
49     int i,j;
50     for(i =x0;i<x1;i++)
51         for(j = y0;j<y1;j++)
52             add[i*1280+j] = color;
53 
54 }
四颜色分屏

 

bubuko.com,布布扣
 1 #include<stdio.h>
 2 #include<fcntl.h>
 3 #include<sys/mman.h>
 4 #include<string.h>
 5 #include<linux/fb.h> 
 6 
 7 void clean_srcean(unsigned long *add,int x,int y);
 8 void drawline(unsigned long *add ,int x0,int y0,int x1 ,int y1,unsigned long color);
 9 int main()
10 {
11     int fd = 0;
12     int file_size = 0;
13     void *add = NULL;
14     
15     fd = open("/dev/fb0",O_RDWR|O_CREAT,0644);
16     if(fd < 0){
17         perror("open");
18         return 1;
19     }
20     struct fb_var_screeninfo info;
21     int ret = ioctl(fd,FBIOGET_VSCREENINFO,&info);
22     if(ret < 0){
23         perror("loctl");
24         return 1;
25     }
26     file_size = info.xres * info.yres * info.bits_per_pixel >> 3 ;
27     printf("vga is %d * %d\n",info.xres,info.yres);
28     printf("bits_per_pixel is %d\n",info.bits_per_pixel);
29     add = mmap(NULL,file_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
30     if(add ==(void *)-1){
31         perror("mmap");
32         return 1;
33     }
34     clean_srcean(add,info.xres,info.yres);
35     drawline(add,50,600,750,610,0x00ff0000);
36     drawline(add,200,300,210,900,0x00ff0000);
37     drawline(add,600,300,610,900,0x00ff0000);
38     drawline(add,200,300,600,310,0x00ff0000);
39     drawline(add,200,900,610,910,0x00ff0000);
40     close(fd);
41 }
42 
43 void clean_srcean(unsigned long *add,int x,int y){
44     int i ;
45     for(i = 0;i<x*y;i++)    
46         add[i] = 0x0000ff00;
47 
48 }
49 void drawline(unsigned long *add ,int x0,int y0,int x1,int  y1,unsigned long color){
50     int i,j;
51     for(i =x0;i<x1;i++)
52         for(j = y0;j<y1;j++)
53             add[i*1280+j] = color;
54 
55 }
屏幕中写“中”

 

bubuko.com,布布扣
 1 #include<stdio.h>
 2 #include<fcntl.h>
 3 #include<sys/mman.h>
 4 #include<string.h>
 5 #include<linux/fb.h> 
 6 
 7 void clean_srcean(unsigned long *add,int x,int y);
 8 int main()
 9 {
10     int fd = 0;
11     int file_size = 0;
12     void *add = NULL;
13     
14     fd = open("/dev/fb0",O_RDWR|O_CREAT,0644);
15     if(fd < 0){
16         perror("open");
17         return 1;
18     }
19     struct fb_var_screeninfo info;
20     int ret = ioctl(fd,FBIOGET_VSCREENINFO,&info);
21     if(ret < 0){
22         perror("loctl");
23         return 1;
24     }
25     file_size = info.xres * info.yres * info.bits_per_pixel >> 3 ;
26     add = mmap(NULL,file_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
27     if(add ==(void *)-1){
28         perror("mmap");
29         return 1;
30     }
31     int fp = open("2.bmp",O_RDWR);
32     if(fp < 0){
33         perror("open");
34         return 1;
35     }
36     lseek(fp,54,SEEK_SET);
37     ret = read(fp,add,file_size);
38     if(ret < 0){
39         perror("read");
40         return 1;
41     }
42     close(fp);
43     close(fd);
44 } 
显示图片

 

   前两个代码都是利用两点确定一个矩形来完成画线和区域划分。最后显示图片代码要注意一定要使用位图。显示的时候因为位图的前54个字节是保存图片信息的。所以显示的时候要偏移54个字节。

  rgb888转换成rgb565的思路是装换过程,取高位保存。涉及到位运算。底下代码还是有些错误。后面回来再改,先保存下。

bubuko.com,布布扣
 1 #include<stdio.h>
 2 #include<sys/mman.h>
 3 #include<fcntl.h>
 4 #include<string.h>
 5 void rgb888torgb565(char *rgb888,char *rgb565);
 6 int main()
 7 {
 8     int oldpicture = 0;
 9     oldpicture = open("old.bmp",O_RDWR);
10     if(oldpicture < 0){
11         perror("open");
12          return 1;
13     }
14     int newpicture = 0;
15     newpicture = open("new.bmp",O_RDWR|O_CREAT,0755);
16     if(newpicture < 0){
17         perror("open");
18         return 1;
19     }
20     int old_size = lseek(oldpicture,0,SEEK_END);
21     lseek(oldpicture,54,SEEK_SET);
22     lseek(newpicture,54,SEEK_SET);
23     printf("old_size is %d\n",old_size);
24     
25     char a[54] = {0};
26     char rgb888[4] = {0};
27     char rgb565[2] = {0};
28 
29     int ret = 0;
30     int i  = 0;
31     while(i < old_size - 54){
32         ret=read(oldpicture,rgb888,4);
33         if(ret < 0){
34             perror("read");
35             return 1;
36         }
37         rgb888torgb565(rgb888,rgb565);
38         ret = write(newpicture,rgb565,2);
39         if(ret < 0){
40             perror("write");
41             return 1;
42         }
43         i = i + 4;
44 
45     }
46 
47 
48 void rgb888torgb565(char *rgb888,char *rgb565){
49     
50     rgb565[0] = (rgb888[1] & 0xf8) | ((rgb888[2] & 0xe0 >> 5));
51     rgb565[1] = ((rgb888[2] & 0x1c) << 3) | ((rgb888[3] & 0xf1) >> 3);
52 
53 }
rgb888转rgb565

 

第二十天:mmap内存映射

标签:style   blog   http   io   color   ar   os   使用   for   

原文地址:http://www.cnblogs.com/linrong/p/4070220.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!