• ARM--FreamBuffer显示操作


    图像基本知识:

    即像素点的数量,由行与列数据,通常有1024*768,800*600等等

    像素色彩格式(颜色深度): 像素彩色格式即:每一个像素点颜色的组成模式。

    RGB888 由红绿蓝三原色组成,每一个像素占24位,即3个字节。红、绿、蓝分别占8位。

    RGB565 (天嵌开发板LCD所支持的格式) 由红绿蓝三原色组成,每一个像素占16位,红占5位, 绿占6位,蓝占5位。

    计算一屏幕占用的显存大小:

    公式:长 * 宽 * 像素大小 / 8 = 屏幕大小(Byte)。

    即公 式:分辨度 * 像素大小 / 8 = 屏幕大小(Byte)。

    freambuffer 结构:

    framebuffer就相当于一个中间层,对驱动和硬件进行一个封装和管理,便于用户开发图形界面或进行视频输出操作。

    framebuffer本身不具备任何运算数据的能力,就只好比是一个画布,CPU将运算后的结果放到这个画布中,而这个画

    布就是显示器的投影。画布里面的内容直接显示到显示器上。

    FreamBuffer显示操作流程:

    1. 打开显示设备
    2. 获取freambuffer有关的固定信息(可省略)
    3. 获取freambuffer有关的可变信息
    4. 将可变信息放入FB_INFO_S 类型的结构体g_fb中 ,FB_INFO_S 为自定义的结构体:

    typedef struct _fb_info
    {
    int fd; // 显示设备文件描述符(句柄)
    char *memp; // 内存映射地址
    int screensize ; // 一屏(一桢)占用的内存大小
    unsigned int width; // 宽 每一行的像素个数
    unsigned int height; // 高 每一列的像素个数
    unsigned int stride; // 跨度 每一行的占用的字节数
    unsigned int depth; // 每个像素的大小
    }FB_INFO_S;

      5.进行内存映射 

    显存处于驱动中(内核中),用户无法直接操作驱动中的内存,
    因此需要做内存映射操作,即将内核态的内存映射到用户态中

         6.解除内存映射

      7.关闭显示设备

    下为一示例代码:

      1 /****************************************************
      2 程序作用:framebuffer 显示操作----->进度条
      3 备注:图像基本知识
      4       公式:长 * 宽 * 像素大小  / 8 = 屏幕大小(Byte)。
      5   6 *****************************************************/
      7 //头文件
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 #include <string.h>
     11 #include <fcntl.h>            //文件控制头文件
     12 #include <sys/types.h>        
     13 #include <sys/mman.h>        //内存映射头文件
     14 #include <linux/fb.h>        //framebuffer头文件
     15 
     16 //自定义的结构体: 用于存放设备信息
     17 
     18 typedef struct _fb_info 
     19 {
     20     int fd;            // 显示设备文件描述符(句柄)
     21     char *memp;            // 内存映射地址
     22     int screensize ;        // 一屏(一桢)占用的内存大小
     23     unsigned int width;      // 宽     每一行的像素个数
     24     unsigned int height;    // 高     每一列的像素个数
     25     unsigned int stride;    // 跨度  每一行的占用的字节数
     26     unsigned int depth;        // 每个像素的大小
     27 }FB_INFO_S;
     28 FB_INFO_S g_fb = {-1, NULL, 0, 0, 0, 0};
     29 /***************************************************
     30 函数名  : fb_clear()
     31 函数功能: 将屏幕全部填充为白色
     32 输入    : 无
     33 输出    : 无
     34 备注    :
     35 ****************************************************/
     36 int fb_clear()
     37 {       
     38     memset(g_fb.memp, 0xffff, g_fb.screensize);    //       
     39     return 0;
     40 }
     41 /***************************************************
     42 函数名  : fb_pixel()
     43 函数功能: 在屏幕坐标为(x,y)处画深度为depth的点
     44 输入    : x:横坐标 y:纵坐标  color:像素深度
     45 输出    : 成功输出 0  失败数次-1
     46 备注    :
     47 ****************************************************/
     48 int fb_pixel(int x, int y, unsigned short color)
     49 {
     50        if ((x > g_fb.width) || (y > g_fb.height))
     51               return (-1);
     52 
     53        unsigned short *dst = ((unsigned short *) g_fb.memp + (y-1) * g_fb.width + x);
     54        *dst = color;
     55        return 0;
     56 }
     57 
     58 int main()
     59 {
     60     //打开显示设备
     61     g_fb.fd = open("/dev/fb0",O_RDWR); 
     62     if (g_fb.fd < 0)
     63         return -1;
     64     //获取freambuffer有关的固定信息(可省略)
     65     struct fb_fix_screeninfo finfo;
     66     if (ioctl(g_fb.fd, FBIOGET_FSCREENINFO, &finfo) < 0) 
     67     {
     68         perror("get fix screeninfo failed");
     69         return -1;          
     70     }
     71     //获取freambuffer有关的可变信息
     72     struct fb_var_screeninfo vinfo;
     73     if (ioctl(g_fb.fd, FBIOGET_VSCREENINFO, &vinfo) < 0) 
     74     {
     75           perror("get variable screen info failed");
     76           return -1;
     77     }
     78     //将可变信息放入FB_INFO_S g_fb中
     79     g_fb.width = vinfo.xres;             //
     80     g_fb.height = vinfo.yres;             //
     81     g_fb.depth = vinfo.bits_per_pixel;         //每个像素的大小 
     82     g_fb.stride = g_fb.width * vinfo.bits_per_pixel; 
     83     g_fb.screensize = g_fb.width * g_fb.height * g_fb.depth / 8; // 屏幕字节大小 
     84     //进行内存映射:
     85     /********************************************************
     86     显存处于驱动中(内核中),用户无法直接操作驱动中的内存,
     87     因此需要做内存映射操作,即将内核态的内存映射到用户态中
     88     *********************************************************/
     89     g_fb.memp = (char*)mmap(0,g_fb.screensize,PROT_READ|PROT_WRITE,MAP_SHARED, g_fb.fd, 0);
     90     if (MAP_FAILED == g_fb.memp ) 
     91     {                
     92         printf("map failed 
    ");                
     93         return -1;        
     94     }
     95     /**********************进度条******************/
     96     int x = 0 ,y ;
     97     for(;x<x+100;x++)
     98     {
     99         usleep(10000);
    100         for(y=124;y<148;y++)
    101         {
    102             fb_pixel(x, y, 0x1f);    
    103         }
    104         if(x == g_fb.width)
    105             break;
    106     }
    107     fb_clear();
    108     // 解除内存映射
    109     munmap(g_fb.memp,  g_fb.screensize);
    110     // 关闭显示设备    
    111     close(g_fb.fd);                
    112 }

     

  • 相关阅读:
    垂直的SeekBar:VerticalSeekBar
    android 获取路径目录方法以及判断目录是否存在,创建目录
    JSON
    列表和导航
    【前端积累】链接
    【前端积累】背景图像和背景替换
    【前段积累】可视化模型
    【前端积累】选择器
    银联支付-产品测试sdk使用流程
    【CSS系列】块级元素和行内元素
  • 原文地址:https://www.cnblogs.com/be-m/p/FreamBuffer.html
Copyright © 2020-2023  润新知