• linux驱动之framebuffer


    第一部分   framebuffer 概念介绍

    1、framebuffer帧缓冲

      帧缓冲(framebuffer)是Linux系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都是由帧缓冲设备驱动本身来完成。

      framebuffer机制模仿显卡的功能,将显卡硬件结构抽象为一系列的数据结构,可以通过对framebuffer的读写直接对显存进行操作。用户可以将framebuffer看成是显卡的一个映像,将其映射到进程空间后,就可以直接读写操作,写操作会直接反映在屏幕上。

      framebuffer是一个字符设备,主设备号是29,对应于/dev/fb%d设备文件。通常,使用如下方式(数字代表次设备号)

      0 =  /dev/fb0  第一个fb设备

      1 =  /dev/fb1  第二个fb设备

      fb也是一种普通的内存设备,可以读写其内容。例如,屏幕抓屏:cp /dev/fb0 myfilefb   虽然可以向内存设备(/dev/mem)一样,对其read、write、seek以及mmap。但区别在于fb使用的不是整个内存区。而是显存部分。

    2、fb与应用程序的互交

      对于应用程序而言,它和其它的设备并没有什么区别,用户可以把fb看成是一块内存,既可以向内存中写数据,也可以读数据。fb的显示缓冲区位于内核空间。应用程序可以把此空间映射到自己的用户空间,再进行操作。

      在应用程序中,操作/dev/fbn的一般步骤如下:

      (1)打开/dev/fbn设备文件。

      (2)用ioctl()操作取得当前显示屏幕的参数,如屏幕的分辨率、每个像素点的比特数。根据屏幕的参数可计算屏幕缓冲区的大小。

      (3)用mmap()函数,将屏幕缓冲区映射到用户空间。

      (4)映射后就可以直接读/写屏幕缓冲区,进行绘图和图片显示。

    第二部分  framebuffer数据结构分析 

         

      

       framebuffer涉及的数据结构如下:

      (1)struct  fb_info 

       一个帧缓冲区对应一个struct fb_info结构,它包括了帧缓冲设备的属性和操作的完整集合,每个帧设备都有一个fb_info结构体。

      (2)struct  fb_ops

        结构体用来实现对帧缓冲设备的操作,这些函数需要驱动开发人员编写,

      (3)struct  fb_fix_screeninfo

          该结构体记录了用户不能修改的固定显示控制器参数。这些固定的参数如缓冲区的物理地址、缓冲区的长度等等。

      (4)struct  fb_var_screeninfo

        结构体中存储了用户可以修改的显示器控制参数,例如屏幕分辨率、透明度等等。

      (5)struct  fb_cmap

        结构体中记录了颜色板信息,即调色板信息。,用户空间可以通过ioctl()的FBIOGETCMAP和 FBIOPUTCMAP命令读取或设定颜色表。
      

      以上结构体的关系如下:

    (6)struct fb_bitfield

      结构体描述每一像素显示缓冲区的组织方式,包含位域偏移、位域长度和MSB 指示。

    第三部分 framebuffer核心层框架分析

      framebuffer设备在Linux中是以平台设备形式存在的,fb设备驱动核心层为上层提供了系统调用,为底层驱动提供了接口,核心层的主文件及其功能如下。
      (1)drivers/video/fbmem.c。主要任务:1、创建graphics类、注册FB的字符设备驱动、提供register_framebuffer接口给具体framebuffer驱动编写着来注册fb设备的。本文件相对于fb来说,地位和作用和misc.c文件相对于杂散类设备来说一样的,结构和分析方法也是类似的。
      (2)drivers/video/fbsys.c。这个文件是处理fb在/sys目录下的一些属性文件的。
      (3)drivers/video/modedb.c。这个文件是管理显示模式(譬如VGA、720P等就是显示模式)的
      (4)drivers/video/fb_notify.c

     

      fbmem_init函数
      (1)#ifdef MODULE
      (2)fb_proc_fops和fb在proc文件系统中的表现
      (3)register_chrdev注册fb设备
      (4)class_create创建graphics类
      (5)fbmem_exit的对应
      fb_fops
      (1)为应用层实现read/write/mmap/ioctl在驱动层的接口
      (2)registered_fb和num_registered_fb
      (3)struct fb_info  register_framebuffer函数

      (1)fb驱动框架开放给驱动编写着的注册接口
      (2)fb_check_foreignness
      (3)remove_conflicting_framebuffers
      (4)device_create
      (5)fb_init_device

      fb在sysfs中的接口
      (1)device_attrs
      (2)dev_set_drvdata和dev_get_drvdata

      注册登记该fb设备
      (1)registered_fb[i] = fb_info;
      (2)结合fb_read等函数中对fb_info的使用
      (3)关键点:数据如何封装、数据由谁准备由谁消费、数据如何传递

    第四部分 framebuffer驱动层分析

      驱动层涉及源码文件:

      (1)drivers/video/samsung/s3cfb.c,驱动主体,主要是处理和数据结构有关的
      (2)drivers/video/samsung/s3cfb_fimd6x.c,里面有很多LCD硬件操作的函数,主要是处理和硬件有关的
      (2)arch/arm/mach-s5pv210/mach-x210.c,负责提供platform_device的
      (3)arch/arm/plat-s5p/devs.c,为platform_device提供一些硬件描述信息

      s3cfb.c文件probe函数分析

      (1)struct s3c_platform_fb *pdata;

      struct s3c_platform_fb 这个结构体是fb的platform_data结构体,这个结构体变量就是platform设备的私有数据,这个数据在platform_device.device.platform_data中存储。在mach文件中去准备并填充这些数据,在probe函数中通过传参的platform_device指针取出来。

      (2)struct s3cfb_global 这个结构体主要作用是在驱动部分的2个文件(s3cfb.c和s3cfb_fimd6x.c)的函数中做数据传递用的。
      (3)struct resource
      (4)regulator

       

      mach-x210.c文件分析

      smdkc110_machine_init函数里面主要是做了一些该平台下数据的初始化,里面涉及fb的由两个部分,如下:

      (1)platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));  //存放平台数据

            smdkc110_devices

              s3c_device_fb

      (2)s3cfb_set_platdata(&ek070tn93_fb_data);  //主要是用于提供设置GPIO的函数

    第五部分 修改内核logo

      1、找一个需要显示的logo的png格式的图片(图片分辨率不得大于屏幕分辨率),并将其命令为logo.png

      2、在终端下执行以下命令

        pngtopnm logo.png | ppmquant -fs 224 | pnmtoplainpnm > logo_linux_clut224.ppm

      3、将生成的ppm文件拷贝到替换掉/root/porting_x210/kernel/x210kernel/drivers/video/logo/目录下

        并将其改名为logo_x210_clut224.ppm

      4、make

     备注:

     (1)修改fbmem.c的471行可以修改Logo显示的位置,例如,显示在屏幕中间:

        image.dx = (info->var.xres - logo->width)/2;
        image.dy = (info->var.yres - logo->height)/2;

     (2)如果图片显示不出来可能有以下原因

        a、内核里framebuffer的分辨率不对,可以在mach-x210.c的225行修改(1024 * 600);

        b、只能在左上角显示,CONFIG_FRAMEBUFFER_CONSOLE宏可能被选中(该宏不需要勾选,可以现在.config里面查看,确定后,make menuconfig 去除)

  • 相关阅读:
    简单拓扑排序
    Havel-Hakimi定理
    阿里云宁磊:能力中心开启,携手伙伴共享共赢
    阿里云高磊:API网关加速能力聚合与生态集成
    阿里云智能推荐AIRec产品介绍
    OpenSearch最新功能介绍
    30分钟全方位了解阿里云Elasticsearch
    研发效能提升 36 计第三课:束水攻沙,持续加快产品交付速度
    SaaS上云工具包为企业应用构筑上云之梯
    阿里云资深技术专家黄省江:让天下没有难做的SaaS
  • 原文地址:https://www.cnblogs.com/gzqblogs/p/10105804.html
Copyright © 2020-2023  润新知