- 论坛徽章:
- 0
|
基于S3C2410与2.6内核linux
下TFT液晶的驱动设计
张新健 指导教师:刘超英
请要转载的朋友注明出处,谢谢!
![]()
文件:
linux_LCD.rar
大小:
577KB
下载:
下载
摘 要 实现了以S3C2410处理器为硬件,
为可移植的嵌入式linux系统编写TFT-LCD屏的系统驱动技术。该驱动基于linux系统帧缓冲技术,既实现驱动底层S3C2410的LCD控制器又为上层应用程序提供系统调用的接口API。
关键词 S3C2410处理器、LCD控制器、ARM920T、嵌入式linux系统、帧缓冲设备驱动、LCD设备驱动。
1引言
随着现代计算机的大量普及,各类智能电脑也越来越多的显现在我们的现实生活中。LCD液晶作为重要的人机界面非常广泛的使用在各种嵌入式设备中,而linux操作系统由于其非常强的可移植性和稳定性同样也被广大的嵌入式设备开发商所采用。本设计就是基于最新的2.6内核的linux系统的底层驱动编写,研究linux下的TFT-LCD驱动(属字符设备驱动)的结构、移植、编写、加载与卸载、以及用户层的接口设计等技术。其中硬件使用三星公司开发的ARM9核嵌入式处理器——S3C2410。Linux系统采用2.6.8的内核。
2 硬件实现
2.1 TFT LCD显示器原理
LCD(liquid crystal display),是一种数字显示技术,可以通过液晶和彩色过滤器过滤光源,并在平面面板上产生图像。常见的液晶显示器按物理结构分为一下四种:
l 扭曲向列型(TN)
l 超扭曲向列型(STN)
l 双层超扭曲向列型(DSTN)
l 薄膜晶体管型(TFT)
本设计采用TFT型液晶显示器。TFT-LCD是一种广泛拥有电视、笔记本电脑、监视器、手机等产品的有源矩阵液晶显示器件。TFT将点阵像素分割成红、绿、蓝三个子像素,并在其对应位置的器件内表面设置R、G、B 三个微型滤色膜,此时液晶显示器件只作为一个光阀,控制每个子像素光阀,就可以控制滤色膜透过光的通断;控制光阀的灰度等级就可以控制相应滤色膜透过光的多少;利用R、G、B这三个子像素透过的不同光量,便可以混合加色实现极为丰富的彩色。如果R、G、B这三个子像素均可实现人眼对灰度分辨能力64级灰度驱动,就可以实现有64x64x64约26万种彩色的“真彩色”。
TFT的主要特点是在每个像素配置一个半导体开关器件,由于每个像素都可以通过点脉冲直接控制,使得每个节点相对独立,并可以连续控制。TFT-LCD具有屏幕反应速度快,对比度和亮度都教高,屏幕可视角度大,色彩丰富、分辨率高等特点,是目前最好的LCD彩色显示设备之一。其原理见图1:
图1 LCD液晶原理
此次设计采用东华WXHAT35-TG2#001在320*240分辨率下可提供16位彩色显示。其尺寸参数及引脚说明见图2,液晶屏与S3C2410处理器引脚连接见图3.
分辨率:320*240
对比度:300:1
亮度:250 cm/m2
外观尺寸:76.9*63.9(mm)
厚度:3.2(mm)
显示颜色:16.7兆色
Back light:six LEDs serial type
接口方式:24bit RGB
显示面积:70.08(H)mm×52.56(V)mm
图2 液晶尺寸参数及引脚说明
图3 液晶屏与S3C2410处理器引脚连接]
2.2三星嵌入式处理器:S3C2410
2.2.1 S3C2410处理器概述
S3C2410 是韩国三星公司的一款基于ARM920T 内核的16/32 位RISC 嵌入式微处理器,主要面向手持设备以及高性价比,低功耗的应用。运行的频率可以达到203MHz。
ARM920T 核由ARM9TDMI,存储管理单元(MMU)和高速缓存三部分组成。其中MMU 可以管理虚拟内存,高速缓存由独立的16KB 地址和16KB 数据高速Cache 组成ARM920T 有两个协处理器:CP14 和CP15。CP14 用于调试控制,CP15 用于存储系统控制以及测试控制。(其内部结构见图4)
S3C2410 的资源包括:
l 1 个LCD 控制器
l SDRAM 控制器。
l 3 个通道的UART。
l 4 个通道的DMA。
l 4 个具有PWM 功能的计时器和一个内部时钟。
l 8 通道的10 位ADC。
l 触摸屏接口。
l IIS 总线接口。
l 2 个USB 主机接口,1 个USB 设备接口。
l 2 个SPI 接口。
l SD 接口和MMC 卡接口。
l 看门狗计数器。
l 117 个通用I/O 口和24 位外部中断源。
l 8 通道10 位AD 控制器。
图4 S3C2410结构
2.2.2 S3C2410的LCD控制器
LCD控制器的功能是产生显示驱动信号,驱动LCD显示器。用户只需要通过读写一系列的寄存器,完成配制和显示控制。S3C2410 LCD控制器支持STN和TFT屏,对TFT屏,其特性如下:
l 支持单色、4级灰度、256色的调色板显示模式。
l 支持64K和16M色非调色板显示模式。
l 支持分辨率为640*480,320*240及其他多种规格的LCD。
S3C2410的LCD控制器内部逻辑结构见图5。
REGBANK是LCD控制器的寄存器组,用来对LCD控制器的各项参数进行设置。而LCDCDMA则是LCD控制器专用的DMA信道,负责将视频资料从系统总线(System Bus)上取来,通过VIDPRCS从VD[23:0]发送给LCD屏。同时TIMEGEN和LPC3600负责产生LCD屏所需要的控制时序(如VSYNC,HSYNC,VCLK,VDEN),然后从VIDEO MUX送给LCD屏。
图5 S3C2410的LCD控制器内部逻辑结构
通常使用的LCD控制管脚的定义如下:
VCLK:像素时钟信号;
VD [23:0]:LCD像素输出端口;
VM/VDEN/TP: LCD驱动器的AC偏置信号(STN)/数据使能信号(TFT)/SEC TFT源驱动器数据加载脉冲信号复用端口。
S3C2410 LCD控制器内部的寄存器可以控制LCD控制器接口的工作模式,LCD驱动编写的主要工作就是正确设置对应于所用的LCD屏的CPU寄存器。表1 所示为S3C2410中与LCD相对应的寄存器,给出了各个寄存器的简要描述。(LCDCON1~5是最重要的控制寄存器,其详细说明可以参看S3C2410处理器的详细说明书)
表1 S3C2410 LCD控制器相关设置
2.3 S3C2410 LCD控制器的详细设置
对于控制TFT屏来说,除了要给它送视频资料(VD[23:0])以外,还有以下一些信号是必不可少的,分别是:
l VFRAME:LCD控制器和LCD驱动器之间的帧同步信号。该信号告诉LCD屏的新的一帧开始了。LCD控制器在一个完整帧显示完成后立即插入一个VFRAME信号,开始新一帧的显示;
l VLINE:LCD控制器和LCD驱动器之间的线同步脉冲信号,该信号用于LCD驱动器将水平线(行)移位寄存器的内容传送给LCD屏显示。LCD控制器在整个水平线(整行)数据移入LCD驱动器后,插入一个VLINE信号;
l VCLK:LCD控制器和LCD驱动器之间的像素时钟信号,由LCD控制器送出的数据在VCLK的上升沿处送出,在VCLK的下降沿处被LCD驱动器采样;
l VM: LCD驱动器的AC信号。VM信号被LCD驱动器用于改变行和列的电压极性,从而控制像素点的显示或熄灭。VM信号可以与每个帧同步,也可以与可变数量的VLINE信号同步。
HOZVAL和L NEVAL的值由LCD屏的尺寸决定:
l HOZVAL=水平显示尺寸-1
l LINEVAL=垂直显示尺寸-1
VCLK信号的频率取决于LCDCON1寄存器中的CLKVAL域。VCLK和CLKVAL的关系如下(其中CLKVAL的最小值是0):
l VCLK(Hz)=HCLK/[(CLKVAL+1)x2]
一般情况下,帧频率就是VSYNC信号的频率,它与LCDCON1和LCDCON2/3/4寄存器的VSYNC、VB2PD、VFPD、LINEVAL、HSYNC、HBPD、HFPD、HOZVAL和CLKVAL都有关系。大多数LCD驱动器都需要与显示器相匹配的帧频率,帧频率计算公式如下:
l FrameRate=1{[(VSPW+1)+(VBPD+1)+(LINEVAL+1)+(VFPD+1)]×[(HSPW+1)+ (HBPD+1)+(HFPD+1)+(HOZVAL+1)]×[2×(CLKVAL+1)/(HCLK)]}
以下图6为东华WXHAT35-TG2#001,的时序要求:
图6东华WXHAT35-TG2#001,的时序要求
依照液晶屏时序设置linux系统的相关驱动文件参数如下:
1)添加头文件
#include
2)添加初始化s3c2410的LCD控制器时所需的参数(修改文件:linux/drivers/video/s3c2410fb.c)
/* LCD driver info */
/* Configuration for 320*240东华WXHAT35-TG2#001*/
struct pxafb_mach_info S3C2410_320X240_WX3500B_M06 = {
.pixclock = 270000,
.xres = 320,
.yres = 240,
.bpp = 16,
.hsync_len = 29, //LCD_HSPW
.left_margin = 19, //LCD_HFPD
.right_margin = 37, //LCD_HBPD
.vsync_len = 2, //LCD_VSPW
.upper_margin = 11, //LCD_VFPD
.lower_margin = 14, //LCD_VBPD
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.cmap_greyscale = 0,
.cmap_inverse = 0,
.cmap_static = 0,
.reg = {
.lcdcon1 = (7
.lcdcon2 = (14
.lcdcon3 = (37
.lcdcon4 = (13
.lcdcon5 = (1 |(0
}
};
3 linux系统下驱动的软件实现
3.1 嵌入式linux系统典型构成
嵌入式Linux(Embedded Linux)是指对Linux经过裁剪小型化后,可固化在存储器或单片机中,应用于特定嵌入式场合的专用Linux操作系统。嵌入式Linux的开发和研究已经成为目前操作系统领域的一个热点。嵌入式Linux系统的典型构成见图7。
图7嵌入式Linux系统的典型构成
3.2 linux设备驱动简介
1)设备驱动的任务包括:
对设备初始化和释放
把数据从内核传送到硬件和从硬件读取数据
读取应用程序传送给设备文件的数据和回送应用程序请求的数据
检测和处理设备出现的错误
2)设备类型分类:
字符设备(char device)。
块设备(block device)。
网络设备(Network interfaces)
3)Linux下LCD设备驱动的实现方法:
像普通字符设备进行驱动编写
基于linux framebuffer 设备进行驱动编写
4)嵌入式linux的驱动程序所起的作用间下图8
图8 驱动程序在嵌入式linux系统中的作用
5)嵌入式linux设备驱动程序分三大部分
l 自动配置和初始化:检查硬件设备能否正常工作,进行状态初始化工作。
l I/O端口请求:这部分需要进行系统调用才能完成,系统从用户态变成内核态,然后进行各种I/O操作。
l 中断服务:在嵌入式linux中,中断信号由嵌入式linux系统接收,然后选择相应的中断服务程序。
3.2 linux的帧缓冲设备驱动(Framebuffer)
此次设计linux LCD驱动就是基于帧缓冲设备编写。帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer设备驱动来完成的。
linux framebuffer设备是标准字符设备,主设备号为29,次设备号则从0到31,分别对应/dev/fb0-/dev/fb31。帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示卡,Linux下还可支持多个帧缓冲设备,最多可达32 个,分别为/dev/fb0到/dev/fb31,而/dev/fb则为当前缺省的帧缓冲设备,通常指向/dev/fb0。此次设计为嵌入式系统,支持一个显示设备就够了。
编写帧缓冲设备驱动程序的主要工作有5部分。
l 编写初始化程序
l 编写成员函数
l 读/写(read/write)
l 地址映射(map)
l 输入/输出控制(I/O)
3.3 LCD驱动程序结构
帧缓冲设备提供给用户空间的file_operations结构体有fbmem.c中的file_operations提供,而特定帧缓冲设备fb_info结构体的注册、注销、以及其中成员的维护,尤其是fb_ops中成员函数的实现则由对应的xxxfb.c文件实现,fb_ops中的成员函数最终会操作LCD控制器硬件寄存器。其程序结构间图9:
图9帧缓冲设备驱动的程序结构
3.4 LCD驱动函数实现
具体要编写相关平台的驱动文件为:s3c2410fb.h 和s3c2410fb.c
s3c2410fb.h:主要为声明结构体和宏定义,有下面三个主要的结构体要声明
l struct pxafb_lcd_reg
l struct pxafb_info
l struct pxafb_mach_info
s3c2410fb.c:针对帧缓冲设备驱动程序的5部分工作进行结构体声明与函数定义,两个结构体及主要函数见下:
l static struct fb_ops pxafb_ops{}
主要函数: static int pxafb_setcolreg //设置颜色表函数
static int pxafb_check_var //检查可变参数
static int pxafb_set_par //设置可变参数
static int pxafb_blank //空白显示设定
l static struct device_driver pxafb_driver{}
主要函数:int __init pxafb_probe //LCD设备探测函数,此函数调用前面定义的函数,完成LCD硬件的初始化、fb_info参数的填充、申请缓冲区并注册缓冲设备。
l 除以上结构体及其成员函数还有如下主要函数:
int __devinit s3c2410fb_init //设备驱动注册
static int pxafb_freq_transition //LCD时钟参数修改函数,使其匹配CPU时钟改变
static inline unsigned int get_pcd //取得像素时钟
static inline void __pxafb_backlight_power//设定LCD背光电源
static inline void __pxafb_lcd_power //设定LCD电源
static void pxafb_setup_gpio //挂起io端口
static void pxafb_enable_controller //使能LCD控制器
static void pxafb_disable_controller //使停LCD控制器
4 linux设备驱动的移植
在完成了嵌入式linux驱动程序编写测试工作以后,下一步就是将编写好的驱动程序加载到系统内核,完成驱动硬件的工作。通常有以下两种方法。
1)驱动程序的模块加载
采用模块加载方式的驱动程序将会以模块形式存储在文件系统里,需要时动态载入内核即可。这样使得驱动程序按需加载,不用时节省内存,并且驱动程序相对独立于内核,升级灵活。具体实现方法见下图10:
图10 驱动程序的模块加载模式
2)驱动程序直接编译入内核
采用这种方式编译的驱动程序在内核启动时就已经在内存中,运行时不需要再自己加载驱动,可以保留专用的存储器空间。具体实现方法入图11:
图11 驱动程序编译进内核的加载方式
本次设计的LCD驱动的加载就是直接编译进内核的。具体实现如下:
l 将LCD驱动文件s3c2410fb.h 和s3c2410fb.c复制到/drivers/video目录。
l 更改该目录下的Kconfig,增加如下代码:
l 在该目录下的Makefile中添加如下代码:
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
l 进入源码目录,执行make menuconfig后,选择video项,进入video项后选中我们要加载进内核的“s3c2410 LCD framebuffer support”选项。
l 编译内核,使用make zImage将内核重新打包编译成映像文件。编译完成后的映像文件就可以用于开发板的下载了。
5 设计结果
经过此次设计圆满的完成了linux下TFT屏的帧缓冲设备驱动程序设计,达到了预先的设计目的。
参考文献:
【1】宋宝华。Linux设备驱动开发详解。北京:人民邮电出版社,2008。
【2】孙纪坤,张小全。嵌入式linux系统开发技术详解—基于ARM。北京:人民邮电出版社,2006。
【3】李俊。嵌入式linux设备驱动开发详解。北京:人民邮电出版社,2008。
【4】孙天泽,袁文菊。嵌入式设计及linux驱动开发指南—基于ARM9处理器(第2版)。北京:电子工业出版社,2007。
【5】张崙。32位嵌入式系统硬件设计与调试。北京:机械工业出版社,2006。
【6】
(美)Jonathan Corbet,Alessandro Rubini, Greg Kroah-Hartman
著
魏永明
,
耿岳
,
钟书毅
译。Linux设备驱动程序(第三版)。北京:中国电力出版社,2006。
【7】许庆丰。嵌入式Linux下彩色LCD驱动的设计与实现。2002年12月。
【8】刘利国。S3C2410 下LCD 驱动程序移植及GUI 程序编写。2005年1月。
【9】seasea。2410 lcd(ltv350)驱动在2.6.14下的移植经历。2007年1月。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/37510/showart_677654.html |
|