Linuz之LCD驱动

目录

一、Framebuffer 设备

二、修改LCD设备树

1.LCD 屏幕 IO 配置 

2.LCD 屏幕参数节点信息修改

3.LCD 屏幕背光节点信息

三、LCD相关配置

1.内核-Logo配置

2.LCD终端控制台显示

3.LCD背光调节

4.LCD自动关闭解决方法


一、Framebuffer 设备

Framebuffer(帧缓冲):简称帧缓存或显存,它是屏幕所显示画面的一个直接映象,又称为位映射图(Bit Map)或光栅。帧缓存的每一存储单元对应屏幕上的一个像素,整个帧缓存对应一帧图像

Framebuffer是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,它允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer设备驱动来完成的。

帧缓存可以在系统存储器(内存)的任意位置,视频控制器通过访问帧缓存来刷新屏幕。 帧缓存也叫刷新缓存 Frame buffer 或 refresh buffer, 这里的帧(frame)是指整个屏幕范围。

 帧缓存有个地址,是在内存里。通过不停的向frame buffer中写入数据, 显示控制器就自动的从frame buffer中取数据并显示出来。全部的图形都共享内存中同一个帧缓存。

CPU指定显示控制器工作,则显示控制器根据CPU的控制到指定的地方去取数据和指令, 目前的数据一般是从显存里取,如果显存里存不下,则从内存里取, 内存也放不下,则从硬盘里取,当然也不是内存放不下,而是为了节省内存的话,可以放在硬盘里,然后通过指令控制显示控制器去取。帧缓存 Frame Buffer,里面存储的东西是一帧一帧的, 显卡会不停的刷新Frame Buffer, 这每一帧如果不捕获的话, 则会被丢弃,也就是说是实时的。这每一帧不管是保存在内存还是显存里,都是一个显性的信息,这每一帧假设是800x600的分辨率, 则保存的是800x600个像素点和颜色值。

Framebuffer(帧缓冲),其内容对应于屏幕上的界面显示,可以将其简单理解为屏幕上显示内容对应的缓存,修改Framebuffer中的内容,即表示修改屏幕上的内容,所以,直接操作Framebuffer可以直接从显示器上观察到效果。

 Framebuffer简称 fb,fb 是一种机制,将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一个 fb 设备,当编写好 LCD 驱动以后会生成一个名为/dev/fbX(X=0~n)的设备,应用程序通过访问/dev/fbX 这个设备就可以访问 LCD。NXP 官方的 Linux 内核默认已经开启了 LCD 驱动,因此在dev目录下可以看到/dev/fb0设备。

 /dev/fb0 是 LCD 对应的设备文件, /dev/fb0 是个字符设备。相关字符设备驱动一般原厂已经在内核中写好了。

二、修改LCD设备树

6ULL eLCDIF接口驱动程序NXP已经编写好了,因此LCD驱动部分不需要去修改。只需要做的就是按照所使用的 LCD 来修改设备树。

① LCD 所使用的 IO 配置
② LCD 屏幕节点修改,修改相应的属性值,换成所使用的 LCD 屏幕参数
③LCD 背光节点信息修改,要根据实际所使用的背光 IO 来修改相应的设备节点信息

1.LCD 屏幕 IO 配置 


pinctrl_lcdif_dat: lcdifdatgrp {
    fsl,pins = <
        MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x49
        .....
        MX6UL_PAD_LCD_DATA23__LCDIF_DATA23  0x49
    >;
};

pinctrl_lcdif_ctrl: lcdifctrlgrp {
    fsl,pins = <
        MX6UL_PAD_LCD_CLK__LCDIF_CLK	    0x79
        MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x79
        MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x79
        MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x79
    >;
};

pinctrl_pwm1: pwm1grp {
    fsl,pins = <
        MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
    >;
};

子节点 pinctrl_lcdif_dat,为 RGB LCD 的 24 根数据线配置项。

子节点 pinctrl_lcdif_ctrl, RGB LCD 的 4 根控制线配置项,包括 CLK、ENABLE、 VSYNC 和 HSYNC。

子节点 pinctrl_pwm1, LCD 背光 PWM 引脚配置项。

默认LCD 的电气属性都设置为 0X79,这里将其都改为 0X49,将 LCD 相关 IO 的驱动能力改为 R0/1,降低 LCD 相关 IO 的驱动能力。

正点原子的 ALPHA 开发板上的 LCD 接口用了三个 SGM3157 模拟开关,为了防止模拟开关影响到网络,因此这里需要降低 LCD 数据线的驱动能力,如果所使用的板子没有用到模拟开关那么就不需要将 0X79 改为 0X49。

2.LCD 屏幕参数节点信息修改

&lcdif {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lcdif_dat             //使用到的 IO
		     &pinctrl_lcdif_ctrl>;

	display = <&display0>; 
	status = "okay"; 

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

		display-timings {                      //时序信息
			native-  = <&timing0>;
			timing0: timing0 {
			clock-frequency = <51200000>;      //LCD 像素时钟,单位 Hz 
			hactive = <1024>;                  //LCD X 轴像素个数
			vactive = <600>;                   //LCD Y 轴像素个数
			hfront-porch = <160>;              //LCD hfp 参数
			hback-porch = <140>;               //LCD hbp 参数 
			hsync-len = <20>;                  //LCD hspw 参数
			vback-porch = <20>;                //LCD vbp 参数
			vfront-porch = <12>;               //LCD vfp 参数
			vsync-len = <3>;                   //LCD vspw 参数

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

pinctrl-0 属性, LCD 所使用的 IO 信息,这里用到了 pinctrl_lcdif_dat、pinctrl_lcdif_ctrl和 pinctrl_lcdif_reset 这三个 IO 相关的节点

display 属性,指定 LCD 属性信息所在的子节点,这里为 display0,下面就是 display0子节点内容
 

display0 子节点,描述 LCD 的参数信息,bits-per-pixel 属性用于指明一个像素占用的 bit 数,默认为 16bit。这里将 LCD 配置为 RGB888 模式,因此一个像素点占用 24bit, bits-per-pixel 属性要改为 24。 bus-width 属性用于设置数据线宽度,因为要配置为 RGB888 模式,所以bus-width 要设置为 24。

display-timings设置了 LCD 的时序参数信息,这些时序参数就是要修改的,需要根据自己所使用的屏幕去修改。ALIENTEK 7寸RGB LCD屏幕的参数所示:

 3.LCD 屏幕背光节点信息

pinctrl_pwm1: pwm1grp {
			fsl,pins = <
				MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
			>;
		};

正点原子的 LCD 接口背光控制 IO 连接到了 I.MX6U 的 GPIO1_IO08 引脚上, GPIO1_IO08复用为 PWM1_OUT,通过 PWM 信号来控制 LCD 屏幕背光的亮度。正点原子 I.MX6U-ALPHA 开发板的 LCD 背光引脚和 NXP 官方 EVK 开发板的背光引脚一样,因此背光的设备树节点是不需要修改的。

pinctrl_pwm1 节点是 GPIO1_IO08 的配置节点,设置 GPIO1_IO08这个 IO 复用为 PWM1_OUT,并且设置电气属性值为 0x110b0。

LCD 背光要用到 PWM1,因此要设置 PWM1 节点。在 imx6ull.dtsi 文件中pwm1节点

pwm1: pwm@02080000 {
    compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
    reg = <0x02080000 0x4000>;
    interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clks IMX6UL_CLK_PWM1>,
    <&clks IMX6UL_CLK_PWM1>;
    clock-names = "ipg", "per";
    #pwm-cells = <2>;
};

在imx6ull-alientek-emmc.dts 文件中找到向 pwm1追加的内容,

&pwm1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_pwm1>;
    status = "okay";
};

设置 pwm1 所使用的 IO 为 pinctrl_pwm1。

pwm 和相关的 IO已经配置好了,但是 Linux 系统怎么知道PWM1_OUT是控制 LCD 背光的呢?因此还需要一个节点来将 LCD 背光和 PWM1_OUT连 接 起 来 。 这 个 节 点 就 是 backlight ,该节 点 描 述 可 以 参 考Documentation/devicetree/indings/video/backlight/pwm-backlight.txt。

backlight节点要求:

①节点名称要为backlight

②节点的 compatible 属性值要为pwm-backlight

③pwms属性用于描述背光所使用的PWM以及PWM频率
④brightness-levels 属性描述亮度级别,范围为 0~255, 0 表示 PWM 占空比为 0%,亮度最低, 255 表示 100%占空比,亮度最高

⑤default-brightness-level 属性为默认亮度级别

backlight {
    compatible = "pwm-backlight";
    pwms = <&pwm1 0 5000000>;
    brightness-levels = <0 4 8 16 32 64 128 255>;
    default-brightness-level = <6>;
    status = "okay";
};

三、LCD相关配置

1.内核-Logo配置

Linux 内核启动的时可以选择显示小企鹅 logo,只要这个小企鹅 logo 显示正常,那么LCD 驱动基本就工作正常。logo 显示是要配置的。

使用make menuconfig打开 Linux内核图形化配置界面,按下路径找到对应的配置项:

-> Device Drivers

    -> Graphics support

        -> Bootup logo (LOGO [=y])

            -> Standard black and white Linux logo

                -> Standard 16-color Linux logo

                    -> Standard 224-color Linux logo


 

这三个选项分别对应黑白、 16 位、 24 位色彩格式的 logo,把这三个都选中,都编译进 Linux 内核里面。设置好以后保存退出,重新编译 Linux 内核(直接make),编译完成以后使用编译出来的 dtb 和 zImage 镜像启动系统,如果 LCD 驱动工作正常会在 LCD 屏幕左上角出现一个彩色的小企鹅 logo,屏幕背景色为黑色。

如图所示:

2.LCD终端控制台显示

可以将LCD设置为开发板的终端,LCD 和串口都会显示 Linux 启动 log 信息,然后直接使用鼠标、键盘在开发板上操作命令了。

设置 uboot 中的 bootargs

重启开发板,进入 Linux 命令行,重新设置 bootargs 参数的 console 内容

setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.137.100:/home/xiaochao/Linux/nfs/rootfs,v3,proto=tcp rw ip=192.168.137.50:192.168.137.100:192.168.137.1:255.255.255.0::eth0:off

这里设置两次console,第一次设置 console=tty1,设置 LCD 屏幕为控制台第二遍设置console=ttymxc0,115200,设置串口作为控制台。相当于打开了两个 console,一个是 LCD,一个是串口。

②修改/etc/inittab 文件
打开开发板根文件系统中的/etc/inittab 文件,在里面加入下面这一行:

tty1::askfirst:-/bin/sh     # 打开tty1,设置LCD作为终端

修改完成以后保存/etc/inittab 并退出,然后重启开发板,LCD 屏幕最后一行会显示下面一行语句:

Please press Enter to activate this console.

按下回车键使能当前终端,所以按下回车键就可以使用LCD作为终端。

向LCD 屏幕输出内容:

echo hello linux > /dev/tty1

LCD 屏幕就会输出hello linux。

3.LCD背光调节

背光设备树节点设置了 8 个等级的背光调节,可以设置为 0~7,可以通过设置背光等级来实现LCD 背光亮度的调节。

进入/sys/devices/platform/backlight/backlight/backlight目录

brightness 表示当前亮度等级, max_bgigntness 表示最大亮度等级。


 设置屏幕亮度等级为 5,可以使用如下命令:

echo 5 > brightness

输入命令后屏幕亮度变暗了,如果设置 brightness 为 0 的话就会关闭 LCD背光,屏幕就会熄灭。

4.LCD自动关闭解决方法

默认情况下 10 分钟以后 LCD 就会熄屏,这是Linux 内核设置的,一段时间不操作的话屏幕就会熄灭,以节省电能。

①按键盘唤醒

若开发板上有按键,将这个按键注册为回车键,按下回车键唤醒屏幕。如果开发板上没有按键的话可以外接 USB 键盘,然后按下 USB 键盘上的回车键唤醒屏幕。

②关闭 10 分钟熄屏功能
在 Linux 源码中找到 drivers/tty/vt/vt.c 文件,在此文件中找到 blankinterval 变量

static int vesa_blank_mode;
static int vesa_off_interval;
static int blankinterval = 10*60;

blankinterval 变量控制着 LCD 关闭时间,默认是 10*60,即10 分钟。将 blankinterval的值改为 0 即可关闭 10 分钟熄屏的功能,修改完成以后需要重新编译 Linux 内核,得到新的zImage,然后用新的 zImage 启动开发板。

③编写APP 来关闭熄屏功能

源文件如下

#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>

int main(int argc, char *argv[])
{
    int fd;
    fd = open("/dev/tty1", O_RDWR);
    write(fd, "\033[9;0]", 8);
    close(fd);
    return 0;
}

交叉编译生成可执行程序,将此可执行文件拷贝到开发板根文件系统的/usr/bin 目录中,然后给予可执行权限。设置这个软件为开机自启动打开/etc/init.d/rcS,在此文件最后面加入如下内容

cd /usr/bin
./lcd_always_on
cd ..

保存/etc/init.d/rcS 文件,然后重启开发板即可。
 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Super.Bear

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

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

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

打赏作者

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

抵扣说明:

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

余额充值