本篇是綜合工程,將較爲詳細的講解如何利用vivado搭建一個AXI-DMA環通測試環境,並使用petalinux進行linux系統的部署。以QSPI的啓動方式喚起emmc fat分區中的linux內核系統,並掛載emmc ext4分區中的根文件系統。同時,使用xilinx-axidma庫進行AXI-DMA的環通測試
目錄
0 - 準備工作
- ZYNQ7000開發板,4G eMMC掛載在SD1,SD卡槽掛載在SD0
- 已預先在eMMC中分兩區,fat區用於存放image.ub與設備樹文件dtb,ext分區存放着已預先搭建好的根文件系統
關於如何使用WORK-Linux(一個能運行的存儲在sd卡中的linux系統)來進行eMMC分區:linux指令fdisk
關於如何搭建根文件系統:i.MX6UL #0 - ubuntu根文件系統的修改與配置(從零開始的掉頭髮生活)
- 根文件系統中已存放編譯好的xilinx_axidma庫
xilinx_axidma github:https://github.com/bperez77/xilinx_axidma
如何編譯xilinx_axidma庫:ZYNQ7000 #3 - Linux環境下在用戶空間使用AXI-DMA進行傳輸
1 - VIVADO工程
vivado工程較爲簡單,如圖所示,在基本的ps系統基礎上(ZYNQ7000 #5 - 從vivado工程開始,從emmc啓動Linux),添加了一個AXI Direct Memory Access IP核以及一個Concat集線器。紅色是數據流環通迴路,藍色是中斷信號從PL到PS的通路。在使用xilinx_axidma庫時,AXI-DMA IP核的中斷信號是必須連接到PS核的。
生成比特流文件,導出hdf時需要勾選包括比特流文件。這樣我們就得到petalinux所需的hdf文件了
bitstream是vivado中生成的,導出爲hdf文件時需要include bitstream。
hdf實際只是個壓縮文件,其中包括硬件信息、bitstream等等,petalinux需要解包hdf然後將其中的bitstream用於後面進行petalinux-package
2 - petalinux工程
2.1 - petalinux工程建立
將hdf文件拷貝到已安裝好petalinux的虛擬機中
運行下面的語句,加載petalinux環境
$ . /opt/pkg/petalinux/settings.sh
讀取hdf文件
$ petalinux-config --get-hw-description=你的hdf文件所在文件夾路徑
之後會自動打開petalinux工程配置的menuconfig
2.2 - 工程配置
修改Linux Components Selection,選擇使用外部的linux內核(ZYNQ7000 #0 - petalinux的使用與工程建立(都9102年了,就用用便利的工具吧))
這裏我們需要從eMMC啓動Linux Kernel。所以改變主SD爲掛載了eMMC的SD1,讓boot image從primary flash讀取,設置linux kernel存儲位置爲primary sd(ZYNQ7000 #5 - 從vivado工程開始,從emmc啓動Linux)
修改使用eMMC中的根文件系統,eMMC已經分區,但是其掛載在的是SD1上,所以eMMC上的ext分區會被識別爲mmcblk1p2。這裏不需要使用tftboot,所以也取消
2.3 - UBOOT的BUG修復
整個下來唯一要操心的就只有uboot
修改uboot的project-spec\meta-user內文件,避免從sd載入dtb的錯誤(ZYNQ7000 #3 - Linux環境下在用戶空間使用AXI-DMA進行傳輸)和跳過空SD0的錯誤(ZYNQ7000 #5 - 從vivado工程開始,從emmc啓動Linux)
在 project-spec/meta-user/recipes-bsp/u-boot/files/plantform-top.h 文件末尾加入下面的代碼。注意CONFIG_BOOTCOMMAND後接語句使用一個TAB製表符
#ifdef CONFIG_BOOTCOMMAND
#undef CONFIG_BOOTCOMMAND
#define CONFIG_BOOTCOMMAND "mmc dev ${sdbootdev}; run uenvboot; run cp_kernel2ram && run cp_dtb2ram && bootm ${netstart} - ${dtbnetstart}"
#endif
2.4 - 設備樹修改
爲了使用xilinx_axidma,我們需要修改dma通道的id,並在設備樹中添加axidma_chrdev子節點
將 project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi 文件添加下面的代碼
&amba_pl{
axidma_chrdev: axidma_chrdev@0 {
compatible = "xlnx,axidma-chrdev";
dmas = <&axi_dma_0 0 &axi_dma_0 1>;
dma-names = "tx_channel", "rx_channel";
};
};
&axi_dma_0{
dma-channel@40400000 {
xlnx,device-id = <0x0>;
};
dma-channel@40400030 {
xlnx,device-id = <0x1>;
};
};
這樣我們就在amba_pl總線下掛載好了axidma_chrdev子節點,並且將axi_dma_0總線下的兩個dma通道(一發一收)的id分別設置爲了0和1
2.5 - linux內核配置
修改內核CMA大小
$ petalinux-config -c kernel
Device Drivers -> Generic Driver Options -> Default contiguous memory area size 的 Size in Mega Bytes修改爲25
2.6 - 編譯生成
$ petalinux-build -c kernel
$ petalinux-build -c fsbl
$ petalinux-build -c u-boot
$ petalinux-package --boot --fsbl --fpga --u-boot --force
這裏不用單獨來 build device-tree 其會在編譯 kernel 時一同生成
使用dtc反編譯dtb,查看dts內容是否被修改爲期望的樣子
dtc -I dtb -O dts -o system.dts ststem.dtb
將BOOT.BIN image.ub system.dtb複製到物理機備用
3 - 部署運行測試
3.1 - 覆寫新的BOOT.BIN與image.ub
啓動預製的WORK-Linux,通過ssh上傳文件
擦除QSPI FLASH上的mtd0,寫入新的BOOT.BIN
$ sudo su
$ flash_eraseall /dev/mtd0
$ dd if=BOOT.BIN of=/dev/mtdblock0
掛載eMMC上的FAT分區
清除FAT分區上原有的image.ub 和 system.dtb 將新的寫入
將磁盤緩存寫入,重啓
3.2 - 運行測試
重啓後進入之前已經編譯好放置在emmc根文件系統上的xilinx_axidma-master\outputs文件夾
insmod 掛載axidma模塊,dmesg查看報告是否正確,這裏的確檢測到了一個發送一個接受通道
運行測速例程,查看是否正常
也可以運行自己編寫的測試例程(ZYNQ7000 #4 - Linux環境下使用AXI-DMA讀取PL外接ADC)