前言
zynq 7000 一般有2個(gè)cpu (arm A9),我們一般都用一個(gè)cpu0,本實(shí)驗(yàn)讓2個(gè)cpu 都運(yùn)行起來(lái),cpu0 運(yùn)行操作系統(tǒng)petalinux 2018.2, cpu1: 裸機(jī)流水燈。同時(shí)通過(guò)共享內(nèi)存的方式,實(shí)現(xiàn)2個(gè)核之間的交互。
關(guān)于zynq 雙核運(yùn)行的官方文檔有如下3篇:
xapp1078-amp-linux-bare-metal.pdf
xapp1079-amp-bare-metal-cortex-a9.pdf
ug1186-zynq-openamp-gsg.pdf
我們這個(gè)實(shí)驗(yàn)對(duì)應(yīng)xapp1078, 但文檔對(duì)應(yīng)petalinux2014 的版本,有點(diǎn)太老了,而我的實(shí)驗(yàn)是在petalinux2018.2 上完成的。
需要掌握的知識(shí)
1:會(huì)做petalinux 2018.2 或其他版本的啟動(dòng)制作。
2:熟悉 zynq 7000 AMP模式 雙裸核CPU同時(shí)運(yùn)行,因?yàn)檫@個(gè)比較簡(jiǎn)單,可以作為本實(shí)驗(yàn)的熱身。
硬件平臺(tái)的建立
硬件工程的建立是在Vivado2018.2 上完成的。其實(shí)要求很簡(jiǎn)單,符合linux下流水燈實(shí)驗(yàn)的要求即可,當(dāng)然還需要掛接上SD卡。
裸機(jī)流水燈工程的準(zhǔn)備和驗(yàn)證
這個(gè)流水燈工程是建立運(yùn)行在cpu1上的,存放地址在0x1e00_0000,工程的建立請(qǐng)看:zynq 7000 AMP模式 雙裸核CPU同時(shí)運(yùn)行。鏈接里的工程建立的存放地址是0x1000_0000,但我們這里cpu0 要運(yùn)行petalinux2018.2 ,所以設(shè)置得比較高。
程序的代碼做了適當(dāng)修改如下:
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 的驗(yàn)證程序 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 ?
驗(yàn)證程序一定要看到程序正常運(yùn)行,并且復(fù)制到sd卡運(yùn)行。特別是那個(gè)cpu1地址改為了0x1e00_0000,在fsbl 里的那個(gè)CPUSTARTMEM 記得改為0x1e000000??吹絊D卡啟動(dòng)后能正常運(yùn)行。有流水燈,還有helloworld顯示。led 的顯示被關(guān)閉了。
我開(kāi)始沒(méi)有好好驗(yàn)證,發(fā)現(xiàn)linux 下沒(méi)有流水燈,只好返回驗(yàn)證才發(fā)現(xiàn)其中的一些錯(cuò)誤。
petalinux 2018.2 工程的建立
利用相同的hdf 文件建立一個(gè)SD卡上運(yùn)行的petalinux??梢韵炔蛔鲂薷闹谱鰾OOT.BIN 和image.ub ,復(fù)制到SD卡,測(cè)試petalinux 能夠正常啟動(dòng)。
然后我們?cè)趐etalinux 里做2個(gè)地方的修改。
1:需要保留cpu1 流水燈裸機(jī)所占用的DDR空間修改的文件名是system-user.dtsi , 文件的目錄是~/alinx/cnc7a/project-spec/meta-user/recipes-bsp/device-tree/files
我的工程目錄是~/alinx/cnc7a/,所以你的應(yīng)該是:工程目錄/project-spec/meta-user/recipes-bsp/device-tree/files
文件內(nèi)容如下,就是添加保留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?
如果不保留這個(gè)空間,linux 就會(huì)沖掉我們的cpu1的裸機(jī)流水燈程序
做了這個(gè)修改,來(lái)測(cè)試下我們的系統(tǒng)做得怎么樣了,可以雙核啟動(dòng)了嗎。
petalinux-build 成功后,我們需要更改我們的打包方案了,我們需要把cpu1led 流水燈裸機(jī)程序加上去,并且啟動(dòng)流水燈程序。
直接用petalinux 下的打包程序,我不知道怎么啟動(dòng)流水燈程序,所以我轉(zhuǎn)到sdk 下的打包程序。
打包程序包括流水燈程序
其實(shí)很簡(jiǎn)單,linux 下需要的是system.bit, u-boot.elf, image.ub。把這幾個(gè)文件通過(guò)共享的方式,復(fù)制到windows 的共享目錄下。
然后我們繼續(xù)使用雙核裸機(jī)的打包流程,只是把cpu0 部分替換成llinux下形成的u-boot.elf。流文件也用linux 下的,其實(shí)應(yīng)該也可以用sdk 下的,我這個(gè)沒(méi)測(cè)試。
看看打包的界面如下:
這樣就形成了BOOT.BIN。把這個(gè)BOOT.BIN和image.ub復(fù)制到SD卡,然后測(cè)試啟動(dòng)。
看到流水程序啟動(dòng)了,然后linux 啟動(dòng)了。但linux 啟動(dòng)的時(shí)候,流水燈就不流了。
2:設(shè)置linux 為 單核
正常情況下,linux 為雙核運(yùn)行。上面的內(nèi)存保留沒(méi)有沖掉程序,但linux啟動(dòng)時(shí)占用了cpu1,所以流水燈被停掉了。查找xapp1078,page 21/34 上這樣寫(xiě)的:
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 設(shè)置進(jìn)設(shè)備樹(shù)就成了關(guān)鍵,xapp1078 這么寫(xiě)了,我卻不知怎么做,困惑了我好幾天。我在xilinx 論壇上問(wèn)到了。下面是問(wèn)題鏈接:
https://forums.xilinx.com/t5/Embedded-Linux/how-to-add-maxcpus-1-to-dt/m-p/1127901#M43760
知道了,其實(shí)很簡(jiǎn)單,不是去修改設(shè)備樹(shù),如下操作就可以。
petalinux-config
界面出現(xiàn)后,選擇 DTG Setting ----->
在出現(xiàn)的子界面里選擇 Kernel Bootargs ----->
取消那個(gè)generate boot args automatically,轉(zhuǎn)到下行回車,或者直接出現(xiàn)輸入界面
在這個(gè)界面里添加 maxcpus=1, 如下圖
這樣操作保存后后,再petalinux-build ,按上面打包方法打包,在petalinux 2018.2 啟動(dòng)后, 流水燈在繼續(xù)運(yùn)行。
這說(shuō)明cpu0 核運(yùn)行petalinux2018.2 ,cpu1 運(yùn)行裸機(jī)流水燈成功了。
petalinux 核和裸機(jī)流水燈核的交互
在上面的流水燈代碼里,
?
COM_VAL1=1<?
每隔1秒延遲,COM_VAL2 會(huì)+1, 而COM_VAL1 則保存燈控命令,1,2,4,8。
在linux 里編程讀取到這些值,就完成了我們的交互實(shí)驗(yàn)。linux 里能讀到裸機(jī)程序的變量。
linux 里有個(gè)io口測(cè)試的程序,就是說(shuō)不用編程就有,叫做devmem。
在petalinux 終端輸入 devmem 0xffff0008,可以看到計(jì)數(shù)值不斷增加,可以不斷重復(fù)上個(gè)命令,反正隔幾秒就加幾。
在petalinux 終端輸入 devmem 0xffff0004 ,就可以看到燈控命令1,2,4,8中之一。
為什么是0xffff0008,這是我們共享宏定義里確定的。
這就說(shuō)明數(shù)據(jù)的交互完全成功。
編輯:黃飛
?
評(píng)論
查看更多