本文将在petalinux下完成 GPIO的输入输出功能。其中输出功能将用LED灯来演示,输入功能用板子上的按键来演示
vivado 版本是2018.3版 ,其他版本请自行尝试
(备注 此章节内容适用于 Smart ZYNQ SP和SL 版的板子,如果是Smart ZYNQ 标准版请看对应板子目录)
Vivado 部分的工程创建(Vivado 创建过程和之前的工程有部分雷同,可以选择性对的跳看)
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/04/image-50.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)选择芯片型号 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/2021/07/image-4.png)
之后 工程就新建好了, vivado 进入到开发界面
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-172-1024x738.png)
Block Design 部分创建
此处需要创建一个ZYNQ CORE ,并在ZYNQ CORE中设置DDR 以及UART等参数
UART此处用 EMIO方式连接(Tiny FPGA 以及 EBAZ4205转接板都用EMIO的方式连接)
1)创建一个BLOCK设计
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-173.png)
2)搜索并添加ZYNQ7 Processing System,添加ZYNQ7 PROCESSING SYSTEM模块
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-174.png)
3)软件自动生成了一个 zynq的block 如下图所示,接下来要做一些相应的设置,双击下图中的ZYNQ核
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-175.png)
4)在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)
5) 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)
6). 在block design 的设置界面 使能SD的功能
![](http://www.hellofpga.com/wp-content/uploads/2022/12/image-80.png)
增加4路GPIO (EMIO方式),其中两路用来点亮LED灯,两路用来读入按键的值
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-4.png)
7)随后点OK 保存修改, 点击“Run Block Automation”如下图所示。在弹出的选项中保持默认,点击“OK”,即可完成对ZYNQ7 Processing System的配置
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-178.png)
8)用鼠标连接FCLK_CLK和 M_AXI_GP0_ACLK,得到下图
![](http://www.hellofpga.com/wp-content/uploads/2023/02/image-36.png)
9)右键GPIO_0选择Make External
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-5.png)
10) 引出UART 信号,右键选择ZYNQ模块的UART_0,然后选择Make External
![](http://www.hellofpga.com/wp-content/uploads/2023/04/image-32.png)
11)source→Design Source ,右键我们创建的BLOCK工程,点击create HDL wrapper,打包BLOCK文件并生成.v代码
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-179.png)
12) 点击绿色箭头RUN 对代码进行编译
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-180.png)
13) 完成后点击RTL 中的SCHEMATIC , 并选择右边出现的 IO Ports 来增加UART 0 EMIO部分的管脚定义(这一步也可以在约束文件中定义, 可看之前的例子)
![](http://www.hellofpga.com/wp-content/uploads/2022/07/image-7-1024x482.png)
将4个EMIO的GPIO 分别接P20 P21 K21 J20分别对应两个LED灯和两个按键,UART 的TX设置L17 和 RX设置 M17 之后保存(保存的时候会让你给约束文件命名,自行定义就好)
![](http://www.hellofpga.com/wp-content/uploads/2023/04/image-51-1024x301.png)
14) 生成bit文件 :按下Generate Bitstream 完成综合以及生成bit文件,等待弹出综合完成的窗口
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-18.png)
15)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)
12)File→Lauch SDK,在弹出的对话框中,保存默认,点击“OK”,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-21.png)
系统将自动打开SDK开发环境
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-22.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_GPIO_TEST的工程
petalinux-create --type project --template zynq --name Petalinux_GPIO_TEST
按下回车后 名为Petalinux_GPIO_TEST的工程会被创建,并且刚才的文件夹下多了一个对应的工程文件夹
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-10.png)
为了方便以后的工程管理,我们将刚才生成的system.hdf 也拖到Petalinux_GPIO_TEST文件夹中
4) 复制hdf文件到刚才创建的工程文件夹中
在图形界面下双击打开这个Petalinux 文件夹
打开刚才SDK的软件界面, 右键hdf文件,选择copy 复制
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-184.png)
然后在图形界面打开 Ubuntu 的Petalinux 文件夹下的Petalinux_GPIO_TEST文件夹内, 右键空白处 点选Paste (粘贴)
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-11.png)
5)设置路径并启动Petalinux 配置页
在刚才的界面下先CD进入 工程文件夹(Petalinux_GPIO_TEST) 备注(CD 的时候 可以输入文件夹的第一个字母然后按tab键,这样相同名称的文件夹就会跳出来)
cd Petalinux_GPIO_TEST
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-12.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 进行配置 (大量内容和之前章节四重复,可选择看)
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 也进行设置 ,ubsystem 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 的,所以这里不需要像Tiny ZYNQ板那样调整net boot offset加载位置
e)保存设置 选择save 并点选ok 对设置进行保存
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-209.png)
f )退出 设置界面
主菜单选择EXIT 退出
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-211.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-210.png)
之后 系统进行配置 ,此时等待配置结束
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-212.png)
g) 等待配置结束后 输入以下命令 对内核进行配置(这一步不操作 没影响)
petalinux-config -c kernel
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-13.png)
之后又是漫长的等待
之后弹出了 KERNEL 的配置界面,这里我们不需要任何修改默认即可,直接保存
退出
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-14.png)
h) 编译整个工程
petalinux-build
之后又是漫长的等待
![](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)
I) 打包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/01/image-16.png)
TF启动测试
在Ubuntu 系统内 打开 工程文件夹内 编译生成的image文件夹
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-17.png)
再打开linux 文件夹
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-18.png)
复制这2个文件 BOOT.bin、image.ub
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-22.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)
设置成SD启动后重新上电后,打开串口助手,波特率设置成115200 ,之后我们就能看到linux 发出来的命令行了(这里也可以用 SDK 自带的Terminal 功能,如下图打开,串口号根据实际的选择,备注:部分JTAG下载器带串口功能,选择串口根据实际用的哪路串口去选择
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-238.png)
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-23.png)
系统此时停留在等待输入账号密码的状态, 此时输入用户名 root 输入密码 root (不同的串口助手有些需要带回车)
之后就正式登录 petalinux 了
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-24.png)
之后就可以进行linux 的操作了
GPIO功能验证一 点亮LED
我们这里直接用最最原始的方式来驱动GPIO(sysfs方式) 首先我们尝试点亮LED灯
对GPIO的操作主要分三步:
①导入IO到用户空间:/sys/class/gpio/export echo 960 > export ②配置IO:/sys/class/gpio/direction echo out > direction # 输出 echo in > direction # 输入 ③控制IO:/sys/class/gpio/value echo 1 > value #输出高电平 echo 0 > value #输出低电平
按照这个思路我们来实际操作一下
a)进入 /sys/class/gpio/ 目录
cd /sys/class/gpio/
b) 查看 文件夹下的内容
ls
c)由下图可以知道系统已经识别出一个GPIO设备 gpiochip906了
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-25.png)
gpiochip906的起始编号是 906 ,因为我们的板子上LED灯被配置到EMIO的0 和EMIO 1上了,而emio0 和emio1分别对应54和55(编号0-53属于MIO),相当于对应linux 系统的 gpio960(906+54)和gpio961(906+55)
备注 有时候gpiochip并不是906 也可能是shu905 904, 这样对应的gpio 数就要加上对应的数
d) 输入下列指令输将EMIO0 节点(即LED灯)导入用户空间
echo 960 > /sys/class/gpio/export
e) 接下来我们尝试点亮LED灯,我们需要的操作是将输入输出改成为输出模式, 并且将LED灯对应的EMIO0 (GPIO960)设置为高电平
下列指令将GPIO960设置为输出
echo out > gpio960/direction
输入下列指令将GPIO960设置为高电平
echo 1 > gpio960/value
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-28.png)
此时LED灯被正常点亮了, 想要关闭LED灯,可以把 gpio960/value 设置为0
echo 0 > gpio960/value
此时LED灯被熄灭
GPIO功能验证二 按键读取
接下来我们来尝试读取按键的值
gpiochip906的起始编号是 906 ,因为我们的板子上KEY被配置到EMIO的2 和EMIO 3上了,而emio0 和emio1分别对应56和57(编号0-53属于MIO),相当于对应linux 系统的 gpio962(906+56)和gpio963(906+57),根据之前设置 KEY1对应的是gpio963
备注 有时候gpiochip并不是906 也可能是shu905 904, 这样对应的gpio 数就要加上对应的数,查看gpiochip 的方法是 进入/sys/class/gpio/目录后,用ls命令查看设备
a)进入 /sys/class/gpio/ 目录
cd /sys/class/gpio/
b) 输入下列指令输将EMIO2 节点(即KEY1)导入用户空间
echo 963 > /sys/class/gpio/export
c) 我们也可以通过下列命令查看当前的输入输出状态
cat gpio963/direction
可以看到这里 GPIO962默认就是输入状态了
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-30.png)
d) 如果输入输出状态是out ,那我们这里需要用下列命令将模式修改成in
echo in > gpio963/direction
e )之后我们通过下列指令来查看当前的按键值(输入指令前,我们需要提前按下或者松开按键)
cat gpio963/value
如下图所示,当KEY1 (即EMIO3 GPIO963) 按下时,返回的value值是0, 当KEY1 松开时返回值是1
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-31.png)
以上是petalinux 的GPIO 输入输出测试的完整流程。 后续有时间 将尝试设备树和驱动等方式来调用GPIO
以下是 VIVADO 的工程 (里面的image文件夹 里面是 Ubuntu 下编译的镜像文件,将image 文件夹里的镜像复制到fat32的TF卡也能看效果),因为ubuntu下工程比较庞大,无法上传,所以大家按照上面描述的内容自行创建
备注 一般linux 的命令行远程调试习惯上用 putty这样的专业工具替代串口助手(这样诸如CTRL+C这样的指令就可以用键盘的形式直接发送了,putty官网可以免费下载到)
打开后配置界面如下 模式选择serial ,并设置好串口号(查看设备管理器得到) 和波特率115200就行
![](http://www.hellofpga.com/wp-content/uploads/2023/02/1UN88AEMMOLWOXKZM0.png)
![](http://www.hellofpga.com/wp-content/uploads/2023/02/image-31.png)
另外 关于 sysfs:sysfs(虚拟文件系统),sysfs的作用是将注册进系统中的设备、总线和驱动组织成一个个分级的文件,并直观地将驱动和设备的层次结构以文件的形式展示在用户空间,通过操作这些文件,系统向用户空间导出内核数据结构以及他们的属性,这样一来用户空间可以通过修改sysfs的文件属性来修改设备的属性值,进而改变设备的工作状态
以下是 VIVADO 的工程 (里面的image文件夹 里面是 Ubuntu 下编译的镜像文件,将image 文件夹里的镜像复制到fat32的TF卡也能看效果)