Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长
三、LCD驱动程序编写
需要注意的地方:
①、 LCD 所使用的 IO 配置。
②、 LCD 屏幕节点修改,修改相应的属性值,换成我们所使用的 LCD 屏幕参数。
③、 LCD 背光节点信息修改,要根据实际所使用的背光 IO 来修改相应的设备节点信息。
1、LCD屏幕IO配置
NXP已经给写好了。
2、 LCD 屏幕参数节点信息修改
pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */
&pinctrl_lcdif_ctrl
&pinctrl_lcdif_reset>;
pinctrl-0 属性,LCD 所使用的 IO 信息,这里用到了 pinctrl_lcdif_dat、pinctrl_lcdif_ctrl
和 pinctrl_lcdif_reset 这三个 IO 相关的节点,pinctrl_lcdif_reset 是 LCD 复位 IO 信息节点,正点原子的 I.MX6U-ALPHA 开发板的 LCD 没有用到复位 IO,因此 pinctrl_lcdif_reset 可以删除掉。
display = <&display0>;
display 属性,指定 LCD 属性信息所在的子节点,这里为 display0。
9 display0: display { /* LCD 属性信息 */
10 bits-per-pixel = <16>; /* 一个像素占用几个 bit */
11 bus-width = <24>; /* 总线宽度 */
12
13 display-timings {
14 native-mode = <&timing0>; /* 时序信息 */
15 timing0: timing0 {
16 clock-frequency = <9200000>; /* LCD 像素时钟,单位 Hz */
17 hactive = <480>; /* LCD X 轴像素个数 */
18 vactive = <272>; /* LCD Y 轴像素个数 */
19 hfront-porch = <8>; /* LCD hfp 参数 */
20 hback-porch = <4>; /* LCD hbp 参数 */
21 hsync-len = <41>; /* LCD hspw 参数 */
22 vback-porch = <2>; /* LCD vbp 参数 */
23 vfront-porch = <4>; /* LCD vfp 参数 */
24 vsync-len = <10>; /* LCD vspw 参数 */
25
26 hsync-active = <0>; /* hsync 数据线极性 */
27 vsync-active = <0>; /* vsync 数据线极性 */
28 de-active = <1>; /* de 数据线极性 */
29 pixelclk-active = <0>; /* clk 数据线先极性 */
30 };
31 };
32 };
display0 子节点,描述 LCD 的参数信息, 第 10 行的 bits-per-pixel 属性用于指明一个像素占用的 bit 数,默认为 16bit将 LCD 配置为 RGB888 模式,因此一个像素点占用 24bit, bits-per-pixel 属性要改为 24。第 11 行的 bus-width 属性用于设置数据线宽度,因为要配置为 RGB888 模式,因此 bus-width 也要设置为 24。
第 13~30 行,这几行非常重要!因为这几行设置了 LCD 的时序参数信息, NXP 官方的 EVK
开发板使用了一个 4.3 寸的 480*272 屏幕,因此这里默认是按照 NXP 官方的那个屏幕参数设置
的。
pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */
&pinctrl_lcdif_ctrl>;
设置 LCD 屏幕所使用的 IO,删除掉原来的 pinctrl_lcdif_reset,因为没有用到屏
幕复位 IO,其他的 IO 不变。
bits-per-pixel = <24>; /* 一个像素占用 24bit */
使用 RGB888 模式,所以一个像素点是 24bit。
15 clock-frequency = <51200000>;/* LCD 像素时钟,单位 Hz */
16 hactive = <1024>; /* LCD X 轴像素个数 */
17 vactive = <600>; /* LCD Y 轴像素个数 */
18 hfront-porch = <160>; /* LCD hfp 参数 */
19 hback-porch = <140>; /* LCD hbp 参数 */
20 hsync-len = <20>; /* LCD hspw 参数 */
21 vback-porch = <20>; /* LCD vbp 参数 */
22 vfront-porch = <12>; /* LCD vfp 参数 */
23 vsync-len = <3>; /* LCD vspw 参数 */
ATK7016 屏幕时序参数,根据自己所使用的屏幕修改即可。
3、屏幕背光节点信息
GPIO1_IO08 这个 IO 的配置:
1 pinctrl_pwm1: pwm1grp {
2 fsl,pins = <
3 MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
4 >;
5 };
pinctrl_pwm1 节点就是 GPIO1_IO08 的配置节点,从第 3 行可以看出,设置 GPIO1_IO08
这个 IO 复用为 PWM1_OUT,并且设置电气属性值为 0x110b0。
设置 PWM1 节点:
1 pwm1: pwm@02080000 {
2 compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
3 reg = <0x02080000 0x4000>;
4 interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
5 clocks = <&clks IMX6UL_CLK_PWM1>,
6 <&clks IMX6UL_CLK_PWM1>;
7 clock-names = "ipg", "per";
8 #pwm-cells = <2>;
9 };
1 &pwm1 {
2 pinctrl-names = "default";
3 pinctrl-0 = <&pinctrl_pwm1>;
4 status = "okay";
5 };
设置 pwm1 所使用的 IO 为 pinctrl_pwm1
将 status 设置为 okay。
backlight节点的创建:
①、节点名称要为“ backlight”。
②、节点的 compatible 属性值要为“ pwm-backlight”。
③、pwms属性用于描述背光所使用的 PWM以及 PWM频率,比如本章我们要使用的 pwm1,
pwm 频率设置为 5KHz(NXP 官方推荐设置)。
④、 brightness-levels 属性描述亮度级别,范围为 0~255, 0 表示 PWM 占空比为 0%,也就
是亮度最低, 255 表示 100%占空比,也就是亮度最高。
⑤、 default-brightness-level 属性为默认亮度级别。
1 backlight {
2 compatible = "pwm-backlight";
3 pwms = <&pwm1 0 5000000>;//PWM 频率为 5KHz。
4 brightness-levels = <0 4 8 16 32 64 128 255>;//设置背 8 级背光(0~7)
5 default-brightness-level = <6>;//设置默认背光等级为 6
6 status = "okay";
7 };
四、运行测试
1、LCD屏幕基本测试
1)、编译新的设备树
make dtbs
等待编译生成新的 imx6ull-alientek-emmc.dtb 设备树文件。
2)、使能Linux logo显示
-> Device Drivers
-> Graphics support
-> Bootup logo (LOGO [=y])
-> Standard black and white Linux logo
-> Standard 16-color Linux logo
-> Standard 224-color Linux logo
2、设置LCD作为终端控制台
1)、设置uboot中的bootargs
2)、修改/etc/inittab文件
打开开发板根文件系统中的/etc/inittab 文件,在里面加入下面这一行:
tty1::askfirst:-/bin/sh
修改完成以后保存/etc/inittab 并退出,然后重启开发板,重启以后开发板 LCD 屏幕最后一
行会显示下面一行语句:Please press Enter to activate this console.
可以通过下面这一行命令向LCD 屏幕输出“ hello linux!”
echo hello linux > /dev/tty1
3、LCD背光调节
设置背光等级来实现 LCD 背光亮度的调节:
进入目录/sys/devices/platform/backlight/backlight/backlight
brightness 表示当前亮度等级, max_bgigntness 表示最大亮度等级。
如果要修改屏幕亮度,只需要向 brightness 写入需要设置的屏幕亮度等级即可。比如设置屏幕亮度等级为 7,那么可以使用如下命令:
echo 7 > brightness
输入上述命令以后就会发现屏幕亮度增大了,如果设置 brightness 为 0 的话就会关闭 LCD
背光,屏幕就会熄灭。
4、LCD自动关闭解决方法
1)、按键盘唤醒
2)、关闭10分钟熄屏功能
static int blankinterval = 10*60;
3)、编写APP关闭熄屏功能
1 #include <fcntl.h>
2 #include <stdio.h>
3 #include <sys/ioctl.h>
4
5
6 int main(int argc, char *argv[])
7 {
8 int fd;
9 fd = open("/dev/tty1", O_RDWR);
10 write(fd, "\033[9;0]", 8);
11 close(fd);
12 return 0;
13 }
使用如下命令编译 lcd_always_on.c 这个文件:
arm-linux-gnueabihf-gcc lcd_always_on.c -o lcd_always_on
编译生成 lcd_always_on 以后将此可执行文件拷贝到开发板根文件系统的/usr/bin 目录中,
然后给予可执行权限。设置 lcd_always_on 这个软件为开机自启动,打开/etc/init.d/rcS,在此文
件最后面加入如下内容:
1 cd /usr/bin
2 ./lcd_always_on
3 cd ..
修改完成以后保存/etc/init.d/rcS 文件,然后重启开发板即可。
五、总结
本节笔记主要学习Linux LCD驱动试验,主要内容包括LCD驱动简析、硬件原理图分析、驱动程序编写及运行测试。其中驱动程序的编写以及运行测试作为本节的重点内容。
本文为参考正点原子开发板配套教程整理而得,仅用于学习交流使用,不得用于商业用途。