大家好,我想在IPNC_RDK3.0的alg_link中添加自己的算法,由于实时性的要求,算法中涉及到的很多数据搬移需要EDMA来实现,比如DDR到L2 cache的数据搬移。我试过利用memcpy()来实现,但效率实在太低,无法满足实时性的要求。于是我查阅了关于8127的代码,
1.在sw_osd_ti_dmaOpt.c和sw_osd_ti_dma.c中涉及到了DMA的相关设置,但所有的API都是需要传递一个handle进去,而且所有的API都以SWOSD开头,但我不清楚这个handle需要怎么初始化,如何用在我的算法中。
2,在…\ipnc_rdk\ipnc_mcfw\mcfw\src_bios6\links_c6xdsp\va\valink_alg.c中的VaLink_algCopyFrames()中调用了EDMA.其中有
/* copy the frame */
edmaWidth = pObj->inQueInfo.chInfo[0].width;
edmaHeight = pObj->inQueInfo.chInfo[0].height;
/* copy Y plane */
DM81XX_EDMA3_setParams(VA_LINK_EDMA3_CH_ID, // chId
VA_LINK_EDMA3_QUEUE_ID, // dmaQueue
(UInt32)pFullFrame->addr[0][0], // srcAddr
(UInt32)pEmptyFrame->addr[0][0], // dstAddr
edmaWidth, // edmaWidth
edmaHeight, // edmaHeight
edmaWidth, // srcLineOffset
edmaWidth); // dstLineOffset
/* Trigger the edma transfer */
DM81XX_EDMA3_triggerTransfer(VA_LINK_EDMA3_CH_ID);
pEmptyFrame->timeStamp = pFullFrame->timeStamp;
于是我将该段代码添加到了Alglink_priv.c中
Int32 AlgLink_algProcessData(AlgLink_Obj * pObj)
{
extern unsigned char *frame_buffer; //frame_buffer大小为2048*1280;开辟在在DDR 的SR2上
unsigned char * current_frame;
unsigned char * temp;
int edmaWidth = 2048;
int edmaHeight = 1280;
UInt32 frameId, status;
System_LinkInQueParams *pInQueParams;
FVID2_Frame *pFrame;
FVID2_FrameList frameList;
pInQueParams = &pObj->createArgs.inQueParams;
System_getLinksFullFrames(pInQueParams->prevLinkId,
pInQueParams->prevLinkQueId, &frameList);
if (frameList.numFrames)
{
/* SCD should be done first as it requires to operate on raw YUV */
if (pObj->createArgs.enableSCDAlg) {
status = AlgLink_ScdalgProcessData(&pObj->scdAlg, &frameList, &pObj->outObj[0].bufOutQue);
if (status == FVID2_SOK) {
/* Send-out the output bitbuffer */
System_sendLinkCmd(pObj->createArgs.outQueParams.nextLink,
SYSTEM_CMD_NEW_DATA);
}
}
for(frameId=0; frameId<frameList.numFrames; frameId++) {
pFrame = frameList.frames[frameId];
if(pFrame->channelNum >= pObj->inQueInfo.numCh)
continue;
//*************************************add my alg ****************************//
/* copy the frame */
edmaWidth = pObj->inQueInfo.chInfo[0].width;
edmaHeight = pObj->inQueInfo.chInfo[0].height;
/* copy Y plane */
DM81XX_EDMA3_setParams(VA_LINK_EDMA3_CH_ID, // chId
VA_LINK_EDMA3_QUEUE_ID, // dmaQueue
(UInt32)pFrame->addr[0][0], // srcAddr
(UInt32)(frame_buffer), // dstAddr
edmaWidth, // edmaWidth
edmaHeight, // edmaHeight
edmaWidth, // srcLineOffset
edmaWidth); // dstLineOffset
/* Trigger the edma transfer */
DM81XX_EDMA3_triggerTransfer(VA_LINK_EDMA3_CH_ID);
pEmptyFrame->timeStamp = pFullFrame->timeStamp;
//判断数据搬移是否出错
current_frame = (unsigned char *)pFrame->addr[0][0];
temp = frame_buffer;
for(i=0;i<2048*1280;i++){
if(*temp !=*current_frame)
Vps_printf("wrong!!!!!!!");
current_frame++;
temp++;
}
//********************************************************************************//
// do SW OSD
if (pObj->createArgs.enableOSDAlg) {
AlgLink_OsdalgProcessFrame(&pObj->osdAlg, pFrame);
}
}
System_putLinksEmptyFrames(pInQueParams->prevLinkId,
pInQueParams->prevLinkQueId, &frameList);
}
return FVID2_SOK;
}
编译通过后发现EDMA源地址和目的地址的元素不一致,帧大小为2048*1280没有错,而且我跑的是fullfeature,valink是没有跑的;请问是我的DMA哪里设置不对吗?有谁在8127上用过EDMA的啊?求各位大神指点,小弟在此谢过了!!!
Robin Edson:
连错误打印都没有贴出来。。
另外你的那个目标地址指针指向哪的?