在C6678中,各部件访问ddr都是通过同一个emif64总线,多部件同时访问呢时会有冲突的发生,最典型的一个情况是:DSP收来自其他设备srio发来的数据,同时使用edma读写本地ddr,此时会导致srio降速,最严重的情况,edma访问ddr带宽占满时,srio会降速到只有几KB/s的速率,严重拖慢srio发端的发送速率。
这个问题困扰了我许久,由于现在6678用得不甚广泛,网上能查到的信息都语焉不详,前段时间下决心解决这个问题,通过网上搜索和查阅数据手册结合,终于找到了解决方法。
使用6678的TeraNet数据网络时,片上所有的主控外设都标明了访问TeraNet总线的优先级,编程者可通过软件设定优先级,PRI数字越小表明优先级越高,0为最高。CorePacs通过UMC寄存器设定优先级,基于包DMA的外设内部也各自有设定优先级的寄存器。理论上来说,我们将SRIO的优先级设置得比所有EDMA-TC的优先级高,就可以避免SRIO被拖慢的问题。
Srio文档中找到一个名为CBA_TRANS_PRI 的寄存器位域,这3个bit位域外设设定控制寄存器PER_SET_CNTL上,地址偏移为0x0014(srio配置寄存器的基地址为0x02620384),该字段主要用于设置内部总线SRIO的优先级(CSDN:TMS320C645x DSP SRIO寄存器(一))
EDMA有好几级可以设置优先级,如下图,我们关注的是system优先级(即访问内部总线的优先级)。每个TC都有一个可编程的system优先级寄存器,叫做QUEPRI寄存器。
下面为修改srio和edma访问数据网络总线优先级的代码,将srio优先级修改为最高0,edma优先级修改为4。
// 修改srio优先级 CSL_SrioHandle srioHandle = CSL_SRIO_Open(0); //获取srio句柄 CSL_SRIO_SetTransactionPriority(srioHandle, 0); //更改优先级为0 CSL_Edma3Handle hModule; CSL_Edma3Obj edmaObj; CSL_Edma3Context context; CSL_Status sta; // 修改edma优先级,遍历3个CC int i,j; for (i=0; i<3; i++) { // Module Level Open hModule = CSL_edma3Open(&edmaObj, i, NULL, &sta); for (j=0; j<4; j++) { // Maps Event Queue 2 to Priority 4 CSL_edma3SetEventQueuePriority(hModule, j, 4); //更改优先级为4 } } // TODO:再读一遍寄存器,确认修改成功 |
经实测,修改优先级后,srio和edma同时访问ddr时,srio速率几乎不降,成功解决。