前言
zynq 7000 一般有2個cpu (arm A9),我們一般都用一個cpu0,本實驗讓2個cpu 都運行起來,cpu0 運行操作系統petalinux 2018.2, cpu1: 裸機流水燈。同時通過共享內存的方式,實現2個核之間的交互。
關于zynq 雙核運行的官方文檔有如下3篇:
xapp1078-amp-linux-bare-metal.pdf
xapp1079-amp-bare-metal-cortex-a9.pdf
ug1186-zynq-openamp-gsg.pdf
我們這個實驗對應xapp1078, 但文檔對應petalinux2014 的版本,有點太老了,而我的實驗是在petalinux2018.2 上完成的。
需要掌握的知識
1:會做petalinux 2018.2 或其他版本的啟動制作。
2:熟悉 zynq 7000 AMP模式 雙裸核CPU同時運行,因為這個比較簡單,可以作為本實驗的熱身。
硬件平臺的建立
硬件工程的建立是在Vivado2018.2 上完成的。其實要求很簡單,符合linux下流水燈實驗的要求即可,當然還需要掛接上SD卡。
裸機流水燈工程的準備和驗證
這個流水燈工程是建立運行在cpu1上的,存放地址在0x1e00_0000,工程的建立請看:zynq 7000 AMP模式 雙裸核CPU同時運行。鏈接里的工程建立的存放地址是0x1000_0000,但我們這里cpu0 要運行petalinux2018.2 ,所以設置得比較高。
程序的代碼做了適當修改如下:
cpu1的led.c
?
#include#include "platform.h" #include "xil_printf.h" #include "xparameters.h" #include "xil_io.h" #include "sleep.h" #define MY_IP 0x41200000 #include "xil_mmu.h" #define COM_VAL (*(volatile unsigned int*)(0xffff0000)) #define COM_VAL1 (*(volatile unsigned int*)(0xffff0004)) #define COM_VAL2 (*(volatile unsigned int*)(0xffff0008)) int main() { u32 Ledwidth; u32 count; Xil_SetTlbAttributes(0xffff0000,0x14de2); COM_VAL=0; COM_VAL1=0; count=0; ? while (1) ? { ? for (Ledwidth = 0x0; Ledwidth < 4; Ledwidth++) ? { ? Xil_Out32(MY_IP,1 << Ledwidth); ? COM_VAL1=1< ?
cpu0 的驗證程序 helloworld.c
?
#include#include "xil_printf.h" #include "sleep.h" #include "xil_mmu.h" #define COM_VAL (*(volatile unsigned int*)(0xffff0000)) #define COM_VAL1 (*(volatile unsigned int*)(0xffff0004)) #define COM_VAL2 (*(volatile unsigned int*)(0xffff0008)) int main() { ? int i=0; ? Xil_SetTlbAttributes(0xffff0000,0x14de2); ? COM_VAL=0; ? COM_VAL1=0; ? while (1) ? { ? i++; ? COM_VAL=i; ? ? printf("%d: Hello led=%d cpu1=%d ",i,COM_VAL1,COM_VAL2); ? ? sleep(2); ? } ? return 0; } 12345678910111213141516171819202122 ?
驗證程序一定要看到程序正常運行,并且復制到sd卡運行。特別是那個cpu1地址改為了0x1e00_0000,在fsbl 里的那個CPUSTARTMEM 記得改為0x1e000000。看到SD卡啟動后能正常運行。有流水燈,還有helloworld顯示。led 的顯示被關閉了。
我開始沒有好好驗證,發現linux 下沒有流水燈,只好返回驗證才發現其中的一些錯誤。
petalinux 2018.2 工程的建立
利用相同的hdf 文件建立一個SD卡上運行的petalinux。可以先不做修改制作BOOT.BIN 和image.ub ,復制到SD卡,測試petalinux 能夠正常啟動。
然后我們在petalinux 里做2個地方的修改。
1:需要保留cpu1 流水燈裸機所占用的DDR空間修改的文件名是system-user.dtsi , 文件的目錄是~/alinx/cnc7a/project-spec/meta-user/recipes-bsp/device-tree/files
我的工程目錄是~/alinx/cnc7a/,所以你的應該是:工程目錄/project-spec/meta-user/recipes-bsp/device-tree/files
文件內容如下,就是添加保留ddr,或者叫reserved-memory。
?
/include/ "system-conf.dtsi" / { ? reserved-memory { ? ? #address-cells = <1>; ? ? #size-cells = <1>; ? ? ranges; ? ? ? reserved: buffer@0x1e000000 { ? ? ? ? no-map; ? ? ? ? reg = <0x1e000000 0x00400000>; ? ? }; ? }; ? ? reserved-driver@0 { ? ? compatible = "xlnx,reserved-memory"; ? ? memory-region = <&reserved>; ? }; }; 123456789101112131415161718?
如果不保留這個空間,linux 就會沖掉我們的cpu1的裸機流水燈程序
做了這個修改,來測試下我們的系統做得怎么樣了,可以雙核啟動了嗎。
petalinux-build 成功后,我們需要更改我們的打包方案了,我們需要把cpu1led 流水燈裸機程序加上去,并且啟動流水燈程序。
直接用petalinux 下的打包程序,我不知道怎么啟動流水燈程序,所以我轉到sdk 下的打包程序。
打包程序包括流水燈程序
其實很簡單,linux 下需要的是system.bit, u-boot.elf, image.ub。把這幾個文件通過共享的方式,復制到windows 的共享目錄下。
然后我們繼續使用雙核裸機的打包流程,只是把cpu0 部分替換成llinux下形成的u-boot.elf。流文件也用linux 下的,其實應該也可以用sdk 下的,我這個沒測試。
看看打包的界面如下:
這樣就形成了BOOT.BIN。把這個BOOT.BIN和image.ub復制到SD卡,然后測試啟動。
看到流水程序啟動了,然后linux 啟動了。但linux 啟動的時候,流水燈就不流了。
2:設置linux 為 單核
正常情況下,linux 為雙核運行。上面的內存保留沒有沖掉程序,但linux啟動時占用了cpu1,所以流水燈被停掉了。查找xapp1078,page 21/34 上這樣寫的:
Creating Linux Device TreeRefer to the wiki pages at http://wiki.xilinx.com for instructions to compile the device tree. Thedevice tree needs to be changed to instruct Linux SMP to only use one CPU and to decreasethe amount of memory available to Linux. A copy of the modified devicetree.dts andcompiled devicetree.dtb is included at designgenerated_filesoot.The commands used are listed here:
Copy the zynq-zc702.dts device tree included with the downloaded linux kernel to anew location:cp arch/arm/boot/dts/zynq-zc702.dts
Modify the copied device tree to reduce the memory. The memory entry should be:memory {device_type = “memory”;reg = <0x00000000 0x30000000>;};
Set the maximum number of CPUs to 1 by adding maxcpus=1 to the bootargs assignment:bootargs = “console=ttyPS0,115200 maxcpus=1 root=/dev/ram rwip=::::dhcp earlyprintk”;
Compile the new devicetree.dts to create devicetree.dtb as described in the wikiscripts/dtc/dtc -I dts -O dtb -o /devicetree.dtb/zynq-zc702.dts.
把maxcpus=1 設置進設備樹就成了關鍵,xapp1078 這么寫了,我卻不知怎么做,困惑了我好幾天。我在xilinx 論壇上問到了。下面是問題鏈接:
https://forums.xilinx.com/t5/Embedded-Linux/how-to-add-maxcpus-1-to-dt/m-p/1127901#M43760
知道了,其實很簡單,不是去修改設備樹,如下操作就可以。
petalinux-config
界面出現后,選擇 DTG Setting ----->
在出現的子界面里選擇 Kernel Bootargs ----->
取消那個generate boot args automatically,轉到下行回車,或者直接出現輸入界面
在這個界面里添加 maxcpus=1, 如下圖
這樣操作保存后后,再petalinux-build ,按上面打包方法打包,在petalinux 2018.2 啟動后, 流水燈在繼續運行。
這說明cpu0 核運行petalinux2018.2 ,cpu1 運行裸機流水燈成功了。
petalinux 核和裸機流水燈核的交互
在上面的流水燈代碼里,
?
COM_VAL1=1<?
每隔1秒延遲,COM_VAL2 會+1, 而COM_VAL1 則保存燈控命令,1,2,4,8。
在linux 里編程讀取到這些值,就完成了我們的交互實驗。linux 里能讀到裸機程序的變量。
linux 里有個io口測試的程序,就是說不用編程就有,叫做devmem。
在petalinux 終端輸入 devmem 0xffff0008,可以看到計數值不斷增加,可以不斷重復上個命令,反正隔幾秒就加幾。
在petalinux 終端輸入 devmem 0xffff0004 ,就可以看到燈控命令1,2,4,8中之一。
為什么是0xffff0008,這是我們共享宏定義里確定的。
這就說明數據的交互完全成功。
編輯:黃飛
?
評論
查看更多