zoukankan      html  css  js  c++  java
  • Linux framebuffer测试程序

      Linux framebuffer的框架非常简单, 对于应用程序就是操作一块内存(俗称帧缓存), 当然也有可能是双缓存, 一般用于高帧率场景, 一块帧在填充数据时, 另一块在显示, 接着对调过来,

    那通过设置哪里告知驱动层读取哪块帧数据呢? 答案是用vinfo.xoffset, vinfo.yoffset

      需要注意的是, 无论用write()、还是mmap()后直接操作内存都只是填充内存而已, 并不代表能够立马显示, 这得看驱动, 如果驱动实现了自刷新(不断从帧缓存拿数据刷到LCD上), 那填充数据到帧缓存就会立马显示出来,

    如果驱动没有实现,那应用程序需要主动的调用 ioctl(fp, FBIOPAN_DISPLAY, &vinfo);, 告知驱动可以刷数据了, 如果这都没显示出来, 估计驱动没实现FBIOPAN_DISPLAY功能。

    示例代码:(驱动实现自刷新, 应用依次显示黄、蓝、红,最后画线)

    #include <unistd.h>  
    #include <stdio.h>  
    #include <fcntl.h>  
    #include <linux/fb.h>  
    #include <sys/mman.h>  
    #include <stdlib.h>  
    #include <string.h>
    
    #define RED    0xF800
    #define YELLOW    0xFFE0
    #define BLUE     0x001F
    #define WHITE    0xFFFF 
    #define BLACK    0x0000
    
    
    void fill_color16(short *fb_addr, short bit_map, int psize)
    {
        int i;
        for(i=0; i<psize; i++) {
            *fb_addr = bit_map;
            fb_addr++;
        }
    }
    
    int main ()   
    {  
        int fp=0;  
        struct fb_var_screeninfo vinfo;  
        struct fb_fix_screeninfo finfo;  
        long screensize=0;  
        char *fbp = NULL, *test_fbp=NULL;    
        int x = 0, y = 0;  
        long location = 0;
        int i;
        int num = 5;
        int pix_size=0;
    
        fp = open("/dev/graphics/fb0", O_RDWR);  
    
        if(fp < 0) {  
            printf("Error : Can not open framebuffer device/n");  
            exit(1);  
        }  
    
        if(ioctl(fp, FBIOGET_FSCREENINFO, &finfo)){  
            printf("Error reading fixed information/n");  
            exit(2);  
        }  
    
        if(ioctl(fp, FBIOGET_VSCREENINFO, &vinfo)){  
            printf("Error reading variable information/n");  
            exit(3);  
        }  
    
        screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;  
    
        printf("The phy mem = 0x%x, total size = %d(byte)
    ", finfo.smem_start, finfo.smem_len);  
        printf("xres =  %d, yres =  %d, bits_per_pixel = %d
    ", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);  
        printf("So the screensize = %d(byte), using %d frame
    ", screensize, finfo.smem_len/screensize);
        printf("vinfo.xoffset = %d, vinfo.yoffset = %d
    ", vinfo.xoffset, vinfo.yoffset);  
        printf("vinfo.vmode is :%d
    ", vinfo.vmode);  
        printf("finfo.ypanstep is :%d
    ", finfo.ypanstep);  
        printf("vinfo.red.offset=0x%x
    ", vinfo.red.offset);
        printf("vinfo.red.length=0x%x
    ", vinfo.red.length);
        printf("vinfo.green.offset=0x%x
    ", vinfo.green.offset);
        printf("vinfo.green.length=0x%x
    ", vinfo.green.length);
        printf("vinfo.blue.offset=0x%x
    ", vinfo.blue.offset);
        printf("vinfo.blue.length=0x%x
    ", vinfo.blue.length);
        printf("vinfo.transp.offset=0x%x
    ", vinfo.transp.offset);
        printf("vinfo.transp.length=0x%x
    ", vinfo.transp.length);
        
    
        fbp =(char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);  
        if ((int)fbp == -1)  
        {    
            printf ("Error: failed to map framebuffer device to memory./n");  
            exit (4);  
        }
        printf("Get virt mem = %p
    ", fbp);  
    
    
        pix_size = vinfo.xres * vinfo.yres;
        /* using first frame, for FBIOPAN_DISPLAY
         * 当刷新需要调用FBIOPAN_DISPLAY, 要告知驱动刷哪块帧, 用到下面两个参数
         * 如果使用第二帧buffer -> vinfo.xoffset = 0; vinfo.yoffset = vinfo.yres;
         */
        vinfo.xoffset = 0;
        vinfo.yoffset = 0;
    
        /* show color loop */
        while(num--) {
            printf("
    drawing YELLOW......
    ");
            fill_color16((short *)fbp, YELLOW, pix_size);
            //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
            sleep(3);
    
            printf("
    drawing BLUE......
    ");
            fill_color16((short *)fbp, BLUE, pix_size);
            //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
            sleep(3);
            
            printf("
    drawing RED......
    ");
            fill_color16((short *)fbp, RED, pix_size);
            //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
            sleep(3);
        }
    #if 1
        /*这是你想画的点的位置坐标,(0,0)点在屏幕左上角*/    
        x = 10;  
        y = 10;  
        location = x * (vinfo.bits_per_pixel / 8) + y  *  finfo.line_length;  
        test_fbp = fbp + location;
        printf("draw line.......
    ");
        for(i = 0; i < (vinfo.xres - x); i++)
            *test_fbp++ = i+30;
    
        //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
    #endif
    
        munmap(fbp, screensize); /*解除映射*/  
    
        close (fp);
        return 0;
    }  

    当然用read()/write(), 也可以, 就是效率非常低, 太多系统调用导致系统在用户态和kernel态切换, 而且每次还传输一个字节, 但作为例子可以参考一下:

    #include <unistd.h>  
    #include <stdio.h>  
    #include <fcntl.h>  
    #include <linux/fb.h>  
    #include <sys/mman.h>  
    #include <stdlib.h>  
    #include <string.h>
    
    #define RED    0xF800
    #define YELLOW    0xFFE0
    #define BLUE     0x001F
    #define WHITE    0xFFFF 
    #define BLACK    0x0000
    
    
    
    int main ()   
    {  
        int fp=0;  
        struct fb_var_screeninfo vinfo;  
        int i;
        int pix_size=0;
        unsigned char color1, color2;
    
        fp = open("/dev/graphics/fb0", O_RDWR);  
    
        if(fp < 0) {  
            printf("Error : Can not open framebuffer device/n");  
            exit(1);  
        }  
    
        if(ioctl(fp, FBIOGET_VSCREENINFO, &vinfo)){  
            printf("Error reading variable information/n");  
            exit(3);  
        }  
    
    
        pix_size = vinfo.xres * vinfo.yres;
        color1 = 0;
        color2 = 0xf8;
        for(i=0; i<pix_size; i++) {
            write(fp, &color1, 1);
            write(fp, &color2, 1);        
        }
    
        close (fp);
        return 0;
    }  
  • 相关阅读:
    PHP数字补零的两种方法
    php 防跨站表单提交
    PHP字符串压缩
    原生JS实现表单序列化serialize()
    java并发实现原子操作
    Effective java -- 9 并发/序列化
    Effective java -- 8 异常
    Effective java -- 7 通用程序设计
    Effective java -- 6 方法
    Effective java -- 5 枚举和注解
  • 原文地址:https://www.cnblogs.com/vedic/p/10705191.html
Copyright © 2011-2022 走看看