This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6678多核使用EDMA搬移数据失败的问题!!!!



TI工程师您好,我使用的是C6678,利用EDMA将数据从DDR3搬移到L2,四个核进行此操作,均使用不同的channel,参考的是edma_test.c的程序,使用global_region, 同时使用时出现数据搬移错误的问题,当使用不同的CC时,可以同时进行数据搬移,但是CC只有三个,我有四个核同时使用,故必须有两个核使用同一个CC,参考了如下帖子:

www.deyisupport.com/.../9092.aspx
e2echina.ti.com/.../104965
这两篇帖子,将
CSL_edma3MapDMAChannelToParamBlock(hModule,channelNum,channelNum);//这里把不同的channel映射到不同的PaRAM

hParamPing = CSL_edma3GetParamHandle(hChannel,channelNum,&status);//这里设置不同的PaRAM
这样修改之后可以传输,但是有时候会卡在
while (!(regionIntr.intr & 0x1));//多核同时运行时有时候会卡在这个地方
参考第二篇帖子中说是要修改intr,和intrh
请问是修改这个吗?需要怎么修改呢?
regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
regionIntr.intr = 0x1; //多核同时使用的时候这个地方也需要修改吗?
regionIntr.intrh = 0x0;

  • 请问这些channel使用同一个TCC吗?建议不同的channel使用不同的TCC。
  • - Polls on IPR bit 0 (Since TCC for PING is 0)
    - Clear the pending bit
    - Manually triggers the channel 'channelNum' (This should be PONG)
    - Polls on IPR bit 1 (Since TCC for PONG is 1)

    do {
    /* Poll on interrupt bit 0 */
    CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
    } while (!(regionIntr.intr & 0x1));

    /* Clear interrupt bit 0 */
    if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr) != CSL_SOK)
    {
    printf("Error: EDMA clear interrupt bit 0 command is failed\n");
    return -1;
    }

    /* Mapping channel 0 to event queue 1 */
    if (CSL_edma3HwChannelSetupQue(hChannel,CSL_EDMA3_QUE_1) != CSL_SOK)
    {
    printf("Error: EDMA channel setup queue is failed\n");
    return -1;
    }

    /* Manually trigger the channel */
    if (CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL) != CSL_SOK)
    {
    printf("Error: EDMA channel set command is failed\n");
    return -1;
    }

    regionIntr.region = regionNum;
    regionIntr.intr = 0;
    regionIntr.intrh = 0;

    /* Poll on interrupt pend bit 1 */
    do {
    CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
    } while (!(regionIntr.intr & 0x2));
    上面是截取的edma_test中的一段代码,可以参考修改。使不同的通道对应不同的IPR[TCC].
  • 您好,我的代码是这样的,没有进行ping pong了,一次只往一个地址传输,麻烦您帮忙看一下
    int Edma3_SYNC_AB(int aCnt, int bCnt, int cCnt, int srcBidx, int dstBidx, float* srcaddr, float* dstaddr, int instNum, int channelNum)
    {
    CSL_Edma3Handle hModule;
    CSL_Edma3Obj edmaObj;
    CSL_Edma3ParamHandle hParamPing;

    CSL_Edma3ChannelObj chObj;
    CSL_Edma3CmdIntr regionIntr;
    CSL_Edma3ChannelHandle hChannel;
    CSL_Edma3ParamSetup myParamSetup;
    CSL_Edma3Context context;
    CSL_Edma3ChannelAttr chAttr;
    CSL_Status status;

    int srcCidx=0;
    int dstCidx=0;

    CSL_edma3Init(&context);
    /* Open the EDMA Module using the provided instance number */
    hModule = CSL_edma3Open(&edmaObj, instNum, NULL, &status);
    /* Channel open */
    chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL;
    chAttr.chaNum = channelNum;
    hChannel = CSL_edma3ChannelOpen(&chObj, instNum, &chAttr, &status);

    if(!instNum)
    {
    /* For first EDMA instance (通道控制器CC0) there are only 2 TCs(传输控制数) and
    * 2 event queues (队列事件数)
    * Modify the channel default queue setup from 0 to 1
    */
    if (CSL_edma3HwChannelSetupQue(hChannel,CSL_EDMA3_QUE_1) != CSL_SOK)
    {
    printf ("Error: EDMA channel setup queue failed\n");
    return -1;
    }
    }
    else
    {
    /* For EDMA instance 1 and 2 maximum of 4 TCs and 4 event queues are supported
    * Change Channel Default queue setup from 0 to 3
    */
    if (CSL_edma3HwChannelSetupQue(hChannel,CSL_EDMA3_QUE_0) != CSL_SOK)
    {
    printf ("Error: EDMA channel setup queue failed\n");
    return -1;
    }
    }

    CSL_edma3MapDMAChannelToParamBlock(hModule,channelNum,channelNum);//这里把不同的channel映射到不同的PaRAM

    hParamPing = CSL_edma3GetParamHandle(hChannel,channelNum,&status);//这里设置不同的PaRAM

    myParamSetup.option = 0x0010000C;
    myParamSetup.srcAddr = (Uint32)srcaddr;
    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(aCnt, bCnt);
    myParamSetup.dstAddr = (Uint32)dstaddr;
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(srcBidx,dstBidx); //这个地方的BIdx的单位是字节
    myParamSetup.linkBcntrld= 0x0000ffff;
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(srcCidx,dstCidx);
    myParamSetup.cCnt = cCnt;

    CSL_edma3ParamSetup(hParamPing,&myParamSetup);
    /* Interrupt enable (Bits 0-1) for the global region interrupts */
    regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
    regionIntr.intr = 0x1; //多核同时使用的时候这个地方也需要修改吗?
    regionIntr.intrh = 0x0;

    CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);
    /* Trigger channel 启动发送*/
    CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);
    regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
    regionIntr.intr = 0x0;
    regionIntr.intrh = 0x0;
    do
    {
    CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
    }
    while (!(regionIntr.intr & 0x1));//多核同时运行时有时候会卡在这个地方

    CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR,&regionIntr);

    CSL_edma3ChannelClose(hChannel);

    CSL_edma3Close(hModule);

    return 0;
    }
  • shine,TCC是在myParamSetup.option = 0x0010000C;中被设定的吗?如果是的话那么我所有的channel使用的都是同一个TCC,我需要怎么修改呢?
  • 不同的param.option里的TCC设置不同的值,这样避免多个channel同时置上相同的IPR bit。
  • shine,我昨天尝试使用shadow region,每一个核选择不同的region,然后在DRAE寄存器中只将使用到的通道位置一,每一个核选择的TCC的值也不同,这样子是不是可以实现多核同时使用EDMA,不会出现同时对IPR置位清除的操作
  • shine,这样做是可以避免相同的IPR bit被同时置位,但是当有一个核的channel使用
    CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr)对IPR寄存器的值进行清除后,会导致另外一个核的程序卡在
    do
    {
    CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);//读取IPR寄存器
    }
    while (!(regionIntr.intr & 0x2));这个位置,这有什么办法解决吗?