模拟智能家居项目
基本原理
-
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; }