ZYNQ 雙核運行並交互,一個linux,一個裸核

zynq 7000 通常有2個cpu (arm A9),咱們通常都用一個cpu0,本實驗讓2個cpu 都運行起來,cpu0 運行操做系統petalinux 2018.2, cpu1: 裸機流水燈。同時經過共享內存的方式,實現2個核之間的交互。linux

關於zynq 雙核運行的官方文檔有以下3篇:編程

xapp1078-amp-linux-bare-metal.pdfubuntu

xapp1079-amp-bare-metal-cortex-a9.pdfwindows

ug1186-zynq-openamp-gsg.pdfapp

咱們這個實驗對應xapp1078, 但文檔對應petalinux2014 的版本,有點太老了,而個人實驗是在petalinux2018.2 上完成的。工具

前提條件

1:會作petalinux 2018.2 或其餘版本的啓動製做。若是不會請看:petalinux 2018.2 在ubuntu 16 下的工程製做並啓動實驗測試

2:熟悉 zynq 7000 AMP模式 雙裸核CPU同時運行,由於這個比較簡單,能夠做爲本實驗的熱身。ui

硬件平臺的創建

硬件工程的創建是在Vivado2018.2 上完成的。其實要求很簡單,符合linux下流水燈實驗的要求便可,固然還須要掛接上SD卡。個人硬件就用的那個流水燈實驗的工程,如有不清楚,請參考:spa

zynq 7000 petalinux 2018.2下的流水燈實驗操作系統

裸機流水燈工程的準備和驗證

這個流水燈工程是創建運行在cpu1上的,存放地址在0x1e00_0000,工程的創建請看:zynq 7000 AMP模式 雙裸核CPU同時運行。連接裏的工程創建的存放地址是0x1000_0000,但咱們這裏cpu0 要運行petalinux2018.2 ,因此設置得比較高。

程序的代碼作了適當修改以下:

cpu1的led.c

#include <stdio.h>
#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<<Ledwidth;
    		  count++;
    		  COM_VAL2=count;
    		  //printf("led=%x, cpu0 count1=%d cpu1=%d\n\r",1<<Ledwidth,COM_VAL,COM_VAL2);
    		  sleep(1);
    		}
       	}
    return 0;
}

cpu0 的驗證程序 helloworld.c

#include <stdio.h>
#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\n\r",i,COM_VAL1,COM_VAL2);
      sleep(2);
    }
    return 0;
}

驗證程序必定要看到程序正常運行,而且複製到sd卡運行。特別是那個cpu1地址改成了0x1e00_0000,在fsbl 裏的那個CPUSTARTMEM 記得改成0x1e000000。看到SD卡啓動後能正常運行。有流水燈,還有helloworld顯示。led 的顯示被關閉了。

我開始沒有好好驗證,發現linux 下沒有流水燈,只好返回驗證才發現其中的一些錯誤。

petalinux 2018.2 工程的創建

利用相同的hdf 文件創建一個SD卡上運行的petalinux。能夠先不作修改製做BOOT.BIN 和image.ub ,複製到SD卡,測試petalinux 可以正常啓動。能夠參考:petalinux 2018.2 在ubuntu 16 下的工程製做並啓動實驗

而後咱們在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>;
   };
};

若是不保留這個空間,linux 就會沖掉咱們的cpu1的裸機流水燈程序

作了這個修改,來測試下咱們的系統作得怎麼樣了,能夠雙核啓動了嗎。

petalinux-build 成功後,咱們須要更改咱們的打包方案了,咱們須要把cpu1led 流水燈裸機程序加上去,而且啓動流水燈程序。

直接用petalinux 下的打包程序,我不知道怎麼啓動流水燈程序,因此我轉到sdk 下的打包程序。

打包程序包括流水燈程序

其實很簡單,linux 下須要的是system.bit, u-boot.elf, image.ub。 把這幾個文件經過共享的方式,複製到windows 的共享目錄下。若是不會共享,能夠看看:虛擬機VMware時,如何在Windows和Ubuntu之間共享文件夾

而後咱們繼續使用雙核裸機的打包流程,只是把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 Tree
Refer to the wiki pages at http://wiki.xilinx.com for instructions to compile the device tree. The
device tree needs to be changed to instruct Linux SMP to only use one CPU and to decrease
the amount of memory available to Linux. A copy of the modified devicetree.dts and
compiled devicetree.dtb is included at design\generated_files\boot.
The commands used are listed here:
1. Copy the zynq-zc702.dts device tree included with the downloaded linux kernel to a
new location:
cp arch/arm/boot/dts/zynq-zc702.dts <somewhere>
2. Modify the copied device tree to reduce the memory. The memory entry should be:
memory {
device_type = "memory";
reg = <0x00000000 0x30000000>;
};
3. 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 rw
ip=:::::eth0:dhcp earlyprintk";
4. Compile the new devicetree.dts to create devicetree.dtb as described in the wiki
scripts/dtc/dtc -I dts -O dtb -o <somewhere>/devicetree.dtb
<somewhere>/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<<Ledwidth;
count++;
COM_VAL2=count;

每隔1秒延遲,COM_VAL2 會+1, 而COM_VAL1 則保存燈控命令,1,2,4,8。

在linux 裏編程讀取到這些值,就完成了咱們的交互實驗。linux 裏能讀到裸機程序的變量。

linux 裏有個io口測試的程序,就是說不用編程就有,叫作devmem。個人博客裏有他源代碼分析,能夠查看 Linux驅動開發經常使用調試工具 devmem之代碼分析

在petalinux 終端輸入 devmem 0xffff0008,能夠看到計數值不斷增長,能夠不斷重複上個命令,反正隔幾秒就加幾。

在petalinux 終端輸入 devmem 0xffff0004 ,就能夠看到燈控命令1,2,4,8中之一。

爲何是0xffff0008,這是咱們共享宏定義裏肯定的,也能夠看看  ZYNQ 7000 AMP模式雙裸核運行 雙方共享內存交互,這文介紹得比較詳細。

這就說明數據的交互徹底成功。

介紹到此,但願對你有用。

相關文章
相關標籤/搜索