模拟智能家居项目Part3

来自于两周的粤嵌实习,主要是网络编程和线程控制部分比较重要,贯穿了常用的C语言用法,值得做一个复盘,共有11个部分,本节介绍了地址映射方法。

Posted by LJJ on July 1, 2020

模拟智能家居项目

基本原理

  • write函数效率是比较低,是因为执行的时候要从用户态转换到内核态 为了提高效率,所以就有了映射,映射就是把用户空间的东西映射到 进程的地址空间中去

  • 映射函数mmap

    头文件
    #include <sys/mman.h>
    函数原型
    void *mmap(void *addr, size_t length, int prot, int flags,
    int fd, off_t offset);
    函数的功能
    把fd所代表的文件映射到进程的地址空间
    函数的参数
    void *addr			//就是你要映射到进程地址空间区域的首地址(一般填NULL,由操作系统自行分配)
    size_t length		//就是你要映射的长度
    int prot			//就是你用何种权限去映射  PROT_READ | PROT_WRITE
    int flags			//以何种方式去映射 MAP_SHARED(以共享的方式去映射,其他映射了 这个文件
    的进程也可以访问这个映射的内存区域)
    int fd				//就是代表你要映射的那个文件的文件描述符
    off_t offset		//就是你要从文件的哪个位置开始映射一般填0(从文件的头开始映射)
    函数的返回值
    成功:返回映射区域的首地址
    失败:返回MAP_FAILED
      
    解除映射函数
    函数的功能 
    解除映射区域
    函数原型
    int munmap(void *addr, size_t length);
    void *addr	
    //填要解除的映射区域的首地址
    size_t length
    //填解除的映射区域的长度
    返回值 
    成功:返回0
    失败:返回-1
    

任务要求

  • 把write的方式改成映射的方式实现屏幕显示大红色
  • 具体步骤:
    • 打开帧缓冲设备文件
    • 将打开后的帧缓冲设备文件映射到进程的地址空间中去
    • 再把颜色值写入到映射区域中去
    • 收尾工作 ,解除映射 ,关闭文件
  • 把write的方式改成映射的方式实现屏幕显示七种颜色

实现代码

  • p1

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/mman.h>
      
    int *p = NULL;
      
      
    void draw_point(int x, int y, int color)
    {	
    	if(x >= 0 && x < 800 && y >= 0 && y < 480)
    	{
    		*(p + x + y * 800) = color; //颜色值给到映射区域的空间中去
    	}
      	
    }
      
    int main()
    {
    	//1.打开帧缓冲设备文件
    	int lcd_fd = open("/dev/ubuntu_lcd",O_RDWR);
    	if(lcd_fd < 0)
    	{
    		perror("open lcd_fd error\n");
    	}
    	//2.将打开后的帧缓冲设备文件映射到进程的地址空间中去
    	p = mmap(NULL, 800*480*4, PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd, 0);
    	if(p == MAP_FAILED)
    	{
    		perror("mmap error\n");
    	}
    	//3.再把颜色值写入到映射区域中去
    	int i,j;
    	for(i = 0; i < 480; i++)			//行
    	{
    		for(j = 0; j < 800; j++)		//列
    		{
    			draw_point(j, i, 0x0000FF00);
    		}
    	}
      	
    	//4.收尾工作 
    		//解除映射 
    		munmap(p, 800*480*4);
    		//关闭文件
    		close(lcd_fd);
      		
      	
      	
      	
    	return 0;
    }
    
  • p2

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/mman.h>
      
    int *p = NULL;
      
      
    void draw_point(int x, int y, int color)
    {	
    	if(x >= 0 && x < 800 && y >= 0 && y < 480)
    	{
    		*(p + x + y * 800) = color; //颜色值给到映射区域的空间中去
    	}
      	
    }
      
    int main()
    {
    	//1.打开帧缓冲设备文件
    	int lcd_fd = open("/dev/ubuntu_lcd",O_RDWR);
    	if(lcd_fd < 0)
    	{
    		perror("open lcd_fd error\n");
    	}
    	//2.将打开后的帧缓冲设备文件映射到进程的地址空间中去
    	p = mmap(NULL, 800*480*4, PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd, 0);
    	if(p == MAP_FAILED)
    	{
    		perror("mmap error\n");
    	}
    	//3.再把颜色值写入到映射区域中去
    	int color_value[7] = {0x00FF0000,0x00FFFF00,0x00FF00FF,0x0000FFFF,0x00FFFFFF,0x00000000,0x0000FF00};
    	int i,j,num = 0;
    	while(1)
    	{
    		for(i = 0; i < 480; i++)			//行
    		{
    			for(j = 0; j < 800; j++)		//列
    			{
    				draw_point(j, i, color_value[num]);
    			}
    		}
    		num++;//num = num + 1;
    		if(num == 7)
    		{
    			num = 0;
    		}
    		sleep(2);
    	}
      
      	
    	//4.收尾工作 
    		//解除映射 
    		munmap(p, 800*480*4);
    		//关闭文件
    		close(lcd_fd);
      		
      	
      	
      	
    	return 0;
    }