一、概述
本设计的设计流程如图所示
1 主核创建messageQ(master)
2 发送起始标志信号至FPGA(nwrite)
3 FPGA收到信号之后,通过SWRITE的方式向DSP写数据
4 FPGA写完数据之后,发送doorbell,触发DSP doorbell中断
5 在doorbell中断中释放信号量 开始进行数据处理
6 DSP打开从核创建的messageQ(slave) 并将各自需要的数据通过messageQ发送给各个从核
7 从核接收主核发送来的messageQ(slave) 进行数据处理
8 处理完毕之后 发送messageQ(master)至主核
9 主核接收到从核发送的messageQ(slave)之后,通过SWRITE的方式发送数据至FPGA
二、cfg文件
主要定义doorbell中断函数以及信号量
//创建SRIO doorbell硬件中断
var hwi0Params = new Hwi.Params();
hwi0Params.instance.name = "hwi0";
hwi0Params.eventId = 0x14; //CSL_GEM_INTDST_N_PLUS_16
Program.global.hwi0 = Hwi.create(4, "&SRIO_Doorbell_ISR", hwi0Params);
//创建信号量
Sem.supportsEvents = false;
Program.global.sem_db = Sem.create(0);
定义初始化入口函数
Startup.firstFxns.$add('&system_init');
三、main函数
3.1 系统初始化 system_init
void system_init(void)
{
if(DNUM == 0)
{
TSC_init(); //initialize TSC to measure cycle
// System init
CACHE_setL1PSize(CACHE_L1_32KCACHE);
CACHE_setL1DSize(CACHE_L1_32KCACHE);
CACHE_setL2Size(CACHE_0KCACHE);
CACHE_invAllL1p(CACHE_WAIT);
CACHE_wbInvAllL1d(CACHE_WAIT);
//DSP core speed: 100*10/1=1000MHz
KeyStone_main_PLL_init(100, 10, 1);
KeyStone_PASS_PLL_init(100, 21, 2);
//DDR init 66.66667*20/1= 1333
KeyStone_DDR_init (66.66667, 20, 1, NULL);
/* protect L1 as cache */
L1_cache_protection();
/*enable L1P ED and scrub whole L1P*/
L1P_EDC_setup();
/*enable LL2 EDC and scrub whole LL2*/
LL2_EDC_setup();
/*Enable MSMC EDC and setup scrubbing cycle counter= 255*1024*/
KeyStone_SL2_EDC_enable(255);
}
}
3.2 初始化队列名称
int mc_process_init (int number_of_cores)
{
int i;
/* Generate queue names based on own proc ID and total number of procs */
System_sprintf(localQueueName, "%s",MultiProc_getName(MultiProc_self()));
System_sprintf(masterQueueName,"%s",MASTER_QUEUE_NAME);
for(i = 0;i < number_of_cores; i++)
{
System_sprintf(slaveQueueName[i], "%s", MultiProc_getName(i)); //返回i核的名字
}
return 0;
}
3.3 SRIO初始化
srio_init(312.5,0xAA,3.125,PATH_4xLaneABCD);
void srio_init(float inputRefClock_MHz,unsigned int localId,float linkSpeed_GHz,SRIO_Path_CTL pathMode)
{
serdes_cfg.commonSetup.inputRefClock_MHz = inputRefClock_MHz; //参考时钟
memset(&srio_cfg, 0, sizeof(srio_cfg));
srio_cfg.blockEn.bBLK1_LSU_EN= 1;
srio_cfg.blockEn.bBLK2_MAU_EN= 1;
srio_cfg.blockEn.bBLK3_TXU_EN= 1;
srio_cfg.blockEn.bBLK4_RXU_EN= 1;
srio_cfg.srio_1x2x4x_path_control = get_path_cfg(pathMode); //设置SRIO几根线
srio_cfg.loopback_mode = SRIO_NO_LOOPBACK; //设置SRIO模式
srio_identify_used_ports_lanes(srio_cfg.srio_1x2x4x_path_control);//通道数确认
srio_cfg.device_ID_routing_config = dsp0_device_ID_routing_config;
srio_cfg.uiNumDeviceId = sizeof(dsp0_device_ID_routing_config)/sizeof(SRIO_Device_ID_Routing_Config);//8
serdes_cfg.commonSetup.loopBandwidth = SERDES_PLL_LOOP_BAND_MID;
srio_cfg.serdes_cfg = &serdes_cfg;
serdesLinkSetup.txOutputSwing = 15; /*0~15 represents between 100 and 850 mVdfpp */
serdesLinkSetup.testPattern = SERDES_TEST_DISABLED;
serdesLinkSetup.rxAlign = SERDES_RX_COMMA_ALIGNMENT_ENABLE;
serdesLinkSetup.rxInvertPolarity = SERDES_RX_NORMAL_POLARITY;
serdesLinkSetup.rxTermination = SERDES_RX_TERM_COMMON_POINT_AC_COUPLE;
serdesLinkSetup.rxEqualizerConfig= SERDES_RX_EQ_ADAPTIVE;
serdesLinkSetup.rxCDR = SERDES_RX_CDR_1;
serdesLinkSetup.txInvertPolarity = SERDES_TX_NORMAL_POLARITY;
serdesLinkSetup.linkSpeed_GHz = linkSpeed_GHz;
srio_cfg.msg_cfg = &msg_cfg;
KeyStone_SRIO_Init(&srio_cfg);
}
主要设置SRIO相关参数,速度、lane数、本地ID等相关参数。
3.4 创建任务
/* Create a unique 'master' Task if on proc 0 */
Task_Params_init(¶ms);
params.stackSize = 0x2000;
if (MultiProc_self() == 0) //核0执行主任务
{
Task_create(master_main, ¶ms, NULL);
}
Task_create(slave_main, ¶ms, NULL); //其余核执行从任务
分别创建主核和从核的任务函数 master_main, slave_main
3.5 BIOS_start( )
=======================================================================
最近新开的公众号,文章正在一篇篇的更新,
公众号名称:
玩转电子世界。
各位朋友有什么问题了可以直接在上面提问,我会一一进行解答的。
跟着阳光非宅男,一步步走进电子的世界。
关注之后回复 资料下载 关键词可以获得
免费海量的视频学习资料下载~~!
已共享的学习视频资料,共享资料正在不断更新中。。。
=======================================================================