驱动程序开发:LCD屏显示驱动

1、简介

  在 Linux 中应用程序最终也是通过操作 RGB LCD 的显存来实现在 LCD 上显示字符、图片等信息。在裸机中我们可以随意的分配显存,但是在 Linux 系统中内存的管理很严格,显存是需要申请的,不是你想用就能用的。而且因为虚拟内存的存在,驱动程序设置的显存和应用程序访问的显存要是同一片物理内存。
  为了解决上述问题, Framebuffer 诞生了, Framebuffer 翻译过来就是帧缓冲,简称 fb,因此大家在以后的 Linux 学习中见“Framebuffer”或者“fb”的话第一反应应该想到 RGBLCD或者显示设备。 fb 是一种机制,将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一个 fb 设备,当我们编写好 LCD 驱动以后会生成一个名为/dev/fbX(X=0~n)的设备,应用程序通过访问/dev/fbX 这个设备就可以访问 LCD。
  具体的fb驱动程序处理比较复杂,这里主要记录怎么使用官方提供的fb驱动程序去驱动对应的LCD屏。

2、LCD驱动分析

  打开到imx6ull.dtsi->lcdif节点内容,如下:

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: lcdif@021c8000解释:“:”前面的label是为了方便引用而起的别名,而“:”后面的label才是真正的节点名称,而这个真正的节点名称常常会伴随“&label”节点的引用(所谓的节点的引用是指在引用这个节点并在这个节点增加新的属性)。“@021c8000”表示设备的地址。

  在以上程序中可以查看到lcdif 节点的compatible 属性值为“fsl,imx6ul-lcdif”和“fsl,imx28-lcdif”,因此可以确定到LCD 驱动文件为drivers/video/fbdev/mxsfb.c,这个驱动程序是有一个典型的platform驱动架构,自行查看源程序分析。

3、LCD驱动程序编写

①LCD屏幕的IO配置,在imx6ull-alientek-emmc.dts 设备树文件下的iomuxc节点中找到如下内容:

1 pinctrl_lcdif_dat: lcdifdatgrp {
2 fsl,pins = <
3 MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
4 MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
5 MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
6 MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
7 MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
8 MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
9 MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
10 MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
11 MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
12 MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
13 MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
14 MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
15 MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
16 MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
17 MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
18 MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
19 MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
20 MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
21 MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
22 MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
23 MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
24 MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
25 MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
26 MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
27 >;
28 };
29
30 pinctrl_lcdif_ctrl: lcdifctrlgrp {
31 fsl,pins = <
32 MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
33 MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
34 MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
35 MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
36 >;
37 pinctrl_pwm1: pwm1grp {
38 fsl,pins = <
39 MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
40 >;
41 };

  第 2~27 行,子节点 pinctrl_lcdif_dat,为 RGB LCD 的 24 根数据线配置项。
  第 30~36 行,子节点 pinctrl_lcdif_ctrl, RGB LCD 的 4 根控制线配置项,包括 CLK、ENABLE、 VSYNC 和 HSYNC。
  第 37~40 行,子节点 pinctrl_pwm1, LCD 背光 PWM 引脚配置项。这个引脚要根据实际情况设置,这里我们建议大家在以后的学习或工作中, LCD 的背光 IO 尽量和半导体厂商的官方开发板一致。

② LCD 屏幕参数节点信息修改

&lcdif {
	pinctrl-names = "default";	/* default : 对应的引脚是pinctrl-0 ,他指定了group是<...> */
	pinctrl-0 = <&pinctrl_lcdif_dat
		     &pinctrl_lcdif_ctrl
		     &pinctrl_lcdif_reset>;	/* 使用到的IO */
	display = <&display0>;
	status = "okay";				/* 使能状态 */

	display0: display {				/* LCD属性信息 */
		bits-per-pixel = <32>;		/* 一个像素点占几个bit */
		bus-width = <24>;			/* 总线宽度 */

		display-timings {
			native-mode = <&timing0>;		/* 时序信息 */
			timing0: timing0 {
			clock-frequency = <51200000>;	/* LCD像素时钟,单位Hz */
			hactive = <1024>;				/* LCD X轴像素个数 */
			vactive = <600>;				/* LCD Y轴像素个数 */
			hfront-porch = <160>;			/* 行同步信号前肩 */
			hback-porch = <140>;			/* 行同步信号后肩 */
			hsync-len = <20>;				/* 行同步信号长度 */
			vback-porch = <20>;				/* 列同步信号后肩 */
			vfront-porch = <12>;			/* 列同步信号前肩 */
			vsync-len = <3>;				/* 列同步信号长度 */

			hsync-active = <0>;				/* hsync 数据线极性 */
			vsync-active = <0>;				/* vsync 数据线极性 */
			de-active = <1>;				/*  de 数据线极性 */
			pixelclk-active = <0>;			/* clk 数据线先极性 */
			};
		};
	};
};

以下是我的屏幕参数:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  此时,编译设备树,重新加载设备树即可看到开机有小企鹅的画面了。
在这里插入图片描述

4、设置 LCD 作为终端控制台

 #emsp;我们一直使用SecureCRT作为Linux开发板终端,开发板通过串口和SecureCRT进行通信。现在我们已经驱动起来 LCD 了,所以可以设置 LCD 作为终端,也就是开发板使用自己的显示设备作为自己的终端,然后接上键盘就可以直接在开发板上敲命令了,将 LCD 设置为终端控制台的方法如下:
①设置 uboot 中的 bootargs

1 setenv bootargs 'console=tty1 console=ttymxc0,115200 rw root=/dev/nfs nfsroot=192.168.1.111:/home/djw  /linux/nfs/rootfs ip=192.168.1.119:192.168.1.111:192.168.1.1:255.255.255.0::eth0:off'
2 saveenv

console=tty1是设置 LCD 屏幕为控制台.
②修改/etc/inittab 文件
在这里插入图片描述
测试->通过下面这一行命令向LCD 屏幕输出“hello linux!”

echo hello linux > /dev/tty1
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邓家文007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值