6678多核加载启动实现主要是通过0核完成。
具体实现是DSP上电通过I2C, SPI, EMIF等接口将应用程序加载到核心0运行,然后在核心0运行代码里实现另外7个核的启动地址指定和发送IPC中断唤醒其余7核。
启动实现详见如下:
1、寄存器定义
// CorePac0-7 IPC 触发寄存器(IPCGRx)
#define IPCGR_0_REGS (*((volatile unsigned int *)(0x02620240)))
#define IPCGR_1_REGS (*((volatile unsigned int *)(0x02620244)))
#define IPCGR_2_REGS (*((volatile unsigned int *)(0x02620248)))
#define IPCGR_3_REGS (*((volatile unsigned int *)(0x0262024C)))
#define IPCGR_4_REGS (*((volatile unsigned int *)(0x02620250)))
#define IPCGR_5_REGS (*((volatile unsigned int *)(0x02620254)))
#define IPCGR_6_REGS (*((volatile unsigned int *)(0x02620258)))
#define IPCGR_7_REGS (*((volatile unsigned int *)(0x0262025C)))
// 核0~核7 魔术地址(L2地址后4字节)
#define CORE_0_MAGIC_ADDR (*((volatile unsigned int *)(0X1087FFFC)))
#define CORE_1_MAGIC_ADDR (*((volatile unsigned int *)(0X1187FFFC)))
#define CORE_2_MAGIC_ADDR (*((volatile unsigned int *)(0X1287FFFC)))
#define CORE_3_MAGIC_ADDR (*((volatile unsigned int *)(0X1387FFFC)))
#define CORE_4_MAGIC_ADDR (*((volatile unsigned int *)(0X1487FFFC)))
#define CORE_5_MAGIC_ADDR (*((volatile unsigned int *)(0X1587FFFC)))
#define CORE_6_MAGIC_ADDR (*((volatile unsigned int *)(0X1687FFFC)))
#define CORE_7_MAGIC_ADDR (*((volatile unsigned int *)(0X1787FFFC)))
// 寄存器锁
#define KICK0 (*((volatile unsigned int *)(0x02620038)))
#define KICK1 (*((volatile unsigned int *)(0x0262003C)))
#define KICK0_UNLOCK (0x83E70B13)
#define KICK1_UNLOCK (0x95A4F1E0)
#define KICK_LOCK (0x1)
2、获取入口地址
该实例实现多核启动用的是一个公用工程,所以启动入口地址只有一个。若是多个工程,则各核启动入口地址不同,具体是看自己如何定义内存分配。
如口地址如何获取?在编译后工程Debug目录下。**.map文件有指定,如下图
官方指定启动入口地址为 _c_int00 ,也可自定义指定地址,具体实现在工程里新建一个 **.cmd文件,内容如下:
-heap 0x8000
-stack 0x20000
MEMORY
{
}
SECTIONS
{
//.text:_c_int00 > DDR3 START(BootMagic)
.text:_c_int00 > 0x80000000 START(BootMagic)
}
3、加载各核启动地址,并发送IPC中断
//指定起始地址,在.cmd文件内定义
extern unsigned int _c_int00(void);
extern unsigned int far BootMagic;
void Load_Core_app_Start()
{
// 解锁寄存器
KICK0 = KICK0_UNLOCK;
KICK1 = KICK1_UNLOCK;
//加载核1~核7魔术地址
CORE_1_MAGIC_ADDR = (unsigned int )_c_int00;
CORE_2_MAGIC_ADDR = (unsigned int )_c_int00;
CORE_3_MAGIC_ADDR = (unsigned int )_c_int00;
CORE_4_MAGIC_ADDR = (unsigned int )&BootMagic;
CORE_5_MAGIC_ADDR = (unsigned int )&BootMagic;
CORE_6_MAGIC_ADDR = (unsigned int )&BootMagic;
CORE_7_MAGIC_ADDR = (unsigned int )&BootMagic;
// 向核1~核7发送IPC启动运行中断
IPCGR_1_REGS = 0x01;
IPCGR_2_REGS = 0x01;
IPCGR_3_REGS = 0x01;
IPCGR_4_REGS = 0x01;
IPCGR_5_REGS = 0x01;
IPCGR_6_REGS = 0x01;
IPCGR_7_REGS = 0x01;
// 上锁寄存器
KICK0 = KICK_LOCK;
KICK1 = KICK_LOCK;
my_Delay(1000);
}
4、各核启动后向指定地址写入数据,便于查看各核是否已经启动。你也可以通过串口打印实现。
#define UIREG(x) (*((volatile unsigned int *)(x)))
void Load_Core_start_Test(unsigned char coreNum)
{
switch( coreNum )
{
case 1: UIREG(0x0C000000) = 0x11111111; break;
case 2: UIREG(0x0C000004) = 0x22222222; break;
case 3: UIREG(0x0C000008) = 0x33333333; break;
case 4: UIREG(0x0C00000C) = 0x44444444; break;
case 5: UIREG(0x0C000010) = 0x55555555; break;
case 6: UIREG(0x0C000014) = 0x66666666; break;
case 7: UIREG(0x0C000018) = 0x77777777; break;
default: break;
}
}
5、主程序入口
int main()
{
if (0 == DNUM)
{
// 通过核0启动 其它7核
Load_Core_app_Start();
}
else
{
// 其余核启动后向指定地址写数据
Load_Core_start_Test(DNUM);
}
BIOS_start(); /* does not return */
return(0);
}
6、通过仿真器加载初始化0核,并将工程加载到0核
6.1、初始化核0如下图
6.2、加载工程到核0如下图
7、运行工程
7.1、运行工程之前写地址为初始化后随机默认数据,如下图
7.2、运行后为各个核启动后向指定地址所写数据,如下图
7.3、查看各核停靠地址
通过仿真器查看各核运行停靠地址,也可以知道各核是否启动。