谢 聪
(武汉船舶通信研究所 武汉 430079)
通信显示终端是通信系统及设备的重要组成部分,通常具有一定的信息处理能力和对外通信网络接口,提供相关设备信息的显示功能以及人机交互功能。目前触屏显示设备主要基于X86系列处理器,其驱动及应用软件系统与PC系统类似具有良好的复用性只需部署即可使用,作为通信设备的显示终端为兼顾系统稳定性、低功耗、小型化等特性,为此需选用嵌入式处理器开发通信智能控制显示终端,来更好的满足上述要求,但在嵌入式终端设备的软件平台及系统应用方面没有成熟的商业化平台,因此,通用通信智能控制显示终端的软件系统开发是设备实现的关键,而底层的驱动开发及移植是实现的软件基础。本文主要就通信领域的智能控制显示终端的触屏显示设备的LCD原理及其驱动开发等方面进行了详细介绍,重点分析了终端设备显示控制器的寄存器设置以及控制器显示模块的驱动实现方法,结合选型的工业液晶屏时序要求在嵌入式系统上进行移植和测试验证,为实现具有自主可控的智能通信控制显示终端及平台提供基础支撑和技术保障。
TFT-LCD(薄膜晶体管液晶显示器),成为目前最为主流的液晶显示器类型,广泛应用于桌面显示器、笔记本电脑和众多嵌入式设备中。逻辑上显示屏所显示的一幅完整画面即一个帧(frame),在系统内存中用一段存储空间(帧缓冲设备)与整个显示区域对应,应用通过改变该帧缓冲(FrameBuffer)的内容,从而改变显示屏的显示内容;显示屏上的每一像素点都与帧缓冲设备里的某一位置对应,鉴于计算机显示的颜色是通过RGB值来表示的,则必须给出相应的帧缓冲中RGB码值来实现显示屏在屏幕某一像素点显示某种颜色的效果[1~2]。物理上TFT-LCD液晶屏由显示屏、信号驱动部件、背光源等组成,其最重要的信号驱动部件由LCD控制器、LCD时序控制器、源驱动器/栅极驱动器构成,目前LCD控制器多集成在处理器中,专门用于液晶屏的接口,可以独立地对屏提供同步时序信号和显示数据信号;时序控制器是信号驱动部件中负责时序管理的控制单元,它直接控制着屏中的驱动部件(LCD驱动器)保证其输出正确的控制时序,实现LCD控制器与LCD驱动器间的信号时序转换功能;LCD驱动器主要用来生成屏所需要的各种驱动信号,分为栅极驱动器(Gate Driver)和源驱动器(Source Driver)[3],其物理组成框图见图1。
图1 显示屏物理组成示意框图
一般LCD驱动器所需要的输入时序信号众多,且不同的LCD驱动器所需要的输入时序信号不尽相同,以下信号是所有LCD驱动器所必需的,如表1。
表1 LCD信号功能表
本文涉及的通信终端采用目前主流ARM Cor⁃tex处理器、液晶触摸显示屏、嵌入式Linux操作系统等构建显示终端基础平台,为上层基于QT等GUI工具开发的通信监控应用提供运行环境。
2.2.1 硬件组成
硬件平台采用三星公司的S5PV210芯片为微处理器,S5PV210采用的是主频可达到1G Hz的ARM Cortex-A8内核,具有64/32位内部总线结构,32/32KB的数据/指令一级缓存,512KB的二级缓存,可实现每秒2亿条指令集的运算能力。支持XGA(1027*768)级别LCD显示,其内置LCD控制器可以传输显示数据和产生控制信号,接口包含行扫/时钟/使能控制信号和RGB数据信号,通过I2C和中断脚方式支持电容和电阻屏[4~6];液晶屏选用日立工业屏KOE TX18D200VM0EAA,它是由JDI公司生产的5寸TFT类型的LCD,支持VGA接口,4:3格式,分辨率为640*480像素,262K色(R、G、B 6BIT),显示响应时间不大于45ms[7]。
2.2.2 基础软件组成
底层基础软件基于嵌入式Linux内核和Fram⁃buffer机制进行驱动设计与移植。
LCD上一副画面称为一帧,每帧由多个行组成,多个像素组成了一行,多位(bit)数据组成了每个像素的颜色。对于262K色的KOE TX13D200VM5BAA LCD,每个像素由18bit来表示R、G、B各6bit,称为18BPP。当VSYNC信号到来,显示器从屏幕的最左上方开始,从左往右一行行的显示每个像素的数据,当显示到一行最右边时,HSYNC信号到来,随即跳到下一行的最左边开始显示下一行;当所有行显示完后,VSYNC信号重新到来,跳到最左上方显示下一帧[8]。
通常LCD控制器支持多种帧缓冲区的内存格式,如:25BPP Display(A888)、32BPP(8888)、24BPP Display(A887)、24BPP Display(888)等,实际上在Linux驱动程序里用得比较多的是32BPP(8888)的内存格式组织图象数据,即用32位数据来表示一个像素的颜色,每种原色(R、G、B)使用8位,还有8位分配给ALPHA。(ALPHA用于实现图形渐变效果、半透明效果:0xff全透明0x00不透明)其32BPP(8888)格式在内存中像素的排列格式如表2。
表2 32BPP内存格式WSWP无效
控制器中的VDMA自动地从帧缓冲区中获取视频数据(如上述的32BPP(8888)内存格式),再由VPRCS接受来自VDMA的视频数据后并将它们组合成指定的数据格式(例如24bpp或16bpp模式),经由控制器数据端口(RGB_VD,or SYS_VD)发送到LCD显示,像素颜色值与VD[23:0]引脚的对应关系。
结合文献[9]中介绍时序关系,LCD屏根据其时序设置,按这些信号有序并不停地读取总线数据并显示;
通过设置S5PV210的显示控制器的寄存器,配置显示缓冲区、时序、窗口、坐标等参数后,便可将所显示的内容从显示缓冲区中读出屏中显示[10],其寄存器说明见表3。
表3 CPU显控寄存器组成表
寄存器的配置在操作系统内核中文件路径为
/drivers/video/samsung/S3cfb_fimd6x.c中实现。其具体相关实现函数如下:
函数s3cfb_set_output:配置VIDCON0寄存器,实现视频控制器的输出格式(RGB);
函数s3cfb_set_display_mode:配置 VIDCON0寄存器,实现RGB的模式(Parallel RGB);
函数 s3cfb_set_timing:配置VIDTCON0、VIDT⁃CON1寄存器,根据实际LCD的时序图设定VBPDE(YVU)、VBPD 、VFPD、VSPW、VFPDE(YVU)、HB⁃PD、HFPD、HSPW;
函 数 s3cfb_set_window_position:配 置 VI⁃DOSD0C和VIDOSD0B寄存器,设置窗口的左上角和右下角的位置;
函数s3cfb_set_window_size:配置 VIDOSD0C寄存器,设置窗口的大小(Height*Width);
函数s3cfb_set_buffer_size:配置VIDWxxADD2寄存器,设置虚拟屏幕的页宽度(字节)。
帧缓冲设备驱动采用分层的设计方式,在内核空间里第一层是对帧缓冲设备文件层接口file_op⁃erations结构体进行填充(代码实现在/drivers/video/fbmem.c),它向用户空间提供/dev/fb*设备的访问接口,用户空间通过它绘制图形。在内核空间里第二层是对帧缓冲设备驱动层接口fb_info结构体进行填充(代码实现在/drivers/video/samsung/s3cfb.c),这是与架构相关代码,初始化LCD控制器,注册/注销帧缓冲设备等,其中fb_ops结构体中的成员函数实现对LCD控制器硬件寄存器操作[11],具体示意图见图2。
图2 函数组成图
帧缓冲设备驱动最重要的数据结构有定义在/include/linux/fb.h文件中的 fb_info、fb_var_screenin⁃fo、fb_fix_screeninfo、fb_ops等结构,以及定义在/linux/drivers/vedio/fbmem.c文件中的file_operations结构。
图3 LCD初始化流程示意
fb_info结构中描述了帧缓冲设备全部内容,例如属性、状态和操作等,每个帧缓冲设备都有一个对 应 的 fb_info结 构 ,fb_var_screeninfo、fb_fix_screeninfo、fb_ops都包含在该结构中。其中fb_var_screeninfo结构描述了用户可修改的显示控制器参数,包括LCD分辨率、BPP、内存中像素颜色组织方式和时序参数等;fb_fix_screeninfo结构描述了用户不能修改的显示控制器参数,包括屏幕缓冲区的物理地址、长度等,该结构的成员需要在驱动程序中初始化和设置,其初始化过程见图3;fb_ops结构是指向底层操作的函数指针结构体,它类似于file_operations结构实现文件设备操作;file_opera⁃tions结构是帧缓冲设备驱动的文件层操作接口[12]。在s3cfb_probe函数中,描述了LCD驱动实现的全部内容。s3cfb_lcd是描述LCD屏密切相关参数的结构体,在arch/arm/mach-s5pv210/mini210-lcds.c中实现,mini210_machine_init函数(定义在arch/arm/mach-s5pv210/mach-mini210.c),通 过 调 用mini210_get_lcd完成LCD屏密切相关参数的传递,那么移植LCD驱动的关键内容就在于修改s3cfb_lcd结构中的成员。s3cfb_lcd结构如下:
struct s3cfb_lcd{
int width;
int height;
int p_width;
int p_height;
int bpp;
int freq;
struct s3cfb_lcd_timing timing;
struct s3cfb_lcd_polarity polarity;
void(*init_ldi)(void);
void(*deinit_ldi)(void);
unsigned long args;
};
根据KOE TX13D200VM5BAA LCD屏的时序、像素、BPP、极性、频率等参数,在arch/arm/mach-s5pv210/mini210-lcds.c中增加如下内容:
static struct s3cfb_lcd wvga_s70={
.width=640,
.height=480,
.p_width=102,//LCD屏的有效区域,非物理尺寸
.p_height=77,//LCD屏的有效区域,非物理尺寸
.bpp=32,
.freq=60,//刷新率
.timing={
.h_fp=100,
.h_bp=50,
.h_sw=10,
.v_fp=40,
.v_fpe=1,
.v_bp=4,//guess 4
.v_bpe=1,
.v_sw=1,//guess 1
},
.polarity={
.rise_vclk=0,//下降沿锁寸数据(此参数是数据图象清晰的关键参数)
.inv_hsync=0,
.inv_vsync=0,
.inv_vden=0,
}
}
完成以上内核代码修改后,必须完成编译才能进行测试。由于移植LCD屏并没有涉及到驱动结构的变动,所以勿需修改Makefile、Kconfig文件,执行“make menuconfig”,出现配置内核界面,在主菜单里选择<Exit>退出,输入以下命令,开始编译内核:#make zImage,编译结束后,会在arch/arm/boot目录下生成linux内核映象文件:zImage。
将编译好的LCD设备驱动下载到目标板,编写应用测试程序lcd_test;进入测试程序源代码目,使用命令行进行手工交叉编译测试程序,生成lcd_test可执行文件:
#arm-linux-gcc-o lcd_test lcd_test.c
通过FTP,将编译好的可执行文件下载到目标板。进入目标板上可执行文件所
测试结果如下图,打开了5个FB,使用了透明度功能,5个窗口叠加效果如下在的目录,改变可执行文件属性:
#chmod+x lcd_test
执行文件:./lcd_test,窗口输出的信息如下:
open framebuffer ok.
640,480,32bpp
[1511.469789] s3cfb s3cfb: win 0:pmem_start=0x3c331000
[1511.469803] s3cfb s3cfb: [fb0] dma:0x3c331000,cpu:0xe3000000,size:0x00465000
[1511.476159] s3cfb s3cfb: [fb1] dma:0x3a200000,cpu:0xffc00000,size:0x00177000
[1511.485200] s3cfb s3cfb: [fb3] dma:0x39c00000,cpu:0xffa00000,size:0x00177000
[1511.489190] s3cfb s3cfb: [fb4] dma:0x39e00000,cpu:0xff800000,size:0x00177000
set screeninfo ok
draw color ok
show window ok
实际LCD显示图型如图4所示。
LCD屏显示及Linux帧缓冲架构在嵌入式Linux显示中已广泛应用,帧缓冲创建的不仅仅是面底层设备和上层应用的抽象,更是一种设计思想架构与应用模型,本文通过分析LCD屏以及控制器的原理、特点,结合嵌入式通信应用环境提出基于最新ARM-CcortexA8架构LCD控制器和触屏的驱动移植开发方法,并在实际工作中有所应用与实现,随着后续研发实现此驱动开发方法和相关技术适用于多种智能显示终端的设计实现,具有较好的技术推广和应用价值。
图4 LCD显示图型
[1]冯国进.嵌入式Linux驱动程序设计从入门到精通[M].北京:清华大学出版社,2008:151-168.
[2]吴利刚.基于ARM驱动TFT-LCD模块研究与应用[D].汕头:汕头大学,2011:8-15.
[3]王珊.TFT-LCD显示芯片的驱动设计与研究[D].西安:西安电子科技大学,2014:9-16.
[4]葛耿育.S5PV210微处理器的启动过程分析[J].计算机工程应用技术,2017,13(15):220-221.
[5]SamSung Electronics Co.,Ltd.S5PV210 RISC Micropro⁃cessorS5PV210_UM_REV1.1[EB/OL].http://www.sam⁃sungsemi.com,2010-5.
[6]刘龙,张云翠,申华.嵌入式Linux软硬件详解[M].北京:人民邮电出版社,2015:183-188.
[7] KOE.TX18D200VM0EAASpecifications[R].TaiWan:Kaohsiung Opto-Electronics Inc,2013.
[8]韦东山.嵌入式Linux应用开发[M].北京:人民邮电出版社,2008:200-201.
[9]王永涛,虞闯.嵌入式LCD裸机驱动设计与实现[J].沈阳理工大学学报,2016,35(6):3-4.
[10]友善之臂.Linux平台下Mini210s裸机程序开发指南[EB/OL].http://www.arm9home.net,2012-10.
[11]陈磊.基于CK-CPU嵌入式平台的LCD驱动的开发与实现[D].哈尔滨:哈尔滨工业大学,2012:23-29.
[12]杨斌斌.嵌入式Linux设备驱动程序的研究与开发[D].太原:太原理工大学,2009:53-59.