AMP双核通信网上一堆重复性的,就不搬运了。
vivado创建工程忽略。本工程只需要保留串口功能和mio即可,不涉及PL端。
仅记录自己的使用过程:(借鉴了原子哥和野火哥)
Vitis创建工程
创建2个platform和2个APP
ddr设置
app0
app1
添加宏定义
在platform cpu1设置中添加-DUSE_AMP=1;
- name:proc_extra_compiler_flags
- value: -g -Wall -Wextra -fno-tree-loop-distribute-patterns -DUSE_AMP=1
注意value中使用空格分开
程序思路:比较简单
添加程序
CPU0程序
· 配置共享内存地址
· 软中断初始化
· 等待接收串口数据
#include "stdio.h"
#include "xparameters_ps.h"
#include "xil_printf.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xil_mmu.h"
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define SHARE_BASE_ADDR 0xffff0000 // Shared memory base address
#define CPU1_COPY_ADDR 0xfffffff0 //存放 CPU1 应用起始地址的地址
#define CPU1_START_ADDR 0x10000000//CPU1应用的起始地址
#define CPU1_ID XSCUGIC_SPI_CPU1_MASK
#define SOFT_INTR_ID_TO_CPU0 0//CPU0的软中断ID
#define SOFT_INTR_ID_TO_CPU1 1//CPU1的软中断ID
#define sev() __asm__("sev")
XScuGic intc; //定义中断控制器实例
int rec_freq_flag = 0;
int freq_grea = 0;
//启动CPU1,用于固化程序
static void start_cpu1()
{
//向CPU1_COPY_ADDR写入CPU1应用的起始地址
Xil_Out32(CPU1_COPY_ADDR, CPU1_START_ADDR);
dmb();
sev();
}
static void soft_intr_handler(void *CallbackRef)
{
xil_printf("cpu0 recive cpu1 intr\r\n");
rec_freq_flag = 0;
}
static void cpu0_intr_init(XScuGic *intc_ptr)
{
XScuGic_Config *intc_cfg_ptr;
intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (intc_cfg_ptr == NULL) {
xil_printf("XScuGic_LookupConfig error\r\n");
return;
}
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, SOFT_INTR_ID_TO_CPU0, (Xil_ExceptionHandler)soft_intr_handler, (void *)intc_ptr);
XScuGic_Enable(intc_ptr, SOFT_INTR_ID_TO_CPU0);
}
int main()
{
xil_printf("Hello World\r\n");
Xil_SetTlbAttributes(SHARE_BASE_ADDR, 0x14de2);//禁用OCM的cache
Xil_SetTlbAttributes(CPU1_COPY_ADDR, 0x14de2);//禁用OCM的cache
// start_cpu1();//使用JTAG启动CPU1时,可以注释掉
cpu0_intr_init(&intc);//初始化CPU0的中断,来响应CPU1的中断
while (1) {
if (rec_freq_flag == 0) {
xil_printf("this is cpu0,please input a num:\r\n");
scanf("%d", &freq_grea);
xil_printf("cpu0 input num is %d\r\n", freq_grea);
Xil_Out8(SHARE_BASE_ADDR, freq_grea);
XScuGic_SoftwareIntr(&intc, SOFT_INTR_ID_TO_CPU1, CPU1_ID);
rec_freq_flag = 1;
}
}
return 0;
}
CPU1程序
#include "stdio.h"
#include "xparameters_ps.h"
#include "xil_printf.h"
#include "xgpiops.h"
#include "xil_mmu.h"
#include "xil_exception.h"
#include "xscugic.h"
#include "sleep.h"
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define SHARE_BASE_ADDR 0xffff0000 // Shared memory base address
#define CPU0_ID XSCUGIC_SPI_CPU0_MASK
#define SOFT_INTR_ID_TO_CPU0 0//CPU0的软中断ID
#define SOFT_INTR_ID_TO_CPU1 1//CPU1的软中断ID
#define PS_LED1 0
#define PL_LED1 55
#define input 0
#define output 1
XGpioPs gpiops_inst;
XScuGic Intc; //定义中断控制器实例
int soft_intr_flag = 0;
int freq_gear = 1000;
static void led_init()
{
xil_printf("led init\r\n");
XGpioPs_Config *gpiops_cfg_ptr;
gpiops_cfg_ptr = XGpioPs_LookupConfig(0);
XGpioPs_CfgInitialize(&gpiops_inst, gpiops_cfg_ptr, gpiops_cfg_ptr->BaseAddr);
XGpioPs_SetDirectionPin(&gpiops_inst, PS_LED1, output);
XGpioPs_SetOutputEnablePin(&gpiops_inst, PS_LED1, 1);
XGpioPs_WritePin(&gpiops_inst, PS_LED1, 0);
}
static void soft_intr_handler(void *CallbackRef)
{
xil_printf("cpu1 recive cpu0 intr\r\n");
soft_intr_flag = 1;
}
static void cpu1_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, SOFT_INTR_ID_TO_CPU1, (Xil_ExceptionHandler)soft_intr_handler, (void *)intc_ptr);
XScuGic_Enable(intc_ptr, SOFT_INTR_ID_TO_CPU1);
}
int main()
{
Xil_SetTlbAttributes(SHARE_BASE_ADDR, 0x14de2);//禁用OCM的cache
led_init();
cpu1_intr_init(&Intc);
while (1) {
if (soft_intr_flag) {
freq_gear = Xil_In8(SHARE_BASE_ADDR);
xil_printf("cpu1 recive freq gear: %d\r\n", freq_gear);
XScuGic_SoftwareIntr(&Intc, SOFT_INTR_ID_TO_CPU0, CPU0_ID);
soft_intr_flag = 0;
}
XGpioPs_WritePin(&gpiops_inst, PS_LED1, 1);
usleep(freq_gear * 1000);
XGpioPs_WritePin(&gpiops_inst, PS_LED1, 0);
usleep(freq_gear * 1000);
}
return 0;
}
下载程序
这里选择的是使用app1下载
点击加号,选择处理器核elf文件