fl2440——LCD应用程序测试及笔记

前面介绍了对开发板LCD的驱动使能,本次是在LCD的驱动基础上做一些应用程序的测试
(因为Linux中有屏幕保护,长时间不对LCD屏幕进行操作,它就会自动灭掉,有时候调试比较麻烦,可以在 vi /drivers/tty/vt/vt.c文件中作如下图修改)

在网上找到了一些测试代码略做修改
*********************************************************************************
*      Copyright:  (C) 2018 anzhihong< [email protected] >
*                  All rights reserved.
*
*       Filename:  lcd1.c
*    Description:  This file
*                 
*        Version:  1.0.0(03/31/2018)
*         Author:  anzhihong < [email protected] >
*      ChangeLog:  1, Release initial version on "03/31/2018 10:27:45 PM"
*                 
********************************************************************************/
/*调用内核里面的一些头文件*/
#include <unistd.h>                                           
#include <stdio.h>
#include <fcntl.h> 
#include <linux/fb.h> //fb.h文件中定义了一些主要的数据结构:struct fb_fix_screeninfo(定义显卡信息,如framebuffer内存的起始地址,地址长度等)、struct fb_var_screeninfo(描述了显卡显示的信息,如宽、高、颜色深度等,不同的显示模式对应不同的信息)、struct fb_info(包含显卡的状态信息,只对内核可见)、 struct fb_cmap(用来定义帧缓冲区设备的颜色表(colormap)信息,可通过ioctl()函数的FBIOGETCMAP和FBIOPUTCMAP命令设置colormap)、 struct fb_ops(应用程序使用这些函数操作底层的LCD硬件,fp_ops结构中定义的方法用于支持这些操作。这些操作需要驱动开发人员来做)

#include <sys/mman.h>


#define FB_DEVICE_NAME "/dev/fb0"               


#define RED_COLOR565            0X0F100  
#define GREEN_COLOR565       0X007E0  
#define BLUE_COLOR565          0X0001F  
#define White_COLOR565        0xFFFFF       
#define BLACK_COLOR             0x0

//延时程序
void delay(int a)
{
    int k;
    for(k=0;k<a;k++)
    ;
}

typedef struct fb_dev   {
        int fd;                                                /*  帧缓冲设备硬件描述符 */
        void *pfb;                                        /*  指向帧缓冲映射到用户空间的首地址 */
        int xres;                                          /*  一帧图像的宽度 */
        int yres;                                         /*  一帧图像的高度 */
        int size;                                          /*  一帧图像的大小 */
        int bits_per_pixel;                          /*  每个像素的大小 */
} fb_dev_t;
int fb_open(fb_dev_t *fbd, char *fbn)      //打开操作(由于帧缓冲是字符设备,应用程序需按文件打开一个帧缓冲设备。打开成功则可以对帧缓冲设备进行读、写等操作
{
    struct fb_var_screeninfo vinfo;                    // struct  fb_info结构体的成员)当前缓冲区的可变参数,也就是当前的视屏信息
     if((fbd->fd = open(fbn, O_RDWR)) == -1)      //判断是否打开framebuffer
     {
         printf("Error: Cannot open framebuffer device.\n");
         exit(1);
     }
     ioctl(fbd->fd, FBIOGET_VSCREENINFO, &vinfo);    //ioctl()函数可读取/设置显示设备以及屏幕的参数。如分辨率、显示颜色、屏幕大小等。ioctl()函数是由底层的驱动程序完成的。
     fbd->xres = vinfo.xres;                 //屏幕x轴
     fbd->yres = vinfo.yres;                //屏幕y轴  
     fbd->bits_per_pixel = vinfo.bits_per_pixel;    //每个像素点占用多少个字节。

     fbd->size = fbd->xres * fbd->yres * fbd->bits_per_pixel / /计算一帧图像的大小
     printf("%d * %d,%d bits_per_pixel,screensize = %d.\n",fbd->xres,fbd->yres,fbd->bits_per_pixel,fbd->size);

     fbd->pfb = mmap(NULL, fbd->size, PROT_READ | PROT_WRITE, MAP_SHARED, fbd->fd, 0); //mmap函数执行帧缓冲设备具体的内存映射。将文件内容映射到一段内存中,准确的说是虚拟内存,通过对内存的读取和修改。 

     if((int)fbd->pfb == -1)    //判断是否映射成功,失败打印错误信息。
     {
         printf("Error: Failed to map frambuffer device to memory!\n");  
         exit(2);
     }
      return 0;
}

int fb_close(fb_dev_t *fbd)     //关闭设备文件
{
    munmap(fbd->pfb,fbd->size);  //解除映射

    close(fbd->fd);
}

int fb_drawrect(fb_dev_t *fbd, int x0, int y0, int w, int h, int color)  //画图像到屏幕上。
{
     int x,y;

     for(y=y0; y<y0+h; y++)
     {
         for(x=x0; x<x0+w; x++)
         {
             *((short *)(fbd->pfb) + y*fbd->xres +x) = color;   //计算一个像素的位置
         }
     }
     return 0;
}

int main(int argc, char **argv)
{
    fb_dev_t *fbd;

    fbd = (fb_dev_t *)malloc(sizeof(fb_dev_t));      //为设备文件分配内存

    fb_open(fbd, FB_DEVICE_NAME);      // 打开帧缓冲设备文件(帧缓冲设备对应的设备文件为/dev/fb*)这里应该加一句,判断一下打开帧缓冲设备是否成功。

    if(fbd->bits_per_pixel == 16)    
    {
        /*while(fbd->bits_per_pixel == 16)*/
         {
            printf("Red/Green/Blue Screen!\n");     // 输出屏幕将要显示的颜色

            fb_drawrect(fbd, 0, 0, fbd->xres, fbd->yres/4, RED_COLOR565);    //屏幕颜色显示,将屏幕分割为4个
            fb_drawrect(fbd, 0, fbd->yres/4, fbd->xres, fbd->yres/4,    White_COLOR565);

            fb_drawrect(fbd, 0, fbd->yres*2/4, fbd->xres, fbd->yres/4,  BLUE_COLOR565);

            fb_drawrect(fbd, 0, fbd->yres*3/4, fbd->xres, fbd->yres/4,  BLACK_COLOR);
         }
     }
     else
         printf("16 bits only!");

     fb_close(fbd);
     return 0;
}
开发板运行结果如下:

FrameBuffer概述:
FrameBuffer是Linux为显示设备提供的接口,是显示缓冲区抽象,用来表示显示缓冲区的数据结构,屏蔽图像硬件的差异,可使应用程序在图形模式下直接对缓冲区操作。
FrameBuffer是标准的字符设备:
FrameBuffer的主设备号是29,其次设备号根据帧缓冲区数目而定。
FrameBuffer与应用程序的交互:
在Linux中,FrameBuffer是一种能够提取图形的硬件设备,是用户进入图形界面的很好接口,它是显存抽象后的一种设备,它允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作,这种操作是抽象的、统一的。

FrameBuffer显示原理
通过 FrameBuffer,应用程序用mmap()把显存映射到应用程序虚拟地址空间,应用程序只需将要显示的数据写入这个内存空间,然后LCD控制器会自动地将这个内存空间(显存)中的数据显示在LCD屏幕上。
FrameBuffer的结构分析:
在linux中,FrameBuffer设备驱动源码主要在linux-3.0/ include/linux/fb.h (我自己的路颈)和linux-3.0/ drivers/video/fbmem.c这两个文件中,它们处于FrameBuffer驱动体系结构的中间层——为上层的用户程序提供系统调用,也为底层特定硬件驱动提供了接口。
linux-3.0/include/linux/fb.h几个重要的数据结构2018/4/3 16:54
  • struct fb_cmap结构体:用来定义帧缓冲区设备的颜色表(colormap)信息,可以通过ioctl()函数的FBIOGETCMAP和FBIOPUTCMAP命令设置colormap。
  • struct fb_info结构体:包含当前显卡的状态信息,struct fb_info结构体只对内核可见。
  • struct fb_ops结构体:应用程序使用这些函数操作底层的LCD硬件,fb_ops结构中定义的方法用于支持这些操作。这些操作需要驱动开发人员来实现。
  • struct fb_fix_screeninfo结构体:定义了显卡信息,如framebuffer内存的起始地址,地址长度等。
  • struct fb_var_screeninfo结构体:描述了一种显卡模式的所有信息,如宽、高、颜色深度等。不同模式对应不同的信息。
在framebuffer中,这些结构体是互相关联,互相配合使用的。只有每一个结构体起到自己的作用,才能使整个framebuffer设备驱动程序正常工作。这几个结构体之间的关系如下:

fb_ops结构体


猜你喜欢

转载自blog.csdn.net/buhuiguowang/article/details/79821130