一、开发环境 ·
开发板:FL2440
LCD:WXCAT35-TG3#001
inux内核版本:linux-3.0
二.背景知识
要使一块LCD正常的显示文字或图像,不仅需要LCD驱动器,而且还需要相应的LCD控制器。在通常情况下,生产厂商把LCD驱动器会以COF/COG的形式与LCD玻璃基板制作在一起,而LCD控制器则是由外部的电路来实现,现在很多的MCU内部都集成了LCD控制器,如S3C2410/2440等。通过LCD控制器就可以产生LCD驱动器所需要的控制信号来控制STN/TFT屏了.我这个开发板上的LCD是TFT屏的.
三.
1.LCD原理图
2. LCD控制器组成
2.时序图
时序图中的各参数含义如下:
VBPD:垂直同步信号以前无效的行数,在下面的驱动中对应的是upper_margin.
VFBD:垂直同步信号以后无效的行数,驱动中对应的是lower_margin.
VSPW:垂直同步脉冲的宽度,驱动中对应的vsync_len.
HBPD:水平同步信号开始前无效的VCLK的个数,驱动中对应的left_margin.
HFPD:水平同步信号结束后无效的VCLK的个数,驱动中对应的right_margin.
HSPW:水平同步信号的宽度,驱动中对应的hsync_len.
用下面的图表示看起来可能形象一些
我是这么理解这个时序图的:
当帧同步信号到来时,意味着新的一屏图像数据开始发送,脉冲宽度VSPW+1.之后有一段无效信号,宽度为VPBD+1,所以一幅图像显示前要准备的时间为(VSPW+1)+(VBPD+1).从一幅图像开始显示到一幅图像显示完之间的有效信号宽度LINEVAL+1,显示完一幅图像之后也有一段无效信号,宽度为VFPD+1.
当行同步信号到来时,意味着新的一行图像数据开始发送,脉冲宽度HSPW+1.之后又一段无效信号,宽度为HBPD+1,所以一行图像显示前要准备的时间为
(HSPW+1)+(HBPD+1).从一行图像开始显示到一行图像显示完之间的有效信号宽度HOZVAL+1,显示完一行图像之后也有一段无效信号,宽度为HFPD+1.
在帧同步以及行同步的头尾都有一段无效信号的原因是CRT显示器电子枪偏转所需一定的时间.
以上参数的设置的值保存到REGBANK寄存器组中的 LCDCON1/2/3/4/5寄存器中,下面由S3C2440给出了主要的控制寄存器的各个位表示的含义。
LCDCON1: 1-4位:色位模式(1BPP,8BPP,16BPP等)注:bpp(bit per pixel)即每个像素用几位表示.
5-6位:扫描模式
8-17位:CLKVAL
LCDCON2: 0-5位:VSPW
6-13位:VFPD
23-14位:LINEVAL
24-31位:VBPD
LCDCON3: 0-7位:HFPD
8-18位:HOZVAL
19-25位:HBPD
LCDCON4: 0-7位:HSPW
这些参数将根据你的开发板和LCD手册设置。
帧缓冲的概念:
帧缓冲是Linux系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作.用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成.对于帧缓冲设备而言,只要在显示缓冲区中与显示点对应的区域写入颜色值,对应的颜色会自动在屏幕上显示。
如果像素为320*240,那么显示缓冲区应该有多大呢?这里的像素表示一行有320点,屏幕共有240行,一共有320*240个点,如果是16bpp,即一个点需要2个字节表示,那么显示缓冲区的大小为320*240*2.
16位色时显示缓冲区与显示点对应的关系可以是RGB565或者RGB555.我们知道任何一种颜色可以由红,绿,蓝调和而成
RGB565就表示当低5位全为1其余位为0时,这个对应的显示点就显示为Blue(蓝色),当中间6位全为1其余位全为0时对应的显示点就显示为Green(绿色),当最高的5位全为1其余位全为0时就表示Red(红色).对于一个显示点,在对应的16位显示缓冲区内的各个位写入不同的数值就能组合成不同的颜色,所以当bpp为16时,一个显示点能有2^16种颜色.
在什么时候使用调色板?
如果在显示缓冲里只给了每个像素一个字节,这时就需要调色板。所谓调色板就相当于一个数组,每一项都代表一个16位的像素(当然根据具体的LCD不同,可以自己配置调色板),可以根据从显示缓冲区中取出的数据来选择数组中的一项,这个16位像素就可以传给LCD了。
帧缓冲设备对应的设备文件是/dev/fb*。如果系统有多个显卡,Linux还支持多个帧缓冲设备,最多可达32个,即/dev/fb0~/dev/fb31。而/dev/fb则指向当前的帧缓冲设备,通常情况下,默认的帧缓冲设备为/dev/fb0。
Linux帧缓冲相关数据结构与函数
1.fb_info
一个帧缓冲设备对应一个数据结构体fb_info,fb_info记录了帧缓冲设备的全部信息,包括设备的设置参数,状态以及操作函数指针。
struct fb_info {
atomic_t count;
int node;
int flags;
struct mutex lock; /*用于open/release/ioctl的锁*/
struct fb_var_screeninfo var; /*可变参数 */
struct fb_fix_screeninfo fix; /* 固定参数 */
struct fb_monspecs monspecs; /* 显示器标准 */
struct work_struct queue; /* 帧缓冲事件队列 */
struct fb_pixmap pixmap; /* 图像硬件mapper */
struct fb_pixmap sprite; /* 光标硬件mapper */
struct fb_cmap cmap; /* 目前的颜色表*/
struct list_head modelist; /* mode list */
struct fb_videomode *mode; /* 目前的video模式 */
#ifdef CONFIG_FB_BACKLIGHT
/* 对应的背光设备*/
struct backlight_device *bl_dev;
/* 背光调整*/
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif
struct fb_ops *fbops;
struct device *device; /*父设备 */
struct device *dev; /* fb设备 */
int class_flag; /* 私有sysfs标志 */
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* 图块 Blitting */
#endif
char __iomem *screen_base; /* 虚拟基地址*/
unsigned long screen_size; /* ioremapped的虚拟内存大小 */
void *pseudo_palette; /* 伪16色颜色表*/
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* 硬件状态,如挂起 */
void *fbcon_par; /* fbcon use-only private area */
/* From here on everything is device dependent */
void *par;
/* we need the PCI or similiar aperture base/size not
smem_start/size as smem_start may just be an object
allocated inside the aperture so may not actually overlap */
struct apertures_struct {
unsigned int count;
struct aperture {
resource_size_t base;
resource_size_t size;
} ranges[0];
} *apertures;
};
fb_info中的fb_ops为指向底层操作函数的指针
struct fb_ops {
/* open/release and usage marking */
struct module *owner; //模块计数指针
int (*fb_open)(struct fb_info *info, int user); //打开设备指针
int (*fb_release)(struct fb_info *info, int user); //释放设备指针
/* For framebuffers with strange non linear layouts or that do not
* work with normal memory mapped access
*/ //下面两个函数对于非线性布局的常规内存无法工作的帧缓冲区设备有效
ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
/* checks var and eventually tweaks it to something supported,
* DO NOT MODIFY PAR */
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info); //检查可变参数,并调整到支持设备。用来检查和改变帧缓存设备的可变参数,当帧缓冲设备中的参数不满足驱动程序要求时,会调用这个函数
/* set the video mode according to info->var */
int (*fb_set_par)(struct fb_info *info); //设置视频模式。根据info->var变量设备视频模式
/* set color register */
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp, struct fb_info *info);