嵌入式Linux fbtft(SPI TFT屏)驱动移植及调试

    技术2022-07-20  73

    一、概述

    项目涉及到kernel配置、DTB设备树、fbtft屏驱动修改移植,驱动模块自动加载、屏幕调试。

    二、准备工作

    1、64bit Linux系统,我用的是VMware+ubuntu 16.4 。

    2、嵌入式开发板,我用的是NanoPi-NEO,全志H3芯片,256M RAM。

    3、TFT屏一块,我用的是ST7735S,128X128分辨率。

    4、网线一根、数据线一根,5V 2A电源一个(一定要2A以上)。

    三、开始干活

    1、搭建开发环境

    开发环境的搭建、BSP包下载及编译参照全志H2/H3 Linux Mainline介绍及下载,需要关心的是,全志原厂BSP和Linux Mainline的区别,全志BSP没有涉及到设备树,而Linux Mainline不仅用到了设备树,而且在uboot配置都采用类似kernel那样的图形界面,之前用全志原厂BSP,资料比较少,走了很多弯路,所以现在使用的是Linux Mainline。

    2、修改设备树文件

    在linux/arch/arm/boot/dts目录下,目录中有很多dts文件和dtsi文件,找到sun8i-h3-nanopi.dtsi,由于nanopi 引出了spi0的引脚,所以我们在spi0节点下添加 fbtft相关代码(matrix: matrix@0),同时disable其他spi0设备:

    &spi0 { /* needed to avoid dtc warning */ #address-cells = <1>; #size-cells = <0>; status = "okay"; pinctrl-names = "default"; //pinctrl-0 = <&spi0_pins &spi0_cs_pins>; pinctrl-0 = <&spi0_pins &spi0_cs_pins>;//<&spi0_pins &spi0_cs_pins> cs-gpios = <&pio 6 9 GPIO_ACTIVE_HIGH>;//<&pio 2 3 GPIO_ACTIVE_HIGH>, <&pio 0 6 GPIO_ACTIVE_HIGH>; spidev0: spi@0 { compatible = "nanopi,spidev"; reg = <0>; status = "disabled"; spi-max-frequency = <10000000>; }; matrix: matrix@0{ compatible = "fa,st7735s"; reg = <0>; status = "okay"; spi-max-frequency = <32000000>; fps = <33>; rotate = <90>; buswidth = <8>; dc-gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>; /* PA17 */ reset-gpios = <&pio 0 3 GPIO_ACTIVE_HIGH>; /* PA3 */ led-gpios = <&pio 0 1 GPIO_ACTIVE_HIGH>; /* PA1 */ debug = <0x0>; }; }

    根据代码中的cs-gpios = <&pio 6 9 GPIO_ACTIVE_HIGH>;推断spi的cs引脚为PG9(A B C D…对应0 1 2 3 4…),修改文件中的IO配置

    &pio { leds_npi: led_pins { pins = "PA10"; function = "gpio_out"; }; spi0_cs_pins: spi0_cs_pins { //pins = "PC3", "PA6"; pins = "PG9"; function = "gpio_out"; }; };

    关闭HDMI,否则设备默认HDMI输出,tft黑屏

    &hdmi { //status = "okay"; status = "disable"; }; &hdmi_out { hdmi_out_con: endpoint { remote-endpoint = <&hdmi_con_in>; }; }; &sound_hdmi { //status = "okay"; status = "disable"; };

    在设备数表中添加节点

    aliases { serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; serial3 = &uart3; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; spi0 = &spi0; spi1 = &spi1; pwm0 = &pwm; mmc0 = &mmc0; mmc2 = &mmc2; ethernet0 = &emac; i2s0 = &i2s0; pcm5102a = &pcm5102a; spidev0 = &spidev0; matrix = &matrix; kewang = &kewang; spiflash = &spiflash; pitft = &pitft; pitft_ts = &pitft_ts; ir = &ir; };

    3、移植tft驱动

    由于Linux Mainline的BSP包里面没有st7735s的驱动文件,但是在全志原厂的BSP里面有看到过st7735s.c的驱动文件,所以直接复制过来,由于源文件是160x80 的分辨率,所以需要在st7735s.c文件中改两个地方: 1:修改分辨率 2、由于驱动和dtsi文件设置的屏幕参数旋转的90°,根据手中屏幕的分辨率128X128,修改起始点位置,否则屏幕上部会有黑条: 修改fbtft_device.c文件,在设备列表里面增加ft_st7735s设备节点

    { .name = "matrix-st7735s", .spi = &(struct spi_board_info) { .modalias = "fb_st7735s", .max_speed_hz = 32000000, .bus_num = 0, .chip_select = 1, // third spi dev .mode = SPI_MODE_0, //.controller_data= &spi_config, .platform_data = &(struct fbtft_platform_data) { .display = { .buswidth = 8, .backlight = 1, }, .gpios = (const struct fbtft_gpio []) { { "reset", 3 }, { "dc" , 17 }, { "led", 1 }, { "cs" , 201 }, }, } } }

    4、修改st7735s.c和fbtft_device.c目录(linux\drivers\staging\fbtft)下的Makefile和Kconfig文件

    makefile中添加一行 Kconfig文件中添加代码,否则kernel图形界面配置选项无法找到

    5、主makefile修改,路径在linux目录下

    如果不修改则每次make 都需要带ARCH=arm CROSS_COMPILE=arm-linux-,因为系统默认架构是arm64,为了方便,所以干脆直接改主makefile,其中CROSS_COMPILE要填交叉编译工具所在路径

    6、配置kernel

    1、执行make sunxi_defconfig,这个配置文件是BSP自带的 2、make menuconfig进入图形配置界面 3、按照顺序依次选择Device Driver->Staging drivers->Support for small TFT LCD display modules 4,、按下图,将st7735s和tbtft_device选择成模块 5、编译kernel 、dtbs 、驱动模块 ,执行make zImage dtbs modules,时间比较长 6、更新SD卡kernel、dtbs 、驱动模块,将驱动模块复制到根文件系统目录,具体为rootfs/lib/modules/4.x.x/kernel/driver/staging/fbtft

    7、连接硬件

    tft屏幕除了VCC和GND之外,还有 SDA:传输的数据,即RGB数据; SCL:SPI通信时钟; RES:复位,模块上电时拉低,通常情况下置1; D/C:芯片的数据/命令控制引脚,当DC = 0时写命令,当DC = 1时写数据; CS:从机片选, 仅当CS为低电平时,芯片才会被使能; BLK(led):背光灯,一般直接接高电平即可; 根据代码和nanopi官方硬件引脚定义连接好

    8、开机上电调试

    成功启动后,进入st7735s,ko fbtft_device.ko驱动文件所在径/lib/modules/4.x.x/kernel/driver/staging/fbtft 执行:

    sudo insmod fbtft_device.ko name=matrix-st7735s busnum=0 gpios="reset:3,dc:17" rotate=90 custom=1 height=128 width=128 sudo insmod fb_st7735s.ko

    执行成功的话屏幕应该点亮了,通过lsmod命令就能看到模块已被加载,在/dev目录下,会产生fb0设备,如果执行失败,可以通过dmesg | grep "fb" 来查看内核日志,分析具体原因,一般都是由于参数错了导致;

    9、设置开机自动加载模块

    1、在st7735s.ko fbtft_device.ko 驱动模块目录下(/lib/modules/4.x.x/kernel/driver/staging/fbtft)执行sudo depmod -A 生成map文件。 2、编辑文件 /etc/modules,添加如下:

    fb_st7735s fbtft_device

    3、新建配置文件 /etc/modprobe.d/fbtft.conf,内容如下:

    options fbtft_device name=matrix-st7735s busnum=0 gpios=reset:3,dc:17 rotate=90 custom=1 height=128 width=128

    4、上面 3 步完成后重启,应该就可以看到屏幕被点亮并显示了 console,说明驱动被自动加载了

    10、参考链接:

    ZYNQ 移植fbtft屏 nanopi-neo 点亮spi tft

    11、添加图形界面

    Processed: 0.014, SQL: 9