LCD驱动程序之层次分析与硬件原理

内核中自带的LCD驱动程序在drivers/video/fbmem.c,它是一个抽象性的框架程序,并不是一个具体的驱动,它依赖于底层的某个驱动程序提供注册一个fb_info结构体。

fb的意思是framebuffer.

首先假设,应用程序调用了open(“/dev/fb0”, …),主设备号是29,次设备号是0,经过层层调用,会调用到file_operations里的open函数。在fb_open函数里做了什么呢?
先获得了次设备号:
int fbidx = iminor(inode);
然后以次设备号为数组的下标,得到了一个结构体:
struct fb_info *info = registered_fb[0]

再假设,应用程序调用了read(),经过层层调用,会调用到file_operations里的read函数,那么在fb_open里做了什么呢?

int fbidx = iminor(inode);
struct fb_info *info = registered_fb[fbidx];
if (info->fbops->fb_read)
    return info->fbops->fb_read(info, buf, count, ppos);

src = (u32 __iomem *) (info->screen_base + p);
dst = buffer;
*dst++ = fb_readl(src++);
copy_to_user(buf, buffer, c) 

先得到了次设备号,然后又从数组里得到了一个结构体,如果这个结构体里有read函数的话,则调用read函数,如果没有则读取现存基址的数据,然后把数据拷贝到用户空间。

仔细比较下open和read,可以看到,里面有一个关键的结构体,这个结构体是从以次设备号为下标的数组registered_fb[]中取出来的。

可以看到,fbmen.c提供的是一个抽象的东西,最终都得依赖于registered_fb这个数组。那么,registered_fb这个数组在哪里被设置呢?是在register_framebuffer()中。

我们可以总结如何写一个LCD驱动程序:
1. 分配一个fb_info结构体: framebuffer_alloc
2. 设置
3. 注册: register_framebuffer
4. 硬件相关的操作

下面介绍一下硬件大致的原理。如下图:
这里写图片描述
可以把LCD人为是一个一个像素,每一行、每一列的数目都是固定的,在后面有一个电子枪打出颜色到屏幕上,每次打一个,然后向后移动。电子枪如何知道移动到下一个像素呢?显然是有一个时钟VCLK,每来一个时钟就向右移动一个像素,直到移动到一行的末尾。那如何换到下一行呢?自然是有一个水平方向的同步信号HSYNC,可以想像 出来,电子枪的路线是“Z字型”。到了最后一行的最后一个,如何跳回第一行第一个呢?通过垂直方向的同步信号VSYNC。颜色是从何而来的呢?LCD与LCD控制器之间有VD0~VD23(只用到一部分),颜色的RGB值就从控制器传到LCD。LCD还有一个颜色使能信号VDEN,只有在这个信号有效的时候颜色才会被打到屏幕上,否则电子枪只移动不喷色。那LCD控制器的颜色从何而来呢?自然是从显存(framebuffer)得到,所以我们应该在SDRAM里分配显存,还要把显存的地址告诉LCD控制器。

硬件操作的具体流程:
1.配置引脚用于LCD
2.根据LCD手册,设置LCD控制器
3.分配显存,并把显存的地址告诉LCD控制器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值