ZYNQ双核运行简例

一、AMP运行模式

从软件的角度来看,多核处理器的运行模式有三种: 
  AMP(非对称多进程):多个核心相对独立的运行不同的任务,每个核心可能运行不同的操作系统或裸机程序,但是有一个主要核心,用来控制整个系统以及其它从核心。
  SMP(对称多进程):一个操作系统同等的管理各个内核,例如PC机。
  BMP(受约束多进程):与SMP类似,但开发者可以指定将某个任务仅在某个指定内核上执行
默认情况下,ZYNQ仅运行一个CPU,这里主要研究AMP模式下,两个CPU同时运行。

本次实验目的:
  让zynq的两个核心跑不同的程序:
    1、CPU0用UART打印消息。
    2、CPU1跑流水灯的程序。

二、创建工程

1、创建并设置bd文件

根据自己的板子创建一个zynq工程、创建一个bd文件,添加zynq的核。双击打开、选中UART和SD卡:ZYNQ双核运行简例_第1张图片
  再根据自己板子选择是否选择EMIO(如果LED连接到PL端则需要选择)和EMIO所需要的位数。
  ZYNQ双核运行简例_第2张图片
  创建完成之后:
  1、右击原理图,生成输出文件(Create HDL Wrapper) 
  2、右击原理图,生成顶层文件(Create Output Products…)
添加约束文件:

set_property PACKAGE_PIN N20 [get_ports {GPIO_0_tri_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_io[0]}]

set_property PACKAGE_PIN P20 [get_ports {GPIO_0_tri_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_io[1]}]

set_property PACKAGE_PIN P19 [get_ports {GPIO_0_tri_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_io[2]}]

set_property PACKAGE_PIN Y19 [get_ports {GPIO_0_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_io[3]}]

set_property PACKAGE_PIN V12 [get_ports {GPIO_0_tri_io[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_io[4]}]

“GPIO_0_tri_io”是在生成的顶层文件中COPY过来的、这个名字和在建立BD文件的时候引出的EMIO的名字有关系。
  然后综合、执行、产生Bit文件。

三、SDK环境

1、创建工程

AMP模式运行、重点在SDK上面:
  首先创建CPU0的“Hello world”工程。“File->new->Application Project”更改helloworld.c文件如下:

#include 
#include "platform.h"
#include "xil_printf.h"
#include "sleep.h"
int main()
{
init_platform();
while (1)
{
print("Hello World\n\r");
sleep(2);
}
cleanup_platform();
return 0;
}

每2S打印信息,用于提示CPU0一直在运行。

CPU1工程设置(注意箭头处processor选择1、表示CPU1):
ZYNQ双核运行简例_第3张图片
创建完成后修改主函数内容如下:

#include "xgpiops.h"
#include "sleep.h"
int main()
{
static XGpioPs psGpioInstancePtr;
XGpioPs_Config* GpioConfigPtr;
int xStatus;
GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
if(GpioConfigPtr == NULL) return XST_FAILURE;
xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr,GpioConfigPtr->BaseAddr);
if(XST_SUCCESS != xStatus) return -1;

XGpioPs_SetDirectionPin(&psGpioInstancePtr, 54,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 55,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 56,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 57,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 54,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 55,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 56,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 57,1);
while(1)
{
XGpioPs_WritePin(&psGpioInstancePtr, 54, 1);
sleep(1);
XGpioPs_WritePin(&psGpioInstancePtr, 54, 0);
XGpioPs_WritePin(&psGpioInstancePtr, 55, 1);
sleep(1);
XGpioPs_WritePin(&psGpioInstancePtr, 55, 0);
XGpioPs_WritePin(&psGpioInstancePtr, 56, 1);
sleep(1);
XGpioPs_WritePin(&psGpioInstancePtr, 56, 0);
XGpioPs_WritePin(&psGpioInstancePtr, 57, 1);
sleep(1);
XGpioPs_WritePin(&psGpioInstancePtr, 57, 0);
sleep(1);
}
return 0;
}

这段程序是用来设置LED灯循环点亮。

2、设置

创建好工程之后、需要设置一些参数,才能让两个核心独立工作。
1、右击CPU1_APP_bsp选择“Board Support Package Setting”
ZYNQ双核运行简例_第4张图片
2、先点击箭头1所指的部分、然后在“2”处添加参数“-DUSE_AMP=1”(是在原有的部分末尾添加、这还少一个编译的条件)。点击“OK”
ZYNQ双核运行简例_第5张图片
3、设置DDR空间分配
  通过修改lscript.ld文件中的内容,可以改变ELF文件在存储器中的执行位置,因为ELF文件是加载到DDR中执行的,所以两个DDR地址不能重合。否则影响运行程序运行。
  打开CPU1_APP中src文件夹中的lscript.ld文件、做如下修改:
  ZYNQ双核运行简例_第6张图片
  修改加载CPU1的程序在DDR中的位置,防止和CPU0冲突;
  现在如果使用DEBUG功能的时候就能看到两个核心都在运行。

3、修改FSBL文件

如果要把程序固话到SD卡中、需要制作BOOT.bin文件,将BOOT.bin文件拷贝到SD卡中、并选择从SD卡启动才能观察到效果。
  从SD卡启动需要FSBL文件、对于双核同时运行的工程、需要在FSBL文件中修改一些参数。
  首先在FSBL中找到main.c函数、在里面添加如下代码:

#define sev() __asm__("sev")
#define CPU1STARTADR 0xFFFFFFF0
#define CPU1STARTMEM 0x20000000
void StartCpu1(void)
{
#if 1
fsbl_printf(DEBUG_GENERAL,"FSBL: Write the address of the application for CPU 1 to 0xFFFFFFF0\n\r");
Xil_Out32(CPU1STARTADR, CPU1STARTMEM);
dmb(); //waits until write has finished
fsbl_printf(DEBUG_GENERAL,"FSBL: Execute the SEV instruction to cause CPU 1 to wake up and jump to the application\n\r");
sev();
#endif
}

这段代码是添加CPU1的启动函数、和加载到DDR中的位置。
然后在main函数中调用刚刚添加的函数:
ZYNQ双核运行简例_第7张图片
找到箭头1处的位置、在后面添加箭头2处的代码(调用刚刚添加启动核心1的启动函数)。

四、从SD卡启动

从SD卡启动需要用BOOT.bin文件;
BOOT.bin文件的制作使用“Create Boot Image”工具即可:
1、右击FSBL、选择“Create Boot Image”
ZYNQ双核运行简例_第8张图片
2、依次添加CPU0_APP.elf、CPU1_APP.elf;
3、点击“Create Image”即可生成BOOT.bin。
4、拷贝BOOT.bin文件到SD卡、选择从SD卡启动即可观察到现象。

你可能感兴趣的:(ZYNQ)