作者: 刘鹏
日期: 2008-12-27
本文分析了frame buffer 设备驱动的主要数据结构,在此基础上介绍了LCD驱动程序的开发。

基本原理

  • 通过 framebuffer ,应用程序用 mmap 把显存映射到应用程序虚拟地址空间,将要显示的数据写入这个内存空间就可以在屏幕上显示出来;
  • 驱动程序分配系统内存作为显存;实现 file_operations 结构中的接口,为应用程序服务;实现 fb_ops 结构中的接口,控制和操作 LDC 控制器;
  • 驱动程序将显存的起始地址和长度传给 LCD 控制器的寄存器 (一般由 fb_set_var 完成) , LDC 控制器会自动的将显存中的数据显示在 LCD 屏上。

写 framebuffer 驱动程序要做什么

  • 简单的讲,framebuffer 驱动的功能就是分配一块内存作显存,然后对 LCD 控制器的寄存器作一些设置。
  • 具体来说:
    1. 填充一个 fbinfo 结构
    2. 用 reigster_framebuffer (fbinfo*) 将 fbinfo 结构注册到内核
  • 对于 fbinfo 结构,最主要的是它的 fs_ops 成员,需要针对具体设备实现 fs_ops 中的接口
  • 考虑是否使用中断处理
  • 考虑内存访问方式
    1. 显卡不自带显存的,分配系统内存作为显存
    2. 显卡自带显存的,用 I/O 内存接口进行访问 (request_mem_region / ioremap),
  • 关于如何写驱动的参考资料,在网站 http: /linux-fbdev.sourceforge.net/HOWTO/index.html 可以找到 "Linux Frame buffer Driver Writing HOWTO"

LCD 模块 / 驱动程序 / 控制器

关于LCD 设备资料可参考如下资料:

  • Datasheet of LCD device
  • 书:液晶显示技术
  • 书:液晶显示器件

什么是 frame buffer 设备

frame buffer 设备是图形硬件的抽象,它代表了图形硬件的侦缓冲区,允许应用程序通过指定的接口访问图形硬件。因此,应用程序不必关心底层硬件细节。

设备通过特定的设备节点访问,通常在 /dev 目录下,如 /dev/fb*。

更多关于 frame buffer device 的资料可以在以下两个文件中找到: linux /Documentation/fb/framebuffer.txt 和 linux /Documentation/fb /interal.txt,但这些资料内容不多,还需要看看结合代码具体分析。

Linux Frame Buffer 驱动程序层次结构

Frame Buffer 设备驱动可以从三个层次来看:

  1. 应用程序与系统调用;
  2. 适用于所有设备的通用代码,避免重复,包括 file_operations 结构、register/unregister framebuffer 接口等;
  3. 操作具体硬件的代码,主要是 fs_ops 结构。

在 Linux 内核中,Frame Buffer 设备驱动的源码主要在以下两个文件中,它们处于 frame buffer 驱动体系结构的中间层,它为上层的用户程序提供系统调用,也为底层特定硬件驱动提供了接口:

  1. linux/inlcude/fb.h
  2. linux/drivers/video/fbmem.c
数据结构

头文件 fb.h 定义了所有的数据结构:

  • fb_var_screeninfo:描述了一种显卡显示模式的所有信息,如宽、高、颜色深度等,不同的显示模式对应不同的信息;
  • fb_fix_screeninfo:定义了显卡信息,如 framebuffer 内存的起始地址,地址长度等;
  • fb_cmap:设备独立的 colormap 信息,可以通过 ioctl 的 FBIOGETCMAP 和 FBIOPUTCMAP 命令设置 colormap;
  • fb_info:包含当前 video card 的状态信息,只有 fb_info 对内核可见;
  • fb_ops : 应用程序使用 ioctl 系统调用操作底层的 LCD 硬件,fb_ops 结构中定义的方法用于支持这些操作;
  • 这些结构相互之间的关系如下所示:

framebuffer 驱动主要数据结构
接口

fbmem.c 实现了所有驱动使用的通用代码,避免了重复。

全局变量:

     struct fb_info *registered_fb [FB_MAX]int num_registered_fb;

这个两个变量用于记录正在使用的 fb_info 结构实例。fb_info 代表 video card 的当前状态,所有的 fb_info 结构都放在数组中。当一个 frame buffer 在内核中登记时,一个新的 fb_info 结构被加入该数组,num_registered_fb 加 1。

fb_drivers 数组:

static struct {const char *name;int (*init)(void);int (*setup)(void);
} fb_drivers[] __initdata= { ....};

若 frame buffer 驱动程序是静态链接到内核中,一个新的 entry 必须要加到这个表中。 若该驱动程序是使用 insmod/rmmod 动态加载到内核,则不必关心这个结构。

static struct file_operations fb_ops ={owner: THIS_MODULE,read: fb_read,write: fb_write,ioctl: fb_ioctl,mmap: fb_mmap,open: fb_open,release: fb_release
};

这是用户应用程序的接口,fbmem.c 实现了这些函数。

register/unregister framebuffer:

 register_framebuffer(struct fb_info *fb_info)unregister_framebuffer(struct fb_info *fb_info)

这是底层 frame buffer 设备驱动程序的接口。驱动程序使用这对函数实现注册和撤销操作。底层驱动程序的工作基本上是填充 fb_info 结构,然后注册它。

一个 LCD controller 驱动程序

实现一个 LCD controller 驱动程序主要做如下两步:

  • 分配系统内存作显存
  • 根据具体的硬件特性,实现 fb_ops 的接口
  • 在 linux/drivers/fb/skeletonfb.c 中有一个 frame buffer 驱动程序的框架,它示例了怎样用很少的代码实现一个 frame buffer 驱动程序。
分配系统内存作为显存

由于大多数 LDC controller 没有自己的显存,需要分配一块系统内存作为显存。这块系统内存的起始地址和长度之后会被存放在 fb_fix_screeninfo 的 smem_start 和 smem_len 域中。该内存应该是物理上连续的。

对于带独立显存的显卡,使用 request_mem_region 和 ioremap 将显卡外设内存映射到处理器虚拟地址空间。

实现 fb_ops 结构

目前还没有讨论的 file_operations 方法是 ioctl ()。用户应用程序使用 ioctrl 系统调用操作 LCD 硬件。fb_ops 结构中定义的方法为这些操作提供支持。注意, fb_ops 结构不是 file_operations 结构。fb_ops 是底层操作的抽象,而 file_operations 为上层系统调用接口提供支持。

下面考虑需要实现哪些方法。ioctl 命令和 fb_ops 结构中的接口之间的关系如下所示:

    FBIOGET_VSCREENINFO fb_get_varFBIOPUT_VSCREENINFO fb_set_varFBIOGET_FSCREENINFO fb_get_fixFBIOPUTCMAP fb_set_cmapFBIOGETCMAP fb_get_cmapFBIOPAN_DISPLAY fb_pan_display

只要我们实现了那些 fb_XXX 函数,那么用户应用程序就可以使用 FBIOXXXX 宏来操作 LDC 硬件了。那怎么实现那些接口呢?可以参考下 linux/drivers/video 目录下的驱动程序。

在众多接口中, fb_set_var 是最重要的。它用于设置 video mode 等信息。下面是实现 fb_set_var 函数的通用步骤:

  1. 检查是否有必要设置 mode
  2. 设置 mode
  3. 设置 colormap
  4. 根据上面的设置重新配置 LCD controller 寄存器

其中第四步是底层硬件操作。

Reference

  • Writing Linux LCD drivers―深入分析framebuffer设备驱动的结构
  • Linux Frame Buffer Driver HOWTO
  • s3c2410_lcd frame buffer 驱动分析
  • Linux 2.6 Device Model
  • Linux 2.6 内核设备模型

怎样写 Linux LCD 驱动程序相关推荐

  1. Linux LCD驱动程序

    LCD操作原理 在Linux系统中通过Framebuffer(简称为fb,又叫显存)驱动程序来控制LCD. Frame是帧的意思,buffer是缓冲的意思,这意味着Framebuffer就是一块内存, ...

  2. Linux内核 LCD 驱动程序框架

    Linux 内核 LCD 驱动程序框架 1. framebuffer 简介 1.1 什么是 framebuffer 1.2 framebuffer的作用 2. framebuffer 驱动的框架 3. ...

  3. linux lcd驱动调试 echo dev/fb0,LCD驱动程序 - osc_msmij2gf的个人空间 - OSCHINA - 中文开源技术交流社区...

    LCD驱动程序 假设 app: open("/dev/fb0", ...) 主设备号: 29, 次设备号: 0 kernel: fb_open int fbidx = iminor ...

  4. Linux系统驱动之分析内核自带的LCD驱动程序_基于IMX6ULL

    百问网技术交流群,百万嵌入式工程师聚集地: https://www.100ask.net/page/2248041 资料下载 coding无法使用浏览器打开,必须用git工具下载: git clone ...

  5. 自己写Linux Usb鼠标驱动程序

    USB子系统相关内容参考<精通Linux设备驱动程序>第11章. USB鼠标驱动程序可以参考内核中的鼠标驱动,路径为linux-3.0.86\drivers\hid\usbhid\usbm ...

  6. Linux LCD 驱动实验

    目录 Linux 下LCD 驱动简析 1 Framebuffer 设备 LCD 驱动简析 硬件原理图分析 LCD 驱动程序编写 运行测试 LCD 屏幕基本测试 设置LCD 作为终端控制台 LCD 背光 ...

  7. arm裸机与嵌入式linux驱动开发,如何编写基于ARM的裸机程序和基于Linux的驱动程序?...

    在嵌入式开发中,ADC应用比较频繁,本文主要讲解ADC的基本原理以及如何编写基于ARM的裸机程序和基于Linux的驱动程序. ARM架构:Cortex-A9Linux内核:3.14 在讲述ADC之前, ...

  8. 七 linux LCD驱动代分析

    LCD驱动分析 原文地址: http://blog.csdn.net/woshidahuaidan2011/article/details/52054795 1.对LCD驱动添加设备信息 对lcd驱动 ...

  9. Linux LCD屏幕驱动调参实操

    Linux LCD屏幕驱动调参实操 初探 Linux下的 LCD 驱动文中提到过, IMX6ULL的 eLCDIF接口驱动程序已经有半导体厂家NXP编写好了,并且不同分辨率LCD屏的eLCDIF接口驱 ...

  10. 嵌入式驱动编写-LCD驱动程序

    如何来写LCD的驱动程序,首先 看芯片开发手册和原理图 根据原理图,找到s3c2440的GPIO控制管脚,gpb   gpc  gpd  gpg管脚控制 需要设置寄存器 以及设置LCD控制寄存器 查看 ...

最新文章

  1. MySQL InnoDB锁
  2. 64位jvm的指针膨胀 和 数据补白
  3. db2分页查询语句优化_面试官:数据量很大,分页查询很慢,怎么优化?
  4. jsp 跳到servlet路径_想打开一个jsp的页面就跳转到servlet中去,并向servlet传值。用什么跳转...
  5. python图形编程复选按钮和单选按钮详细说明_Python_tkinter_单选框(Radiobutton)与复选框(Checkbutton)...
  6. 新一代Notebook神器出现,Jupyter危险了!
  7. Python随机数生成方法
  8. ROS底盘控制节点 源码分析
  9. JQuery修改background-image背景图片
  10. Mysql学习总结(18)——Mysql主从架构的复制原理及配置详解
  11. congestion report解读
  12. 我在华为外包一年的经历分享。
  13. jersey restful 测试_Jersey实现Restful服务
  14. WINCE 矩阵键盘 介绍
  15. 试题 算法提高 字符串跳步
  16. vue在调用摄像头扫码(vue-qrcode-reader)
  17. 华为mate7android版本,华为Mate7升级安卓6.0(EMUI4.0)M版本详细图文教程
  18. ᑋᵉᑊᑊᵒ ᵕ̈ᰔᩚ
  19. 蓝桥杯 核桃的数量(python)
  20. python如何写生日快乐说说_抖音上很火的生日句子,适合过生日发的高逼格

热门文章

  1. 线性判别分析LDA解析2
  2. android studio for android learning (五) 最新Activity理解与其生命周期
  3. android studio for android learning (四) 兼容性问题
  4. mysql 存储过程 高并发_解决数据库高并发常见方案
  5. springboot(运行原理参考借鉴)
  6. [MySQL]触发器
  7. 【转】navicat远程连接mysql,2003 can't connect to mysql server on 10038
  8. struts2远程命令执行漏洞S2-045
  9. jQuery2.x源码解析(设计篇)
  10. PYTHON之路(九)