Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1345838
  • 博文数量: 206
  • 博客积分: 10571
  • 博客等级: 上将
  • 技术积分: 2610
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-30 11:50
文章分类
文章存档

2014年(1)

2013年(4)

2012年(18)

2010年(14)

2009年(31)

2008年(3)

2007年(135)

分类: LINUX

2008-05-06 14:20:26

基于S3C24102.6内核linux

TFT液晶的驱动设计

 

张新健    指导教师:刘超英

 

请要转载的朋友注明出处,谢谢!

文件: 张新健—基于S3C2410与2.6内核linux下TFT液晶的驱动设计.rar
大小: 589KB
下载: 下载

  实现了以S3C2410处理器为硬件,为可移植的嵌入式linux系统编写TFT-LCD屏的系统驱动技术。该驱动基于linux系统帧缓冲技术,既实现驱动底层S3C2410LCD控制器又为上层应用程序提供系统调用的接口API

关键词 S3C2410处理器、LCD控制器、ARM920T、嵌入式linux系统、帧缓冲设备驱动、LCD设备驱动。

 

1引言

随着现代计算机的大量普及,各类智能电脑也越来越多的显现在我们的现实生活中。LCD液晶作为重要的人机界面非常广泛的使用在各种嵌入式设备中,而linux操作系统由于其非常强的可移植性和稳定性同样也被广大的嵌入式设备开发商所采用。本设计就是基于最新的2.6内核的linux系统的底层驱动编写,研究linux下的TFT-LCD驱动(属字符设备驱动)的结构、移植、编写、加载与卸载、以及用户层的接口设计等技术。其中硬件使用三星公司开发的ARM9核嵌入式处理器——S3C2410Linux系统采用2.6.8的内核。

 

2 硬件实现

2.1 TFT LCD显示器原理

 

LCDliquid crystal display,是一种数字显示技术,可以通过液晶和彩色过滤器过滤光源,并在平面面板上产生图像。常见的液晶显示器按物理结构分为一下四种:

l        扭曲向列型(TN

l        超扭曲向列型(STN

l        双层超扭曲向列型(DSTN

l        薄膜晶体管型(TFT

本设计采用TFT型液晶显示器。TFT-LCD是一种广泛拥有电视、笔记本电脑、监视器、手机等产品的有源矩阵液晶显示器件。TFT将点阵像素分割成红、绿、蓝三个子像素,并在其对应位置的器件内表面设置RGB 三个微型滤色膜,此时液晶显示器件只作为一个光阀,控制每个子像素光阀,就可以控制滤色膜透过光的通断;控制光阀的灰度等级就可以控制相应滤色膜透过光的多少;利用RGB这三个子像素透过的不同光量,便可以混合加色实现极为丰富的彩色。如果RGB这三个子像素均可实现人眼对灰度分辨能力64级灰度驱动,就可以实现有64x64x6426万种彩色的“真彩色”。

TFT的主要特点是在每个像素配置一个半导体开关器件,由于每个像素都可以通过点脉冲直接控制,使得每个节点相对独立,并可以连续控制。TFT-LCD具有屏幕反应速度快,对比度和亮度都较高,屏幕可视角度大,色彩丰富、分辨率高等特点,是目前最好的LCD彩色显示设备之一。其原理见图1    

 

 

 

 

 

 

 

                                                                      

1 TFT液晶原理

此次设计采用东华WXHAT35-TG2#001320*240分辨率下可提供16位彩色显示。其尺寸参数及引脚说明见图2,液晶屏与S3C2410处理器引脚连接见图3.

 

 

 

 

 

 

 

 

 

 

 

 

分辨率:320*240
对比度:300
1
亮度:250 cm
/m2
外观尺寸:76.9*63.9mm

厚度:3.2mm
显示颜色:16.7兆色
Back light:six LEDs serial type
接口方式:24bit RGB
显示面积:70.08Hmm×52.56V
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 CP15CP14 用于调试控制,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 S3C2410LCD控制器

 

LCD控制器的功能是产生显示驱动信号,驱动LCD显示器。用户只需要通过读写一系列的寄存器,完成配制和显示控制。S3C2410 LCD控制器支持STNTFT屏,对于TFT屏,其特性如下:

l        支持单色、4级灰度、256色的调色板显示模式。

l        支持64K16M色非调色板显示模式。

l        支持分辨率为640*480320*240及其他多种规格的LCD

S3C2410LCD控制器内部逻辑结构见图5

REGBANKLCD控制器的寄存器组,用来对LCD控制器的各项参数进行设置。而LCDCDMA则是LCD控制器专用的DMA信道,负责将视频资料从系统总线(System Bus)上取来,通过VIDPRCSVD[23:0]发送给LCD屏。同时TIMEGENLPC3600负责产生LCD屏所需要的控制时序(如VSYNC,HSYNC,VCLK,VDEN,然后从VIDEO MUX送给LCD屏。

 

 

 

 

 

                                          

 

5 S3C2410LCD控制器内部逻辑结构

通常使用的LCD控制管脚的定义如下:

VCLK:像素时钟信号;

VD [23:0]LCD像素输出端口;

VMVDENTP: 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])以外,还有以下一些信号是必不可少的,分别是:

VCLK(像素时钟信号)

VDEN(数据使能信号)

VSYNC(垂直同步信号)

HSYNC(水平同步信号)

LEND(行结束信号)

LCD_PWREN(液晶屏使能信号)

VCLK信号依赖于LCDCON1寄存器中CLKVALS3C2410HCLK的取值,具体公式为:

l          VCLK(Hz)=HCLK[(CLKVAL+1)x2]

VSYNCHSYNC的产生依赖于LCDCON23寄存器及HOZVALLINEVAL的配置,其中:

l        HOZVAL=水平显示尺寸-1

l        LINEVAL=垂直显示尺寸-1

 

一般情况下,帧频率就是VSYNC信号的频率,它与LCDCON1LCDCON234寄存器的VSYNCVB2PDVFPDLINEVALHSYNCHBPDHFPDHOZVALCLKVAL都有关系。大多数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)添加初始化s3c2410LCD控制器时所需的参数(修改文件: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<<8)|(0<<7)|(3<<5)|(12<<1),

       .lcdcon2 = (14<<24) | (239<<14) | (11<<6) | (2),

       .lcdcon3 = (37<<19) | (319<<8) | (19),

       .lcdcon4 = (13<<8) | (29),

       .lcdcon5 = (1<<11) | (1<<10) | (1<<9) | (1<<8) | (0<<7) | (1<<5) | (1<<3)  |(0<<1) | (1),

   }

};

 

3 linux系统下驱动的软件实现

3.1 嵌入式linux系统典型构成

 

嵌入式LinuxEmbedded Linux)是指对Linux经过裁剪小型化后,可固化在存储器或单片机中,应用于特定嵌入式场合的专用Linux操作系统。嵌入式Linux的开发和研究已经成为目前操作系统领域的一个热点。嵌入式Linux系统的典型构成见图7

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                         7嵌入式Linux系统的典型构成

 

3.2 linux设备驱动简介

 

1)设备驱动的任务包括:

对设备初始化和释放
把数据从内核传送到硬件和从硬件读取数据
读取应用程序传送给设备文件的数据和回送应用程序请求的数据
检测和处理设备出现的错误

2linux系统下设备类型分类:

字符设备(char device)。

块设备(block device)。

网络设备(Network interfaces

3LinuxLCD设备驱动的实现方法:

像普通字符设备进行驱动编写

基于linux framebuffer 设备进行驱动编写

 

 

4)嵌入式linux的驱动程序所起的作用见下图8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

      

8 驱动程序在嵌入式linux系统中的作用

 

5)嵌入式linux设备驱动程序分三大部分

l        自动配置和初始化:检查硬件设备能否正常工作,进行状态初始化工作。

l        I/O端口请求:这部分需要进行系统调用才能完成,系统从用户态变成内核态,然后进行各种I/O操作。

l        中断服务:在嵌入式linux中,中断信号由嵌入式linux系统接收,然后选择相应的中断服务程序。

 

3.2 linux Framebuffer设备驱动

 

此次设计linux TFT-LCD驱动就是基于帧缓冲设备编写。帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer设备驱动来完成的。

linux framebuffer设备是标准字符设备,主设备号为29,次设备号则从031。帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示卡,Linux下还可支持多个帧缓冲设备,最多可达32 个,分别为/dev/fb0/dev/fb31,而/dev/fb则为当前缺省的帧缓冲设备,通常指向/dev/fb0。此次设计为嵌入式系统,支持一个显示设备就够了。

Framebuffer设备在很大程度上依靠了下面的3个数据结构,在fb.h中声明.

    Struct fb_var_screeninfo

    Struct fb_fix_screeninfo

    Struct fb_info

    1个结构是用来描述图形卡的特性的,通常是被用户设置的。第2个结构定义了图形卡的硬件特性,是不能改变的,用户选定了LCD控制器和显示器后,那么它的硬件特性也就定下来了。第3个结构定义了当前图形卡framebuffer设备的独立状态,一个图形卡可能有两个framebuffer,在这种情况下,就需要两个fb_info结构,这个结构是惟一内核空间可见的。

 

3.3 framebuffer驱动程序的实现

 

3.3.1应用程序调用framebuffer驱动原理

应用程序通过内核对framebuffer的控制主要有下面三种方式:

1)//dev/fb:相当于读/写屏幕缓冲区

2)映射(map)操作:通过映射操作,可将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中,之后用户就可以通过读写这段虚拟地址访问屏幕缓冲区,在屏幕上绘图。

3)I/O控制:对应帧缓冲设备,设备文件的ioctl操作可读取设置显示设备及屏幕的参数,如分辨率、显示颜色数、屏幕大小等等。Ioctl的操作是由底层的驱动程序来完成的。

因此,Framebuffer驱动要完成的工作已经很少了,只需分配显存的大小,初始化LCD控制寄存器、设置修改硬件设备相应的var信息和fix信息。图10反映了应用程序如何写帧缓冲设备来显示图形的全过程。

 

 

 

 

 

 

 

 

 

 

 

 

 

                        

 

 

9 驱动程序实现框图

 

 

3.3.2帧缓冲设备驱动的程序结构

帧缓冲设备提供给用户空间的file_operations结构体有fbmem.c中的file_operations提供,而特定帧缓冲设备fb_info结构体的注册、注销、以及其中成员的维护,尤其是fb_ops中成员函数的实现则由对应的xxxfb.c文件实现,fb_ops中的成员函数最终会操作LCD控制器硬件寄存器。其程序结构间图9

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

10帧缓冲设备驱动的程序结构

 

 

3.3.3具体结构及函数编写

具体要编写相关平台的驱动文件为:s3c2410fb.h s3c2410fb.c

1) s3c2410fb.h:主要为声明结构体和宏定义,有下面三个主要的结构体要声明:

l        struct pxafb_lcd_reg

l        struct pxafb_info

l        struct pxafb_mach_info

 

2) 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

 

 

 

 

 

 

 

11 驱动程序的模块加载模式

 

2)驱动程序直接编译入内核

采用这种方式编译的驱动程序在内核启动时就已经在内存中,运行时不需要再自己加载驱动,可以保留专用的存储器空间。具体实现方法见图11

 

 

12 驱动程序编译进内核的加载方式

 

 

 

本次设计的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后,选择“Graphics support”项,选中我们要加载进内核的“s3c2410 LCD framebuffer support”选项。

l        保存内核改动后,使用make zImage将内核重新打包编译成映像文件。编译完成后的映像文件就可以用于开发板的下载了。

 

 

5 设计结果

本设计的主要目的是通过对S3C2410嵌入式处理器的LCD控制器进行控制,以驱动320*240TFT液晶显示器。驱动的程序结构针对linux系统进行设计,依托linux系统的帧缓冲设备驱动结构,设计了嵌入式linux下的TFT LCD帧缓冲设备驱动程序。驱动包括I/O端口的初始化,LCD控制器的初始化,驱动程序的系统注册和卸载,以及为应用程序设计了一定的API接口程序,以便用户调用。虽然驱动设计的并不十分完美,对于linux系统内核调用等方面的性能有所欠缺,但基本达到了对TFT液晶的驱动效果。

 

 

参考文献:

1】宋宝华。Linux设备驱动开发详解。北京:人民邮电出版社,2008

2】孙纪坤,张小全。嵌入式linux系统开发技术详解基于ARM。北京:人民邮电出版社,2006

3】李俊。嵌入式linux设备驱动开发详解。北京:人民邮电出版社,2008

4】孙天泽,袁文菊。嵌入式设计及linux驱动开发指南基于ARM9处理器(第2版)。北京:电子工业出版社,2007

5】张崙。32位嵌入式系统硬件设计与调试。北京:机械工业出版社,2006

6 译。Linux设备驱动程序(第三版)。北京:中国电力出版社,2006

7】许庆丰。嵌入式Linux下彩色LCD驱动的设计与实现。200212月。

8】刘利国。S3C2410 LCD 驱动程序移植及GUI 程序编写。20051月。

9seasea2410 lcd(ltv350)驱动在2.6.14下的移植经历。20071月。

10】雷鸿,熊文龙,杨单。基于FramebufferLCD驱动程序的实现。20062月。

阅读(4722) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2011-04-04 14:01:53

学习了,多谢楼主分享哦!也欢迎广大linux爱好者来我的论坛一起讨论arm哦!www.lt-net.cn

yanzilove2008-09-20 18:25:46

你好,我是学习LINUX的学生,我想参考一下你的源码,请问可以吗? 如果行的话,麻烦你给我发到wzd585426@163.com

yanzilove2008-09-20 18:25:41

你好,我是学习LINUX的学生,我想参考一下你的源码,请问可以吗? 如果行的话,麻烦你给我发到wzd585426@163.com