ZYNQ MPSOC 软件无线电开发[软件部分(1)] - 导出Vivado硬件设计并构建Petalinux工程
使用的环境:
Kubuntu 18.04.5 LTS
Vivado 2020.1
Petalinux 2020.1
其中包含petalinux的离线编译包:downloads、sstate、linux-xlnx、uboot-xlnx可以在此下载。下载时务必注意版本匹配。
ALINX AXU3EGB开发板
1. Vivado硬件导出
首先打开工程,该工程内包含ad9238和ad9767的AXI DMA设计。
这是从别人那里拷贝的工程,右键design_1_i,点击Generate Output Products。
完成后生成bitstream。
bitstream生成完成后。导出硬件.xsa设计。
File -> Export -> Export Hardware
生成xsa后可以关闭Vivado了,可以使用导出的.xsa去建立Petalinux工程。导出的硬件设计如下:
2. Petalinux 工程构建
在此之前,请确认已经完成Petalinux开发环境的搭建并解压yocto downloads离线开发环境包,并且在terminal中source过petalinux的环境脚本。
我将所有的petalinux工程放到~/peta_prj下,便于工程管理。执行如下命令:
# 创建工程目录并拷贝.XSA文件
cd ~/peta_prj
mkdir -p ./adda_linux/hardware
cd ./adda_linux/hardware
cp <+YOUR_PATH_TO_XSA_FILE+> ./
cd ..
# 创建工程
petalinux-create -t project -n petalinux --template zynqMP
cd petalinux
petalinux-config --get-hw-description ../hardware/
此时terminal会出现petalinux-config的界面,现在设置让Petalinux帮忙我们自动配置Linux、uboot和device-tree。
选择Auto Config Settings,
选中如下三项:
“kernel autoconfig”、“u-boot autoconfig”这两个选项不选也可以。如果工程中配置了这两个选项且编译出错, 也可以尝试把这两个选项去掉再编译。
设置优先离线编译,让yocto首先使用本地downloads和sstate源码。
回到主菜单,选择Yocto Settings,
进入 Local sstate feeds settings,
对于ZYNQMP,这里需要使用aarch64的sstate。
回到Yocto Settings, 选择Add pre-mirror url,
注意,这里的路径前面要加file://
回到Yocto Settings, 取消选择Enable Network sstate feeds。
回到主菜单,进入 Linux Components Selection 。设置Linux内核源码。
进入linux-kernel(linux-xlnx)设置Linux内核源码。这里我没设置uboot,uboot的源码很小,让他自动下载也可以,不影响编译速度。如果有需要修改uboot也需要用一样的方式:
Linux Components Selection
选择 ext-local-src
现在会自动回到Linux Components Selection。进入External linux-kernel local source settings
进入 External linux-kernel local source path
输入下载的linux内核路径
返回主菜单,进入Image Packaging Configuration,配置SD卡启动
配置成如下选项:
现在,保存配置并退出。
3.Petalinux 设备树修改
现在,修改设备树。Petalinux有两处设备树的源,一份在
~/peta_prj/adda_linux/petalinux/components/plnx_workspace/device-tree/device-tree
,这个是Petalinux根据我们的xsa文件生成的设备树,另外一份在是用户定义的设备树,在
~/peta_prj/adda_linux/petalinux/project-spec/meta-user/recipes-bsp/device-tree/files
用于对自动生成的设备树的参数修改和添加。用户只能修改用户定义的设备树。我们需要根据
~/peta_prj/adda_linux/petalinux/components/plnx_workspace/device-tree/device-tree/pl.dtsi
来修改
~/peta_prj/adda_linux/petalinux/project-spec/meta-user/recipes-bsp/device-tree/files/pl-custom.dtsi
在修改之前,我们需要先让Petalinux根据我们的xsa文件生成一份设备树,以便我们对设备进行修改。
petalinux-build -c device-tree
INFO: sourcing build tools
[INFO] building device-tree
[INFO] sourcing build environment
[INFO] generating user layers
[INFO] generating workspace directory
INFO: bitbake virtual/dtb
Parsing recipes: 100% |########################################################################################| Time: 0:00:33
Parsing of 2961 .bb files complete (0 cached, 2961 parsed). 4230 targets, 168 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Fetching uninative binary shim from file:///home/xlnxdev-2020-1/peta_prj/adda_linux/petalinux/components/yocto/downloads/uninative/9498d8bba047499999a7310ac2576d0796461184965351a56f6d32c888a1f216/x86_64-nativesdk-libc.tar.xz;sha256sum=9498d8bba047499999a7310ac2576d0796461184965351a56f6d32c888a1f216
Initialising tasks: 100% |#####################################################################################| Time: 0:00:12
Checking sstate mirror object availability: 100% |#############################################################| Time: 0:00:03
Sstate summary: Wanted 719 Found 614 Missed 105 Current 0 (85% match, 0% complete)
NOTE: Executing Tasks
NOTE: Setscene tasks completed
NOTE: linux-xlnx: compiling from external source tree /opt/pkg/petalinux/2020.1/linux-xlnx/
WARNING: device-tree-xilinx-v2020.1+gitAUTOINC+bc84458333-r0 do_package: device-tree: NOT adding alternative provide /boot/device-tree.dtb: /boot/device-tree-999.dtb does not exist
NOTE: Tasks Summary: Attempted 2254 tasks of which 2007 didn't need to be rerun and all succeeded.
Summary: There was 1 WARNING message shown.
INFO: Successfully copied built images to tftp dir: /tftpboot
[INFO] successfully built device-tree
现在,查看生成的pl.dtsi和zynqmp.dtsi。
生成的pl.dtsi很长,只保留重点部分。
/ {
amba_pl: amba_pl@0 {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
ranges ;
ad9238_sample_0: ad9238_sample@80000000 {
clock-names = "adc_clk", "m00_axis_aclk", "s00_axi_aclk";
clocks = <&misc_clk_0>, <&misc_clk_1>, <&misc_clk_1>;
compatible = "xlnx,ad9238-sample-1.0";
reg = <0x0 0x80000000 0x0 0x10000>;
xlnx,s00-axi-addr-width = <0x4>;
xlnx,s00-axi-data-width = <0x20>;
};
......
ad9238_sample_1: ad9238_sample@80010000 {
......
};
ad9767_send_0: ad9767_send@80020000 {
clock-names = "dac_clk", "s00_axis_aclk", "s00_axi_aclk";
clocks = <&misc_clk_2>, <&misc_clk_1>, <&misc_clk_1>;
compatible = "xlnx,ad9767-send-2.0";
reg = <0x0 0x80020000 0x0 0x10000>;
xlnx,s00-axi-addr-width = <0x4>;
xlnx,s00-axi-data-width = <0x20>;
};
......
ad9767_send_1: ad9767_send@80030000 {
......
};
axi_dma_0: dma@80040000 {
#dma-cells = <1>;
clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_s2mm_aclk";
clocks = <&misc_clk_1>, <&misc_clk_1>, <&misc_clk_1>;
compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a";
interrupt-names = "s2mm_introut";
interrupt-parent = <&gic>;
interrupts = <0 89 4>;
reg = <0x0 0x80040000 0x0 0x10000>;
xlnx,addrwidth = <0x40>;
xlnx,include-sg ;
xlnx,sg-length-width = <0x1a>;
dma-channel@80040030 {
compatible = "xlnx,axi-dma-s2mm-channel";
dma-channels = <0x1>;
interrupts = <0 89 4>;
xlnx,datawidth = <0x10>;
xlnx,device-id = <0x0>;
};
};
axi_dma_1: dma@80050000 {
......
};
};
axi_dma_2: dma@80060000 {
......
};
};
axi_dma_3: dma@80070000 {
......
};
};
};
};
生成的zynqmp.dtsi很长,只保留重点部分。
#include "include/dt-bindings/power/xlnx-zynqmp-power.h"
#include "include/dt-bindings/reset/xlnx-zynqmp-resets.h"
/ {
compatible = "xlnx,zynqmp";
#address-cells = <2>;
#size-cells = <2>;
......
amba: amba {
......
sdhci0: mmc@ff160000 {
u-boot,dm-pre-reloc;
compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 48 4>;
reg = <0x0 0xff160000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
xlnx,device_id = <0>;
#stream-id-cells = <1>;
iommus = <&smmu 0x870>;
power-domains = <&zynqmp_firmware PD_SD_0>;
nvmem-cells = <&soc_revision>;
nvmem-cell-names = "soc_revision";
#clock-cells = <1>;
clock-output-names = "clk_out_sd0", "clk_in_sd0";
};
sdhci1: mmc@ff170000 {
......
};
......
usb0: usb0@ff9d0000 {
#address-cells = <2>;
#size-cells = <2>;
status = "disabled";
compatible = "xlnx,zynqmp-dwc3";
reg = <0x0 0xff9d0000 0x0 0x100>;
clock-names = "bus_clk", "ref_clk";
power-domains = <&zynqmp_firmware PD_USB_0>;
ranges;
nvmem-cells = <&soc_revision>;
nvmem-cell-names = "soc_revision";
dwc3_0: dwc3@fe200000 {
compatible = "snps,dwc3";
status = "disabled";
reg = <0x0 0xfe200000 0x0 0x40000>;
interrupt-parent = <&gic>;
interrupt-names = "dwc_usb3", "otg", "hiber";
interrupts = <0 65 4>, <0 69 4>, <0 75 4>;
#stream-id-cells = <1>;
iommus = <&smmu 0x860>;
snps,quirk-frame-length-adjustment = <0x20>;
snps,refclk_fladj;
snps,enable_guctl1_resume_quirk;
snps,enable_guctl1_ipd_quirk;
snps,xhci-stream-quirk;
/* snps,enable-hibernation; */
};
};
usb1: usb1@ff9e0000 {
......
};
......
};
};
我们需要根据这份生成的pl.dtsi来修改我们的system-user.dtsi。现在,将system-user.dtsi修改为以下内容:
/include/ "system-conf.dtsi"
/ {
};
/* SD */
&sdhci1 {
disable-wp;
no-1-8-v;
};
/* USB */
&dwc3_0 {
status = "okay";
dr_mode = "host";
};
&ad9238_sample_0 {
compatible = "xlnx,axi-adc9238-dma";
dmas = <&axi_dma_0 1>;
dma-names = "axidma1";
};
&ad9238_sample_1 {
compatible = "xlnx,axi-adc9238-dma";
dmas = <&axi_dma_1 1>;
dma-names = "axidma1";
};
&ad9767_send_0 {
compatible = "xlnx,axi-dac9767-dma";
dmas = <&axi_dma_2 0>;
dma-names = "axidma0";
};
&ad9767_send_1 {
compatible = "xlnx,axi-dac9767-dma";
dmas = <&axi_dma_3 0>;
dma-names = "axidma0";
};
保存,下一步就可以构建工程了。
4.构建Petalinux工程、打包boot并测试
删除components和build文件夹(通常情况不删除不会有问题,但我确实遇见了修改dtsi后不更新编译的情况…保险起见还是rm一下),然后进行petalinux-build。
cd ~/peta_prj/adda_linux/petalinux
rm -rf ./build
rm -rf ./components
petalinux-build
INFO: sourcing build tools
[INFO] building project
[INFO] generating Kconfig for project
[INFO] silentconfig project
[INFO] extracting yocto SDK to components/yocto
[INFO] sourcing build environment
[INFO] generating kconfig for Rootfs
[INFO] silentconfig rootfs
[INFO] generating plnxtool conf
[INFO] generating u-boot configuration files, This will be deprecated in upcoming releases
[INFO] generating kernel configuration files, This will be deprecated in upcoming releases
[INFO] generating user layers
[INFO] generating workspace directory
INFO: bitbake petalinux-image-minimal
Parsing recipes: 100% |########################################################################################| Time: 0:00:33
Parsing of 2961 .bb files complete (0 cached, 2961 parsed). 4230 targets, 168 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Fetching uninative binary shim from file:///home/xlnxdev-2020-1/peta_prj/adda_linux/petalinux/components/yocto/downloads/uninative/9498d8bba047499999a7310ac2576d0796461184965351a56f6d32c888a1f216/x86_64-nativesdk-libc.tar.xz;sha256sum=9498d8bba047499999a7310ac2576d0796461184965351a56f6d32c888a1f216
WARNING: Unable to get checksum for linux-xlnx SRC_URI entry oe-logs: [Errno 2] No such file or directory: '/opt/pkg/petalinux/2020.1/linux-xlnx/oe-logs'
WARNING: Unable to get checksum for linux-xlnx SRC_URI entry oe-workdir: [Errno 2] No such file or directory: '/opt/pkg/petalinux/2020.1/linux-xlnx/oe-workdir'
Initialising tasks: 100% |#####################################################################################| Time: 0:00:08
Checking sstate mirror object availability: 100% |#############################################################| Time: 0:00:04
Sstate summary: Wanted 1008 Found 820 Missed 188 Current 0 (81% match, 0% complete)
NOTE: Executing Tasks
NOTE: Setscene tasks completed
NOTE: linux-xlnx: compiling from external source tree /opt/pkg/petalinux/2020.1/linux-xlnx/
WARNING: arm-trusted-firmware-2.0-xilinx-v2020.1+gitAUTOINC+5918e656ef-r0 do_package: arm-trusted-firmware: NOT adding alternative provide /boot/arm-trusted-firmware.elf: /boot/arm-trusted-firmware-999.elf does not exist
WARNING: device-tree-xilinx-v2020.1+gitAUTOINC+bc84458333-r0 do_package: device-tree: NOT adding alternative provide /boot/device-tree.dtb: /boot/device-tree-999.dtb does not exist
WARNING: u-boot-xlnx-v2020.01-xilinx-v2020.1+gitAUTOINC+86c84c0d0f-r0 do_package: u-boot-xlnx: NOT adding alternative provide /boot/u-boot-xlnx.elf: /boot/u-boot-xlnx-999.elf does not exist
WARNING: pmu-firmware-2020.1+gitAUTOINC+6cbb920f4d-r0 do_package: pmu-firmware: NOT adding alternative provide /boot/pmu-firmware.elf: /boot/pmu-firmware-999.elf does not exist
WARNING: fsbl-2020.1+gitAUTOINC+6cbb920f4d-r0 do_package: fsbl: NOT adding alternative provide /boot/fsbl.elf: /boot/fsbl-999.elf does not exist
NOTE: Tasks Summary: Attempted 3609 tasks of which 2652 didn't need to be rerun and all succeeded.
Summary: There were 7 WARNING messages shown.
INFO: Successfully copied built images to tftp dir: /tftpboot
[INFO] successfully built project
打包boot.bin。
petalinux-package --boot --u-boot --fpga --fsbl --force
“–u-boot”参数会将 u-boot 依赖全部合成到 BOOT.bin 中,“–fpga”合成 bit 文件到BOOT.bin 中(注意:如果你的 xsa 文件中不包含 bitstream,就不要加这个参数),“–fsbl”合成 fsbl 文件到 BOOT.bin 中,“–force”为强制合成,覆盖以前合成的 BOOT.BIN。
INFO: sourcing build tools
INFO: File in BOOT BIN: "/home/xlnxdev-2020-1/peta_prj/adda_linux/petalinux/images/linux/zynqmp_fsbl.elf"
INFO: File in BOOT BIN: "/home/xlnxdev-2020-1/peta_prj/adda_linux/petalinux/images/linux/pmufw.elf"
INFO: File in BOOT BIN: "/home/xlnxdev-2020-1/peta_prj/adda_linux/petalinux/project-spec/hw-description/design_1_wrapper.bit"
INFO: File in BOOT BIN: "/home/xlnxdev-2020-1/peta_prj/adda_linux/petalinux/images/linux/bl31.elf"
INFO: File in BOOT BIN: "/home/xlnxdev-2020-1/peta_prj/adda_linux/petalinux/images/linux/system.dtb"
INFO: File in BOOT BIN: "/home/xlnxdev-2020-1/peta_prj/adda_linux/petalinux/images/linux/u-boot.elf"
INFO: Generating zynqmp binary package BOOT.BIN...
****** Xilinx Bootgen v2020.1
**** Build date : May 26 2020-14:07:15
** Copyright 1986-2020 Xilinx, Inc. All Rights Reserved.
[INFO] : Bootimage generated successfully
INFO: Binary is ready.
现在可以将启动文件复制到sd卡启动了。SD卡需要做如下分区,第一分区为FAT32或FAT16,第二分区为ext4:
将文件拷贝到sd卡上,我的sd卡第一分区,第二分区的挂载点分别在/media/xlnxdev-2020-1/BOOT 和/media/xlnxdev-2020-1/root上。:
sudo cp ./images/linux/boot.scr /media/xlnxdev-2020-1/BOOT/
sudo cp ./images/linux/BOOT.BIN /media/xlnxdev-2020-1/BOOT/
sudo cp ./images/linux/image.ub /media/xlnxdev-2020-1/BOOT/
sudo rm -rf /media/xlnxdev-2020-1/root/*
sudo tar -zxvf ./images/linux/rootfs.tar.gz -C /media/xlnxdev-2020-1/root/
sudo sync
连接PL端串口,监视启动
有上述内容,说明pl端的DMA已经加载。
看到PetaLinux 2020.1 petalinux ttyPS0
说明已经成功进入系统的tty,这时系统已经完成启动了,等待用户登录。
5.Problems
启动AXI设备的时候卡住,内核报告 rcu_sched detected stall on CPU/tasks
。
先说结论:一方面,工程路径内不要有非ASCII字符,讲人话就是路径不要有中文。另一方面,从别人拷过来的工程可能和本机环境不兼容?删除一下AXI Interconnect再重新添加一下就好了。
下面是详细解决过程。
我参考了https://support.xilinx.com/s/question/0D54U00006hxFtPSAU/petalinux-20222-kernel-51536-rcusched-detected-stall-on-cputasks?language=zh_CN
这似乎是一个玄学问题,这位老哥用的也是XCZU3EG这个芯片。评论里都在建议调试内核,似乎并没有什么解决办法。至于我是怎么解决的,重新genetare output products,然后synthesis,implementation、Generate Bitstream,到第三次就好了。。。
问题总归是要搞明白的,先对比一下能正常启动的河不能正常启动的.xsa里面的文件。
忽略编译时间和一些正常的差异,里面主要差在这几个文件上:
先来看design_1.hwh,关于hwh文件,我找到了Xilinx在pynq doc里的描述:
简单地说就是用来描述ip核的外部控制信号的,此外还有版本和一些其他信息等等。用bc比较一下差异,下面摘主要部分:
左边是不能正常启动的,缺少了一部分内容,都是围绕这几个信号:
回到Vivado看一下编译信息,正好是这几个:
因为某些玄学原因导致几个pin没有连接,但是工程应该是正常的,编译综合的时候不应该出现这种问题啊,那可能是Vivado的内部错误了。现在注意到默认安装linux的时候home下的一些默认文件夹都是中文。作为软件人的直觉告诉我可能是这里的问题,遂将对接来的项目直接在~/下的英文路径解压。
现在在这个路径下。重新编译综合,生成bitstream。
然后就。。。一点warning都没有了。。。tcl console的输出:
start_gui
open_project /home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/AD_DA_ALL1.xpr
open_project /home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/AD_DA_ALL1.xpr
INFO: [Project 1-313] Project file moved from 'F:/Documents/01_Software_Defined_Radio/02_Vivado_Prj' since last save.
Scanning sources...
Finished scanning sources
INFO: [IP_Flow 19-234] Refreshing IP repositories
INFO: [IP_Flow 19-1700] Loaded user IP repository '/home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/repo'.
INFO: [IP_Flow 19-2313] Loaded Vivado IP repository '/tools/Xilinx/Vivado/2020.1/data/ip'.
open_project: Time (s): cpu = 00:00:29 ; elapsed = 00:00:16 . Memory (MB): peak = 7164.059 ; gain = 38.066 ; free physical = 7401 ; free virtual = 351739
update_compile_order -fileset sources_1
reset_run synth_1
launch_runs impl_1 -to_step write_bitstream -jobs 32
[Tue Mar 26 19:37:33 2024] Launched synth_1...
Run output will be captured here: /home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/AD_DA_ALL1.runs/synth_1/runme.log
[Tue Mar 26 19:37:33 2024] Launched impl_1...
Run output will be captured here: /home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/AD_DA_ALL1.runs/impl_1/runme.log
set_property pfm_name {} [get_files -all {/home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/AD_DA_ALL1.srcs/sources_1/bd/design_1/design_1.bd}]
write_hw_platform -fixed -include_bit -force -file /home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/design_1_wrapper.xsa
INFO: [Vivado 12-4895] Creating Hardware Platform: /home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/design_1_wrapper.xsa ...
INFO: [Hsi 55-2053] elapsed time for repository (/tools/Xilinx/Vivado/2020.1/data/embeddedsw) loading 0 seconds
INFO: [Vivado 12-4896] Successfully created Hardware Platform: /home/xlnxdev-2020-1/vvdtest/02_Vivado_Prj/design_1_wrapper.xsa
write_hw_platform: Time (s): cpu = 00:00:27 ; elapsed = 00:00:26 . Memory (MB): peak = 7813.371 ; gain = 0.000 ; free physical = 9038 ; free virtual = 354645
原罪是中文路径名
24-03-27 更新
今天打包把工程发给别人,测试又遇到问题了。。对面跟我说是运行了一下reset_project之后再重新generate就会这样,不清理缓存直接导出硬件就没事,可能不同环境的工程会触发这个问题。
最终的解决方法是在block design里把AXI Interconnect删掉再添加,然后重新连线就好了。。
后来我自己实测了一下,将AXI Interconnect换成了AXI Smatconnect,后来就没再遇到过问题了。可能真的是Vivado内部的bug吧。。