mmap将物理地址映射到用户空间
2016-07-08 09:04
369 查看
1. 申请空间 void *virt_mem = kzalloc(PAGE_SIZE, GFP_KERNEL); 2. 驱动层----->> 实现file_operation接口的.mmap方法 int led_drv_mmap(struct file *filp, struct vm_area_struct *vma) { // vma是一个信息体, 用户提供mmap的请求 // 参数1, vma信息载体 //参数2,用户空间的虚拟起始位置 // 参数3, 物理地址 unsigned long addr; if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) return -EINVAL; addr = virt_to_phys(led_dev->virt_mem); vma->vm_flags |= VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, PAGE_SIZE, vma->vm_page_prot)) { printk(KERN_ERR "%s: io_remap_pfn_range failed\n", __func__); return -EAGAIN; } return 0; } 3. 用户层的掉用 fd = open("/dev/led0", O_RDWR); // mmap int len = PAGE_SIZE; //返回值为映射上来的物理地址 char *mmap_addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); //往里面写点值 memcpy(mmap_addr,str,strlen(str)); sleep(1); //读取数据 read(fd, rbuf, 64); printf("rbuf = %s\n", rbuf);
2. 字符串或中文在屏幕的位置显示行数, 参数1:x轴坐标 参数2:y轴坐标 参数3:显示内容的大小 参数4:显示的内容 void Display_character(unsigned int x,unsigned int y,unsigned int len,unsigned char *string) { int k, xx; unsigned char qh,wh; const unsigned char *mould; unsigned int length =len; printf("length =%d\n",length); for(k=0,xx=x;k<length-1;k++) { if(string[k]&0x80) //中文字符 { qh =string[k]-0xa0; //区号 wh =string[k+1]-0xa0; //位号 mould =&__CHS[((qh-1)*94+wh-1)*32]; Draw_Text16(4+xx,y,0x0000ff,mould); xx+=16; k++; } else { mould =&__ASCII[string[k]*16]; Draw_ASCII(4+xx,y,0xff0000,mould); xx+=8; } } } 3.获取到lcd屏的 vinfo.xres *vinfo.yres*vinfo.bits_per_pixel/8物理空间大小,并映射到应用层 static int init_lcd(char *dev_name) { int framebuffer_fd; /*1.打开帧缓冲设备*/ framebuffer_fd =open(dev_name,O_RDWR); if(framebuffer_fd<0) { printf("Error: failed open framebuffer device!\n"); return -1; } /*2.获取固定参数*/ if(ioctl(framebuffer_fd,FBIOGET_FSCREENINFO,&finfo)) { printf("Error:failed get the framebuffer device`s fix informations!\n"); return -1; } /*3.获取可变参数*/ if(ioctl(framebuffer_fd,FBIOGET_VSCREENINFO,&vinfo)) { printf("Error:failed get the framebuffer device`s var informations!\n"); return -1; } printf("xres =%ld\n",vinfo.xres); printf("yres =%ld\n",vinfo.yres); screensize =(vinfo.xres *vinfo.yres*vinfo.bits_per_pixel/8); printf("screensize =%ld\n",screensize); /*5.映射*/ framebuffer_ptr =(char *)mmap( NULL,//如果此值为NULL,则表示用内核来自动给你分配一块虚拟空间 screensize, //空间大小 PROT_READ|PROT_WRITE,//权限 MAP_SHARED, //是否可以共享 framebuffer_fd, //文件描述符 0); //从哪个地方开始 if(framebuffer_ptr<0) { printf("Error:failed to mmap device mem!\n"); return -1; } memset(framebuffer_ptr,0,screensize); printf("framebuffer_ptr is mmaped ok!\n"); return framebuffer_fd; } 4. 对图片文件的操作 /*1.打开一副图片*/ pic_fd =open(argv[2],O_RDWR); printf("pic_fd=%d\n",pic_fd); /*2.获取图片大小*/ len =lseek(pic_fd, 0, SEEK_END); printf("len =%ld\n",len); buffer =(char *)malloc(len); lseek(pic_fd, 0, SEEK_SET); /*3.读取图片数据*/ read(pic_fd,buffer,len); 5.如果要显示一张图片 图片文件--读取数据--解析图片数据--------数据转换成RGB565--------------- LCD屏需要什么数据(RGB) void draw_bmp(char *bmpfi b45e lename, unsigned short *fb) { unsigned char * bmpdata; int ret; ret = bmp_read_file(bmpfilename, &bmpdata); if (ret) { printf("read bmpfile error.\n"); } printf("bmpread0000000!!!!\n"); bmp2fb16_rgb565(bmpdata, fb); printf("bm2fb1600000000000!!!!\n"); }
相关文章推荐
- JAVA MAIL发送邮件实例
- Zen Coding: 一种快速编写HTML/CSS代码的方法
- Memcache
- Bootstrap Metronic完全响应式管理模板之菜单栏学习笔记
- Mybatis实体类属性名与字段名不相同冲突_4
- Jackson框架的JsonGenerator、ObjectMapper - Json-lib框架的JsonObject、JsonArray
- java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
- spring源码分析之spring-core asm概述
- 工程部署到linux
- java中treemap和treeset实现(红黑树)
- 凸优化 - 2 - 凸集和凸函数
- [Effective JavaScript 笔记]第59条:避免过度的强制转换
- Java的Struts2框架中拦截器使用的实例教程
- JS中加载cssText延时
- angularjs的$on、$emit、$broadcast
- JMS
- 通过xcode生成ipa安装包
- mysql中怎样配置general log
- Bootstrap Metronic完全响应式管理模板学习笔记
- 开机挂载mount etc/fstab与/etc/rc.d/rc.local区别