APP下载

基于FrameBuffer的嵌入式系统LCD图像显示的实现

2017-05-08孙静

智能计算机与应用 2016年6期

孙静

摘要:本文以OMAP3530为处理器,S3C2410 LCD控制器为基础,基于嵌入式Linux 2.6内核,研究了FrameBuffer机制下的LCD驱动程序,介绍了相关的数据结构,FrameBuffer的加载和卸载的完整过程。实现了在LCD上显示字符、图形、图像的应用。

关键词: 帧缓冲; LCD; 图像显示

中图分类号: TP311

文献标志码: A

文章编号: 2095-2163(2016)06-0127-03

0引言

随着嵌入式技术的发展,显示模块在嵌入式产品中得到了日趋广泛的设计应用。LCD可显示字符、汉字和图形,具有低功耗、体积小、绿色环保等特点,因而在嵌入式产品的显示系统上已然成为重点优先研究首选。LCD的驱动程序针对不同的处理器通用性较差,本文为此研讨提出了一种移植性较好的LCD驱动程序,即基于Linux的FrameBuffer机制,同时采用S3C2410 LCD控制器,进而开发生成了嵌入式LCD的字符、图形、图像显示方法。

[BT4]1基于FrameBuffer的驱动设计

[BT5]1.1FrameBuffer机制

FrameBuffer是Linux操作系统为显示设备提供的一种驱动程序接口,可将显示缓冲区实现抽象处理,屏蔽图像硬件的底层,上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心显示缓冲区的具体物理位置、存放方式。FrameBuffer的显示缓冲区位于Linux核心态地址空间,每个应用程序均有自己的虚拟地址空间。用户通过调用mmap函数,可将文件的内容映射到应用空间。对于FrameBuffer设备而言,通过映射操作,可将屏幕缓冲区的物理地址应用到程序空间的一段虚拟地址中,然后通过读写对应段虚拟地址而访问屏幕缓冲区,从而在屏幕上绘制各种图形、图像、文字等。FrameBuffer的优点是可高度灵活地支持不同的硬件,减少了新处理器的开发工作。

[BT5]1.2基于FrameBuffer的驱动设计

FrameBuffer帧缓冲设备给用户设计指定的读写接口file_operations实际由fbmem.c文件里的特定file_operatins结构对象来展现提供,而特定帧缓冲设备fb_info结构体的注册、注销及其中成员的维护,尤其是fb_ops中的成员函数的实现则由对应的xxxfb.c文件来构造调取显示,fb_ops中的成员函数最终会操作LCD控制器的寄存器。图1即给出了帧缓冲设备驱动的程序结构。

1.2.1FrameBuffer相关的数据结构

本节,将研究给出与帧缓冲相关的数据结构的功能设计概述如下:

1)fb_info。记录了FrameBuffer的全部信息,包括设备的定制参数、状态以及操作函数指针。每一个帧缓冲设备必须对应唯一fb_info。

2)fb_ops。fb_info的成员变量fb_ops即为指向底层操作的函数的指针,这些函数是需要驱动程序开发人员来制定编写的。包括打开、释放函数,用于检查可以修改的屏幕参数并调整到适当值,同时设置color寄存器,使用户设置的屏幕参数在硬件上能够呈现事实有效等具体功能的分配操作。

3)fb_var_screeninfo和fb_fix_screeninfo。这2个结构体也是fb_info的成员。其中,fb_var_screeninfo记录用户可修改的显示控制器参数,包括屏幕分辨率和每个像素点的比特数。fb_fix_screeninfo记录用户不能修改的显示控制器的参数,如屏幕缓冲区的物理地址、长度。当对帧缓冲设备展开执行映射操作的时候,就是从fb_fix_screeninfo中取得缓冲区物理地址的。

4)fb_bitfield。描述每一像素显示缓冲区的组织方式,包括位域偏移、位域长度和MSB指示。

5)fb_cmap。记录设备无关的颜色表信息。

1.2.2FrameBuffer设备驱动的模块加载和卸载

FrameBuffer设备驱动的模块加载,可解析描述为如下4个步骤:

1)申请fb_info结构体的内存空间,初始化fb_info结构体中固定和可变的屏幕参数,即填充fb_info的fb_var_screeninfo var和fb_fix_screeninfo fix成员。

2)根据LCD屏幕的特点,执行LCD控制器硬件的初始化。

3)申请FrameBuffer设备的显示缓冲区空间。

4)注册FrameBuffer设备。

FrameBuffer设备驱动的模块卸载,则需依次释放fb_info结构体内存、关闭LCD、释放显示缓冲区以及注销FrameBuffer设备的流程也将移交到平台驱动的移除函数中顺序操控完成。

[BT4]2基于FrameBuffer的LCD图像显示的实现

在LCD上显示图像的主流程如图2所示。首先调用open函数打开设备,然后调用ioctl获取设备相关信息,接下来就是读取图形文件数据,把图像的RGB值映射到显存中,这部分也是图像显示的设计核心。

[BT5]2.1LCD刷新函数

本系统采用RGB565模式,即Red占5位(bit[11:15]),Green占6位(bit[5:10]),Blue占5位(bit[0:4])。LCD刷新函數的功能是把二级缓存LCDBuffer的数据由32位彩色图形信息转换成16位图形信息,而后存送至fbp指向的一级缓存。转换方法如下:

pixcolor = ((pbuf[0]&0xf8)>>3)|(((pbuf[1]&0xfc)>>2)<<5)|(((pbuf[2]&0xf8)>>3)<<11);

[BT5]2.2显示像素点

LCD上显示图像的基础设计操作即是显示像素点,基于FrameBuffer显示像素点就是把屏幕对应坐标位置的颜色值赋值到LCDFRAMEBUFFER数组里。本系统使用的是640×480 TFT液晶屏,通过如下方法可处理实现像素点的最终显示,关键代码如下:

typedef unsigned long tOff;

void LCD_WRITE_MEM( U32 off,U16 Data)

{

(* ((U16*)LCDFRAMEBUFFER + (off)) ) = Data;

}static void SetPixel(U16 x, U16 y, U32 c)

{

tOff Off = (tOff)((tOff)y*(tOff)640 + (x));

LCD_WRITE_MEM(Off, Data);

}

[BT5]2.3基本图形绘制

得到了像素点的研究显示,就可以在LCD上绘制基本图形了。其中,水平线和垂直线是原始功能线型。本次研究指出,水平线的绘制就是保持点的纵坐标不变,横坐标从x0变化到x1,依次显示像素点,这样就得到一条从(x0,y0)到(x1,y0)的水平线。同样道理,横坐标不变,纵坐标从y0变化到y1,依次显示像素点,即可得到一条从(x0,y0)到(x0,y1)的垂直线。在此基础上,矩形的绘制是给出矩形的左上角坐标和右下角坐标,而后根据这2个坐标在矩形范围内画线即可得到实现。

由于嵌入式系统不能处理浮点数,在LCD屏上显示圆形则较复杂。本系统采用改进的Bresenham画圆算法,分别给出了空心圆和实心圆的绘制方法,空心圆程序设计流程如图3所示。实心圆就是把空心圆内的像素点显示出来。

.4汉字及BMP位图图像显示方法

汉字是以点阵字模形式存储的,采用16×16点阵(32字节)、24×24点阵(72字节),每个点用一个二进制位表示,将其在屏幕上显示出来,就是研究指定刻画的汉字。

BMP位图文件和大多数图形文件一样,分为文件描述区(头文件信息)和图像存储区(像素数据)两部分。图像的显示方法和汉字类似,区别之处只是需要从位图文件里读出头文件信息,BMP位图LCD显示的程序流程如图4所示。

3结束语

基于Linux的FrameBuffer和OMAP3530处理器的开发平台,在LCD上显示实现了清晰、稳定的图形、字符和图像。该方法移植修改简单、方便,为嵌入式产品的显示系统构建了具体模式设计基础,对嵌入式LCD的应用提供了通用的实现方法。

参考文献:[HT]

张策, 杨绪剑, 王君君. 基于 FrameBuffer 的 LCD 驱动设计[J]. 计算机工程与设计,2009,30 (23):5372-5375.

[2] 葛化敏,郑静,杨利青. 基于ARM-Linux的LCD显示模块设计[J]. 仪表技术与传感器,2009(7):75-77,86.

[3] 王海霞,武一. 基于SOPC的LCD显示模块的设计与实现[J]. 液晶与显示,2012,27(4):508-514.

[4] 馬舜峰,金龙旭,安少婷,等. 一种基于ARM9的彩色TFT-LCD模块设计及实现, 液晶与显示,2010,25(5):718-723.