准备在ZYNQ上使用AMP模式,我先在EBAZ4205上进行测试。
首先配置EBAZ4205
只配置NAND FLASH和UART1
因为只需要双核通信,所以没有使用PL部分。
NAND FLASH 配置
DDR配置
基本就这些,把默认的时钟和复位都去掉,中配置如下图
这样直接导出Hardware,接着运行SDK
File-->export...
File-->Lunach ...
在SDK中创建一个新项目,空工程
工程命名为cpu0_app, 处理器选择ps7_cortexa9_0,表明使用CPU0来运行此程序
选择空的工程
在创建的新工程上右击,添加新的源文件
新建的文件,为了区分方便命名为cpu0_main.c
添加代码
#include <xil_io.h>
#include <xscugic.h>
#include <xil_mmu.h>
//宏定义
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID //中断的ID
#define SHARE_BASE 0xffff0000 //共享OCM地址
#define CPU1_COPY_ADDR 0xfffffff0 //CPU1启动的跳转地址
#define CPU1_START_ADDR 0x0f100000 //CPU1的第二条指令地址
#define CPU1_ID XSCUGIC_SPI_CPU1_MASK //CPU的ID
//软中断 0-15
#define SGI_TO_CPU0 0
#define SGI_TO_CPU1 1
//SEV指令 唤醒CPU1
#define sev() __asm__("sev")
XScuGic intc;
int recv_flag = 0;
//启动CPU1
void start_cpu1()
{
//把CPU1应用程序的首地址放到 0xffff_fff0处
Xil_Out32(CPU1_COPY_ADDR, CPU1_START_ADDR);
dmb(); //内存屏障
sev(); //启动CPU1
}
int cpu1_dat = 0;
//cpu0的中断处理函数
void sgi_handler(void *cb)
{
xil_printf("cpu0 interrupt...\r\n");
recv_flag = 1;
cpu1_dat = Xil_In32(SHARE_BASE+4);
}
void cpu0_intr_init(XScuGic *intc_ptr)
{
XScuGic_Config *intc_cfg_ptr;
intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);
XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr, intc_cfg_ptr->CpuBaseAddress);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);
Xil_ExceptionEnable();
XScuGic_Connect(intc_ptr, SGI_TO_CPU0, (Xil_ExceptionHandler)sgi_handler, (void *)intc_ptr);
XScuGic_Enable(intc_ptr, SGI_TO_CPU0);
}
int main()
{
int tmp;
//禁用OCM的Cache
//S=b1 TEX=b100 AP=b11 Domain=b1111 C=b0 B=b0
Xil_SetTlbAttributes(SHARE_BASE, 0x14de2);
//这一句是不必要的,对跳转地址禁止cache
Xil_SetTlbAttributes(CPU1_COPY_ADDR, 0x14de2);
//启动cpu1
start_cpu1();
//cpu0的中断初始化
cpu0_intr_init(&intc);
while(1){
if(recv_flag){
recv_flag = 0;
xil_printf("CPU1 snd data: %d\r\n",cpu1_dat);
}else{
xil_printf("pls input a number\r\n");
scanf("%d", &tmp);
//把数据写到共享地址
Xil_Out32(SHARE_BASE, tmp);
//触发cpu1中断
XScuGic_SoftwareIntr(&intc, SGI_TO_CPU1, CPU1_ID);
}
}
}
编译没有问题生成elf文件
接着我们对内存进行划分,EBAZ4205由256MBytes的内存,我们计划最终实现linux+freertos,第一核心跑Linux,第二核心跑FreeRTOS,所以对于Linux多分一点内存,对于FreeRTOS少分一点
Linux 240MB
FreeRTOS 16MB
当前尚未修改内存范围,我们看一下cpu0_app占用的内存地址,打开工程的lscript.ld,如下图
可以看出DDR内存的起始地址 0x10_0000, 长度 0xff0_0000, 0xff0_0000是255MBytes, DDR的最低1M字节被覆盖了。
cpu0_app 设置起始地址 0x10_0000, 长度:0xF00_0000, 即 240MBytes, 留下15MBytes给CPU1使用,双击对应的字段直接修改后保存即可
至此AMP模式下cpu0的工程创建完毕,cpu1的工程创建下一篇