本文将实现在Petalinux 下调用我们的板载1.47寸320×240 LCD 并显示linux 终端命令行的功能。
(备注 此章节内容适用于 Smart ZYNQ SP,如果是Smart ZYNQ 标准版请看对应板子目录)
本实验是基于vivado 2018.3进行的,如果是其他版本的vivado 请自行尝试
1.硬件介绍
LCD 接口如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-87.png)
LCD_BLK:LCD背光(默认常亮)
SPI 信号: CS 片选信号 SCL 时钟 SDA 数据
DC :数据/命令 信号
RES : 屏幕复位 信号
管脚定义:CS P15 ,D/C R15 ,SCL N15 ,SDA M15 ,RES L16 ,BLK T16(BLK默认不去控制 背光也会默认常亮输出)
彩色液晶屏资料(厂家提供的资料) 店铺 中景园电子
链接:https://pan.baidu.com/s/110uz88iQMA7wl9vdqG9R9A 提取码:8888
工程创建
1)打开Vivado 新建一个项目, 新建一个VIVADO 工程,打开软件 选中Create Project, 如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2021/07/Create-Project.png)
2)点击NEXT ,在出现的第二个对话框“Project name”中输入工程名;在“Project location”中选择保存路径;勾选“Create project subdirectory”(默认),最后点击“Next” 备注,所有的路径均不能出现中文名称
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-11-1024x242.png)
3)点击 RTL PROJECT 选项,点击NEXT
![](http://www.hellofpga.com/wp-content/uploads/2021/07/image.png)
4) 第四步Add Sources 选项直接留空,NEXT
5)第五步Add Constraints 选项直接留空,NEXT
6)选择芯片型号
板子的芯片型号为 XC7Z020 封装是CLG484 所以型号我们选择 xc7z020clg484-1
![](http://www.hellofpga.com/wp-content/uploads/2023/04/image-3-1024x846.png)
7)确认所选信息 点击“Finish”,完成vivado的工程创建
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-12-1024x867.png)
之后 工程就新建好了, vivado 进入到开发界面
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-172-1024x738.png)
8) 创建一个BLOCK设计
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-13.png)
添加ZYNQ7 PROCESSING SYSTEM模块,软件自动生成了一个 zynq的block 如下图所示,接下来要做一些相应的设置,双击下图中的ZYNQ核
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-14.png)
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-3.png)
9)双击ZYNQ 模块,并在zynq中设置DDR功能:
依次在弹窗里找到DDR Configuration→DDR Controller Configuration→DDR3,在Memory Part下拉菜单中根据自己板子上的DDR来选择相应的DDR3,本实验所用到型号:MT41K256M16RE-125,数据位宽选择16bit 最后点击“OK”,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-70.png)
10) linux 需要通过串口来进行命令行的输入输出,所以这里额外在ZYNQ核心中增加串口功能(选择EMIO方式)
由原理图可知, 主板的UART功能接在 ZYNQ PL端的 L17脚和M17脚了,即 ZYNQ的TX是 连接L17,ZYNQ的RX是连接M17 (备注 V1.0板子上的丝印 TX 和 RX标反了,以原理图为准)
![](http://www.hellofpga.com/wp-content/uploads/2023/04/image-44-1024x181.png)
使能UART 0 并在IO选项里选择EMIO方式
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-118.png)
11) 因为本工程要用到TF来进行启动,所以这里使能SD功能
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-15.png)
12)因为我们的屏幕是SPI的屏,所以在ZYNQ中配置SPI功能
因为屏幕的接口是连接到ZYNQ的PL口上,所以这里我们调用EMIO的SPI功能(即使用PS的SPI功能,但是内部连接映射到PL的GPIO口上)
MIO Configuration→SPI 0勾上 并选择EMIO
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-60.png)
13)由于屏幕的驱动除了SPI外,还需要3个额外的GPIO口来分别控制复位RES,D/C信号,和BLK信号,所以这里增加三个GPIO口,这里GPIO资源选择EMIO GPIO 位宽Width选择3(因为是3个IO口)
![](http://www.hellofpga.com/wp-content/uploads/2023/04/image-27.png)
14)因为工程暂时用不到 AXI功能,所以可以先禁用AXI功能
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-131.png)
15)完成上述操作后, 点击“Run Block Automation”如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-65.png)
在上图中分别点击IO口进行以下操作:
右键GPIO_0选择Make External
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-67.png)
右键SPI_0 选择Make External
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-66.png)
右键UART_0 选择Make External
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-17.png)
得到下图所示
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-18.png)
16)创建硬件描述,source→Design Source ,右键我们创建的BLOCK工程,点击create HDL wrapper如下图所示(这一步的作用相当于将图纸转换成对应的硬件描述语言的功能)
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-69.png)
这时候我们可以看到软件的TOP层 的verilog文件,打开后观察管脚信号,如下图
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-70.png)
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-66.png)
圈内的几个管脚是我们之前定义的SPI 管脚,和GPIO管脚, 其中
其中spi_0_io0为 SPI的MISO信号, spi_0_io1_io 为MOSI信号 ,SCK 为SPI时钟信号, SS,SS1,SS2分别为三组SPI 的CS信号
GPIO_0_0为刚才定义的三个GPIO ( 复位 和D/C,和BLK)
17) 因为我们的屏幕只用到了一组CS ,所以我们删除多余的CS
屏幕实际只用到了 SPI的数据SDA和时钟SCL和CS三个信号, 所以SPI 我们只需要引出 MOSI (SDA) 和 SCK(SCL),和CS(SS)即可
删除如下框图中的信号的位置
![](http://www.hellofpga.com/wp-content/uploads/2022/04/image-2.png)
同样也需要删除内部 buf(否则 外部管脚不调用会报错)
![](http://www.hellofpga.com/wp-content/uploads/2022/04/image-4.png)
18) 点击绿色箭头RUN 对代码进行编译
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-71.png)
19) 点击RTL 中的SCHEMATIC , 并选择右边出现的 IO Ports 来增加SPI的管脚定义(这一步也可以在约束文件中定义, 可看之前的例子)
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-69-1024x411.png)
修改GPIO 管脚定义 和SPI管脚定义,如下图所示 ,修改后保存(如弹出 窗口需要,则在窗口中输入约束文件名,然后保存)
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-19-1024x294.png)
CS P15 ,D/C R15 ,SCL N15 ,SDA M15 ,RES L16 ,BLK T16, RXD M17,TXD L17
20) 生成bit文件 :按下Generate Bitstream 完成综合以及生成bit文件
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-18.png)
21)File→Export→Export hardware…在弹出的对话框中勾选“include bitstream”,点击“OK”确认,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-20.png)
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-24.png)
13)File→Lauch SDK,在弹出的对话框中,保存默认,点击“OK”,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-21.png)
系统将自动打开SDK开发环境
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-73.png)
其中SDK工程下的 下图hdf文件就是我们需要的系统硬件描述文件,这个需要交给petalinux 进行交叉编译用。
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-181.png)
PetaLinux 工程创建
1)打开虚拟机下的 Ubuntu系统,打开命令行
输入 source /opt/pkg/petalinux/2018.3/settings.sh 对Petalinux 的环境进行加载
source /opt/pkg/petalinux/2018.3/settings.sh
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-189.png)
2)在Ubuntu下创建工程目录(这里用图形界面的方式,当然也可以用mkdir的方式)
在home文件夹下 创建一个Petalinux文件夹(前两个章节已经创建了),可以图形界面打开Home 文件夹然后直接右键新建一个Petalinux
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-183.png)
3) 创建Petalinux 工程
在工程文件夹的空白处 右键,然后点选Open in Terminal 打开终端命令行(这种方式打开命令行会自动定位到当前文件夹),当然也可以普通方式打开终端 ,再用CD的方式定位到此文件夹
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-188.png)
(备注 如果用此方法,必须重新在这个新打开的命令行中对petalinux 开发环境进行预加载,否则后面会失败,每次打开新的命令行都需要执行这个命令)
source /opt/pkg/petalinux/2018.3/settings.sh
在命令行输入,来创建一个Petalinux_Net_TEST的工程
petalinux-create --type project --template zynq --name Petalinux_LCD_Terminal
按下回车后 名为Petalinux_LCD_Terminal的工程会被创建,并且刚才的文件夹下多了一个对应的工程文件夹
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-74.png)
为了方便以后的工程管理,我们将刚才生成的system.hdf 也拖到Petalinux_USB_HOST_TEST文件夹中
4) 复制hdf文件到刚才创建的工程文件夹中
在图形界面下双击打开这个Petalinux 文件夹
打开刚才SDK的软件界面, 右键hdf文件,选择copy 复制
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-184.png)
然后在图形界面打开 Ubuntu 的Petalinux 文件夹下的Petalinux_Net_TEST文件夹内, 右键空白处 点选Paste (粘贴)
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-75.png)
5)设置路径并启动Petalinux 配置页
在刚才的界面下先CD进入 工程文件夹(Petalinux_LCD_Terminal) 备注(CD 的时候 可以输入文件夹的第一个字母然后按tab键,这样相同名称的文件夹就会跳出来)
cd Petalinux_LCD_Terminal
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-76.png)
进入文件夹后,按下下列代码, 指定导入hdf的路径(因为是当前命令行的路径所以这里 带一个”.”就可以了,不然=号后跟具体路径) 并按下回车
petalinux-config --get-hw-description=.
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-85.png)
之后系统将启动配置页
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-196.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-197.png)
6) 对Petalinux 进行配置 (大部分内容和之前设置相同,其实如果vivado按照我的设置的话,这里很多选项都是默认不用修改的)
a) 修改启动项
用键盘上的上下左右键移动光标,选择Subsystem AUTO Hardware Settings 按下回车(按两下ESC可以退回上一层)
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-198.png)
选择Advanced bootable images storage Settings ,按下回车
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-199.png)
选择 boot image settings选项 回车
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-200.png)
选择 image storage media 回车
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-87.png)
选择 primary sd并按回车(如果你在vivado 里设置了nand flash 等,这里就有多个选项可选了)
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-88.png)
之后连按两次ESC 可以返回上一级, 一直返回,直到回到最初的初始界面
b )同理 对kernel image settings 也进行设置 ,Subsystem AUTO Hardware Settings 按下回车
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-198.png)
选择Advanced bootable images storage Settings ,按下回车
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-199.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-89.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-90.png)
之后用多次双击ESC的方式回到初始菜单
c) root 文件系统 类型选择
选择Image Packaging Configuration
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-206.png)
选择 Root filesystem type
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-207.png)
选择 INITRAMFS(这里不要因为是TF启动就选择SD CARD,否则需要构建根文件系统,这个有时间后面章节再写)
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-208.png)
之后按多次ESC回到根菜单
d)因为板子上的DDR是512MB 的,所以这里net boot offset加载位置保留默认就好
f)保存设置 选择save 并点选ok 对设置进行保存
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-209.png)
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-79.png)
退出 设置界面
主菜单选择EXIT 退出
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-211.png)
之后 系统进行配置 ,此时等待配置结束
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-212.png)
配置Kernel 增加 LCD 驱动部分
输入以下命令 对内核进行配置
petalinux-config -c kernel
选择 Device Drivers
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-80.png)
选中 Staging drivers并且按下 键盘上的Y键,对Staging drivers进行使能,并按下回车键进入
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-82.png)
选中 Support for small TFT LCD display modules 然后按下键盘上的Y 进行使能,并按回车键进入
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-83.png)
选中FB driver for the ST7789V LCD Controller,并按下键盘上的Y键进行使能
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-84.png)
用鼠标右键移动到save上,对设置进行保存
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-85.png)
弹出来的菜单 直接选ok, 之后按多次exit 退回到主目录
如果需要显示开机的linux 企鹅logo 可以在 Device Driveers
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-28.png)
选择Graphics support
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-29.png)
在 Bootup logo 的地方按下键盘上的Y键 进行使能
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-30.png)
之后一多次按ESC键返回主菜单,然后按EXIT 退出kernel 设置(接着继续漫长的等待)
![](http://www.hellofpga.com/wp-content/uploads/2023/02/image-59.png)
设备树的修改
为了让LCD功能正常使用,我们需要在设备树上增加LCD的相关内容
路径在 我们创建的工程下的 /project-spec/meta-user/recipes-bsp/device-tree/files 内的 system-user.dtsi文件
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-86.png)
双击打开这个文件,并按下图所示,在原先的代码后面增加如下内容,并且在保存与退出
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-87.png)
/include/ "system-conf.dtsi" / { }; #define GPIO_ACTIVE_HIGH 0 #define GPIO_ACTIVE_LOW 1 &spi0 { st7789v@0 { status = "okay"; compatible = "sitronix,st7789v"; reg = <0>; spi-max-frequency =<32000000>; rotate =<270>; spi-cpol; spi-cpha; rgb; fps =<30>; buswidth =<8>; reset-gpios=<&gpio0 55 GPIO_ACTIVE_HIGH>; dc-gpios =<&gpio0 54 GPIO_ACTIVE_LOW>; width = <172>; height = <320>; debug =<0>; }; };
接下来 编译整个工程
回到命令行终端,输入以下代码 对Petalinux进行编译
petalinux-build
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-88.png)
之后又是漫长的等待
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-15.png)
直接到出现提示 successfully built project 代表编译完成了
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-215.png)
修改驱动(虽然编译完成了,但是我们要做的工作并没有结束)
后面还需要对屏幕的驱动进行修改,否则显示的内容会有问题,会出现图像偏移的现象(这里备注一个问题,petalinux每次编译都会从网上下载需要的驱动,上面不直接修改驱动是因为,没编译之前,这些驱动在本地是没有的,所以我们需要等驱动下载好后,再对驱动进行修改)
在工程目录里搜索 fbtft 可以用ctrl+F 来进行搜索
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-20-1024x237.png)
双击并打开fbtft-core.c 然后找到 fbtft_set_addr_win 这个函数对其修改,按下图所示增加 Y轴的偏移量
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-21.png)
之后 对文件进行保存,然后关闭
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-22.png)
之后在工程中搜索,st7789,然后如下图所示,打开fb_st7789v.c
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-23.png)
在屏幕初始化代码中按下图增加 write_reg(par, 0x21, 0x00);
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-24.png)
之后 仍然点 save ,和退出
完成上述操作后,不能直接重新编译,否则 修改的内容会直接被忽略
保存修改后,我们需要先清空petalinux 工程编译缓存
petalinux-build -x distclean
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-25.png)
重新编译内核,输入命令
petalinux-build -c kernel -x compile -f
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-26.png)
等完成后 再重新编译
petalinux-build
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-27.png)
打包boot.bin
编译完成后,项目工程文件夹下会有image文件夹,执行petalinux -package 命令 将zynq_fsbl.elf, system_wrapper.bit,u-boot.elf,image.ub 四个文件打包生成
BOOT.bin 文件
petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --u-boot --fpga --kernel --force
如下图所示,代表打包完成(有警告,直接忽略)
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-89.png)
TF启动测试
在Ubuntu 系统内 打开 工程文件夹内 编译生成的image文件夹
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-90.png)
再打开linux 文件夹
![](http://www.hellofpga.com/wp-content/uploads/2023/02/image-66.png)
复制这2个文件 BOOT.bin、image.ub
![](http://www.hellofpga.com/wp-content/uploads/2023/03/image-91.png)
然后回到windows 下,粘贴到格式为FAT32的 TF卡的根目录
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-96.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-95.png)
之后正常退出TF卡, 并将卡插入到 我们的主板上
上电测试
将跳线位置换回到SD上
![](http://www.hellofpga.com/wp-content/uploads/2023/02/image-38.png)
备注 实际测试过程中会发现 虚拟机 和windows 争抢串口的资源的情况,导致windows 下 无法访问串口,所以这里测试的时候(把串口默认设置连接到windows ) 或者临时挂起虚拟机
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-98.png)
因为本工程需要用到ctrl+c来中断应用,所以这里用putty这样的专业工具替代串口助手(这样诸如CTRL+C这样的指令就可以用键盘的形式直接发送了,putty官网可以免费下载到)
打开后配置界面如下 模式选择serial ,并设置好串口号(查看设备管理器得到) 和波特率115200就行
![](http://www.hellofpga.com/wp-content/uploads/2023/02/1UN88AEMMOLWOXKZM0.png)
设置成SD启动后重新上电,我们就能在putty上看到linux 发出来的命令行了(当然本例程 命令行不是最重要的,我们关注的点在屏幕上)
经过大概 20秒钟的启动之后, 屏幕会显示 linux 的启动logo 企鹅, 以及 终端命令行
![](http://www.hellofpga.com/wp-content/uploads/2023/05/image-31.png)
备注 ,这里的命令行 和串口的命令行显示的内容并不相通, 所以通过电脑端串口在命令行中输入的指令这边并不会显示(可以通过 USB HOST 插入键盘来进行 指令的输入和显示,但是本章节并没有做这部分内容,大家可以自行尝试)
以下是 VIVADO 的工程 (里面的image文件夹 里面是 Ubuntu 下编译的镜像文件,将image 文件夹里的镜像复制到fat32的TF卡也能看效果)
另外 为了方便操作,这边放上了一个支持USB 和支持 NET 的固件,这样就可以外接键盘来操作小屏终端了
另外 命令行显示 过暗的情况,跟原厂沟通,以及朋友们的测试得知,原先petalinux 自带的驱动比较老导致色彩和亮度还原不够准确,通过修改gamma的值 可以解决这个问题,我还没尝试过,大家可以自行试试(gamma的值 可以参考中景园 lcd 资料包中的参考值)
写个patch,放bbapend就好,直接改,不符合强迫症要求。。。
哈哈 我研究下你说的方法, 好多人推荐把源码直接下载下来 那个我感觉太占用空间了
width 图片和描述不一致哎
哪个地方的width 我确认下
补充:
如果staging driver里没有找到Support for small TFT LCD display modules,一般是因为其依赖的Framebuffer未使能,使能 Device Drivers –> Graphics support –> Frame buffer Devices –> Support for frame buffer devices
感谢科普