看了不少人写的LCD驱动解释,看之前很懵逼,看之后还是很懵逼。都是放一大堆内核代码,我当时就想吐槽,能写就写,写不明白放一大堆代码是啥意思。后来,实在没办法,只能去看内核代码,结果,真香,原来别人放一堆代码是有用的。就很邪门,翻翻内核源码,不用细究,看看大概的框架,突然就悟了,所以如果大家看完我这篇博客后还是不太明白,去翻翻源码吧!
前言
首先,LCD驱动,linux中本身就包含了,并不需要我们自己去编写,我们要做的只是根据自己的LCD改改参数即可。驱动具体是如何现实的呢?我认为主要分为两个部分,一个部分在“fbmem.c这个文件中,我们想想,如何用户需要自己去修改一些底层的配置,难道让他们去修改驱动么?显然是不能的,所以是不是得提供应用层的接口函数?这不还得是走一遍老套路,进行字符设备的注册。另一个部分就是真正的LCD驱动了 ,通过字符设备提供的接口函数可以修改真正的LCD驱动(NXP 官方编写的 Linux 下的 LCD 驱动mxsfb.c(当然这是不一定的,你也可以自己在写个驱动))”。
什么是Framebuffer设备
Framebuffer 是用一个视频输出设备从包含完整的帧数据的一个内存缓冲区中来驱动一个视频显
示设备。也就是说 Framebuffer 是一块内存保存着一帧的图像,向这块内存写入数据就相当于向
屏幕中写入数据,如果使用 32 位的数据来表示一个像素点(使用 BBP 表示),假设屏幕的显示
频分辨率为 1920x1080,那么 Framebuffer 所需要的内存为 1920x1080x32/8=8,294,400 字节约等于
7.9M。
简单来说 Framebuffer 把屏幕上的每个点映射成一段线性内存空间,程序可以简单的改变这段内
存的值来改变屏幕上某一点的颜色。
Framebuffer 子系统为用户空间操作显示设备提供了统一的接口,屏蔽了底层硬件之间的差异,用
户只需要操作一块内存缓冲区即可把需要的图像显示到 LCD 设备上
第一步注册字符设备类 ,创建设备类
在内核启动时,LCD驱动的第一步是,调用fbmem_init()
fbmem_init(void)
{
proc_create("fb", 0, NULL, &fb_proc_fops);
if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
printk("unable to get major %d for fb devs\n", FB_MAJOR);
fb_class = class_create(THIS_MODULE, "graphics");
if (IS_ERR(fb_class)) {
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
fb_class = NULL;
}
return 0;
}
#ifdef MODULE
module_init(fbmem_init);
好好瞅瞅,是不是很眼熟,这不就是我们平时写字符设备的入口函数么 ,看到这个,fb_fops没,显然它是显示设备提供通用的文件操作接口,代码如下:
static const struct file_operations fb_fops = {
.owner = THIS_MODULE,
.read = fb_read,
.write = fb_write,
.unlocked_ioctl = fb_ioctl