Linux-LCD 驅動
- ■ Framebuffer 簡稱 fb
- ■ LCD 驅動程序編寫
- ■ 1、LCD 屏幕 IO 配置
- ■ 2、LCD 屏幕參數節點信息修改
- ■ 3、LCD 屏幕背光節點信息
- ■ 4、使能 Linux logo 顯示
- ■ 設置 LCD 作為終端控制臺
- ■ 1、設置 uboot 中的 bootargs
- ■ 2、修改/etc/inittab 文件
- ■ LCD 背光調節
- ■ LCD 自動關閉解決方法
- ■ 1、按鍵盤喚醒
- ■ 2、關閉 10 分鐘熄屏功能
■ Framebuffer 簡稱 fb
fb 是一種機制,將系統中所有跟顯示有關的硬件以及軟件集合起來,虛擬出一個 fb 設備,
當我們編寫好 LCD 驅動以后會生成一個名為/dev/fbX(X=0~n)的設備,應用程序通過訪問/dev/fbX 這個設備就可以訪問 LCD.
因此我們是可以看到/dev/fb0 這樣一個設備
/dev/fb0 是個字符設備.因此肯定有file_operations 操作集
Linux 內核將所有的 Framebuffer 抽象為一個叫做 fb_info 的結構體, fb_info 結構體包含了 Framebuffer 設備的完整屬性和操作集合,
fb_info 結構體定義在 include/linux/fb.h 文件里面
fb_info 結構體的成員變量很多,我們重點關注 var、 fix、 fbops、 screen_base、 screen_size和 pseudo_palette。 mxsfb_probe 函數
■ LCD 驅動程序編寫
■ 1、LCD 屏幕 IO 配置
// 修改dts 文件 24 根數據線配置項。
pinctrl_lcdif_dat: lcdifdatgrp { fsl,pins = <MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 電氣屬性都設置為 0X79 0X49 驅動能力改為 R0/1MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79>;
}; // 4 根控制線配置項,包括 CLK、ENABLE、 VSYNC 和 HSYNC
pinctrl_lcdif_ctrl: lcdifctrlgrp {fsl,pins = <MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79>;
};pinctrl_pwm1: pwm1grp {fsl,pins = <MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0>;
};
■ 2、LCD 屏幕參數節點信息修改
&lcdif {pinctrl-names = "default";pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */&pinctrl_lcdif_ctrl// &pinctrl_lcdif_reset>; 刪除掉原來的 pinctrl_lcdif_reset,因為沒有用到屏幕復位 IO,display = <&display0>;status = "okay";display0: display { /* LCD 屬性信息 */bits-per-pixel = <24>; /* 一個像素占用 24bit */bus-width = <24>; /* 總線寬度 */display-timings {native-mode = <&timing0>; /* 時序信息 */timing0: timing0 {clock-frequency = <9200000>; /* 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 數據線先極性 */};};};
};
■ 3、LCD 屏幕背光節點信息
LCD 接口背光控制 IO 連接到了 I.MX6U 的 GPIO1_IO08 引腳上, GPIO1_IO08 復用為 PWM1_OUT,通過 PWM 信號來控制 LCD 屏幕背光的亮度
backlight {compatible = "pwm-backlight";pwms = <&pwm1 0 5000000>; 設置背光使用pwm1, PWM 頻率為 200Hz。brightness-levels = <0 4 8 16 32 64 128 255>; 設置背 8 級背光(0~7), 對應占空比為0%、 1.57%、 3.13%、 6.27%、 12.55%、 25.1%、 50.19%、 100%,default-brightness-level = <6>; 設置默認背光等級為 6,也就是 50.19%的亮度status = "okay";
};&pwm1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_pwm1>;status = "okay";
};在&iomuxc {pinctrl-names = "default";pinctrl-0 = <&pinctrl_hog_1>;imx6ul-evk { 節點下面添加pinctrl_pwm1: pwm1grp {fsl,pins = <MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0>;};
■ 4、使能 Linux logo 顯示
Linux 內核一般都會默認,開啟 小企鵝 logo 顯示如何使能 Linux 小企鵝 logo 顯示
三個選項分別對應黑白、 16 位、 24 位色彩格式的 logo。
■ 設置 LCD 作為終端控制臺
■ 1、設置 uboot 中的 bootargs
setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.1.250:
/home/zuozhongkai/linux/nfs/rootfs ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:off
console=tty1 console=ttymxc0,115200
第一次設置 console=tty1,也就是設置 LCD 屏幕為控制臺,第二遍又設置 console=ttymxc0,115200,也就是設置串口也作為控制臺。
相當于我們打開了兩個 console,一個是 LCD,一個是串口,大家重啟開發板就會發現 LCD 和串口都會顯示 Linux 啟動 log 信息。
■ 2、修改/etc/inittab 文件
打開開發板根文件系統中的/etc/inittab 文件,在里面加入下面這一行:
tty1::askfirst:-/bin/sh
重啟以后開發板 LCD 屏幕最后一行會顯示下面一行語句:Please press Enter to activate this console 按下回車鍵使能當前終端
我們可以通過下面這一行命令向LCD 屏幕輸出“hello linux!”
echo hello linux > /dev/tty1
至此,我們就擁有了兩套終端,一個是基于串口的 SecureCRT,一個就是我們開發板的 LCD屏幕,但是為了方便調試,我們以后還是以 SecureCRT 為主。
■ LCD 背光調節
背光設備樹節點設置了 8 個等級的背光調節,可以設置為 0~7,我們可以通過設置背光等級來實現 LCD 背光亮度的調節
/sys/devices/platform/backlight/backlight/backlight
brightness 表示當前亮度等級, max_bgigntness 表示最大亮度等級。
比如設置屏幕亮度等級為 7,那么可以使用如下命令: echo 7 > brightness
■ LCD 自動關閉解決方法
默認情況下 10 分鐘以后 LCD 就會熄屏,這個并不是代碼有問題,而是 Linux 內核設置的,就和我們用手機或者電腦一樣,一段時間不操作的話屏幕就會熄滅,以節省電能。
■ 1、按鍵盤喚醒
開發板上的 KEY按鍵注冊為了回車鍵,因此按下開發板上的 KEY 按鍵即可喚醒屏幕。如果開發板上沒有按鍵的話可以外接 USB 鍵盤,然后按下 USB 鍵盤上的回車鍵喚醒屏幕。
■ 2、關閉 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 分鐘熄屏的功能,