• 驱动程序开发: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 };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 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 };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 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 数据线先极性 */
    			};
    		};
    	};
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

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

    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
    
    • 1
    • 2

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

    echo hello linux > /dev/tty1
    
    • 1
  • 相关阅读:
    Linux脚本练习之script080-nginx日志分析之IP统计
    手机玻璃盖板为什么需要透光率检测
    数据要素与多元市场主体融合机制研究
    二叉搜索树、红黑树详解、红黑树高的应用、TreeMap的应用(图文详解)-Kotlin版本代码
    不只是负载均衡,活字格智能集群的架构与搭建方案
    代码最佳实践和指南(二)
    1524. 和为奇数的子数组数目
    企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图
    偏差与方差
    Redis6的IO多线程分析
  • 原文地址:https://blog.csdn.net/morecrazylove/article/details/126373726