文章目录
1 framebuffer设备
LCD是Liquid Crystal Display的简称,也就是经常所说的液晶显示器。LCD能够支持彩色图像的显示和视频的播放,是一种非常重要的输出设备。如果我们的系统要用GUI(图形界面接口),这时LCD设备驱动程序就应该编写成frambuffer接口,而不是编写成仅仅操作底层的LCD控制器接口。
framebuffer是Linux系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行操作。framebuffer又叫帧缓冲,是Linux为操作显示设备提供的一个用户接口。用户应用程序可以通过framebuffer透明地访问不同类型的显示设备。从这个方面来说,framebuffer是硬件设备显示缓冲区的抽象。Linux抽象出framebuffer这个帧缓冲区可以供用户应用程序直接读写,通过更改framebuffer中的内容,就可以立刻显示在LCD显示屏上。
framebuffer是一个标准的字符设备,主设备号是29,次设备号根据缓冲区的数目而定。framebuffer对应/dev/fbn设备文件。根据显卡的多少,设备文件可能是/dev/fb0、/dev/fb1等。缓冲区设备也是一种普通的内存设备,可以直接对其进行读写。对用户程序而言,它和/dev下面的其他设备没有什么区别,用户可以把frameBuffer看成一块内存,既可以写,又可以读。显示器将根据内存数据显示对应的图像界面。这一切都由LCD控制器和响应的驱动程序来完成。NXP 官方的 Linux 内核默认已经开启了 LCD 驱动,因此我们是可以看到/dev/fb0 这样一个设备,如图 1.1所示:
上图中的/dev/fb0文件对应的就是LCD设备,,/dev/fb0 是个字符设备,因此肯定有 file_operations 操作集,fb 的 file_operations 操作集定义在 drivers/video/fbdev/core/fbmem.c 文件中,如下所示:
1495 static const struct file_operations fb_fops = {
1496 .owner = THIS_MODULE,
1497 .read = fb_read,
1498 .write = fb_write,
1499 .unlocked_ioctl = fb_ioctl,
1500 #ifdef CONFIG_COMPAT
1501 .compat_ioctl = fb_compat_ioctl,
1502 #endif
1503 .mmap = fb_mmap,
1504 .open = fb_open,
1505 .release = fb_release,
1506 #ifdef HAVE_ARCH_FB_UNMAPPED_AREA
1507 .get_unmapped_area = get_fb_unmapped_area,
1508 #endif
1509 #ifdef CONFIG_FB_DEFERRED_IO
1510 .fsync = fb_deferred_io_fsync,
1511 #endif
1512 .llseek = default_llseek,
1513 };
对于fb的详细处理过程,我们就不去深入了解了,我们的主要任务是驱动开发板上的LCD设备。
2 LCD驱动解析
既然LCD是一个外部设备,那么如果要使用LCD设备,就需要在设备树中添加LCD的相关设备节点。在NXP官方的设备树中已经有LCD设备的设备节点了,但是不适合我们开发板上的LCD设备,需要修改其中的参数来让我们开发板上的LCD设备正常工作。
首先打开imx6ull.dtsi文件,看一下有哪些和LCD相关的设备节点:
1 lcdif: lcdif@021c8000 {
2 compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
3 reg = <0x021c8000 0x4000>;
4 interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
5 clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
6 <&clks IMX6UL_CLK_LCDIF_APB>,
7 <&clks IMX6UL_CLK_DUMMY>;
8 clock-names = "pix", "axi", "disp_axi";
9 status = "disabled";
10 };
lcdif节点在imx6ull.dtsi文件中,所有包含imx6ull.dtsi文件的开发板都有会用到这个节点,lcdif节点只是包含了一些相同的参数,不同的LCD设备会有一些不同的参数,需要在自己的设备树文件中去添加,比如在topeet_emmc_4_3.dts设备树文件中会引用lcdif节点添加其他属性信息。
在lcdif节点中的compatible属性值为“fsl,imx6ul-lcdif”和“fsl,imx28-lcdif”,然后根据这两个compatible属性值可以在内核源码中找到LCD驱动文件,找到的文件为drivers/video/fbdev/mxsfb.c,mxsfb.c就是 I.MX6ULL 的 LCD 驱动文件,在此文件中有如下内容:
1362 static const struct of_device_id mxsfb_dt_ids[] = {
1363 {
.compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], },
1364 {
.compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1