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.

TDA4VEN-Q1: TDA4 VEN DMA COPY

Part Number: TDA4VEN-Q1

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1591094/tda4ven-q1-tda4-ven-dsp-udma

The previous DMA copy has been verified to be normal, but in subsequent development,a phenomenon occurred where after running for a period of time, it would appear in
SemanticPend (&d_udmaDoneSem, SystemP_WAITFOROVER) "permanently waits,Cannot proceed downwards. If SystemP_WAITFOROVER is replaced with a fixed time, there will be several normal transfers followed by one timeout exit.
static int32_t App_udmaMemcpy2D(tivxImgSelectParams *prms, const img_select_2d_copy_params_t *params)

{
    int32_t retVal = UDMA_SOK;
    uint64_t pDesc;
    uint32_t trRespStatus;
    uint64_t trpdMemPhy;
    
    /* Initialize TRPD for 2D copy */
    App_udmaTrpdInit2D(prms->udmaChHandle, prms->udmaTrpdMem, params);
    
    trpdMemPhy = (uint64_t) Udma_defaultVirtToPhyFxn(prms->udmaTrpdMem, 0U, NULL);
    
    /* Submit TRPD to channel */
    retVal = Udma_ringQueueRaw(Udma_chGetFqRingHandle(prms->udmaChHandle), trpdMemPhy);
    
    if (retVal != UDMA_SOK)
    {
        VX_PRINT(VX_ZONE_ERROR,"Failed to submit TRPD to UDMA channel\r\n");
        return retVal;
    }

    /* Wait for completion */
    int status =SemaphoreP_pend(&prms->udmaDoneSem, 5000);
    VX_PRINT(VX_ZONE_ERROR,"SemaphoreP_pend %d \r\n",status);

    retVal = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(prms->udmaChHandle), &pDesc);
    if (retVal != UDMA_SOK)
    {
        VX_PRINT(VX_ZONE_ERROR,"Failed to dequeue from completion ring\r\n");
        return retVal;
    }

    /* Check TR response status */
    CacheP_inv(prms->udmaTrpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD);
    trRespStatus = UdmaUtils_getTrpdTr15Response(prms->udmaTrpdMem, 1U, 0U);
    if (CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE != trRespStatus)
    
    {
        VX_PRINT(VX_ZONE_ERROR,"UDMA 2D transfer failed with status: %d\r\n", trRespStatus);
        retVal = UDMA_EFAIL;
        return retVal;
    }

    return retVal;
}
 

[C7x_1 ] [32.895672][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend 0 
[C7x_1 ] [40.040704][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend 0 
[C7x_1 ] [40.041648][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend 0 
[C7x_1 ] [40.074899][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend 0 
[C7x_1 ] [47.404439][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend -2 
[C7x_1 ] [53.203934][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend -2 
[C7x_1 ] [53.205441][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend 0 
[C7x_1 ] [60.143846][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend -2 
[C7x_1 ] [67.588068][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend -2 
[C7x_1 ] [72.633436][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend -2 
[C7x_1 ] [72.634057][VX_ZONE_ERROR][App_udmaMemcpy2D:247] SemaphoreP_pend 0 

  • Hi,

    The expert assigned to your query is currently on vacation. Please expect a response by early next week.

    Best Regards,
    Sudheer

  • Got it, thanks!

  • Hi,

    The call to the function "SemaphoreP_pend(&prms->udmaDoneSem, SemaphoreP_WAIT_FOREVER)" results in the task hanging as there was no semaphore post response to the function. The use of finite time in the functions results in some of the transfers to be completed and results in failing of some of the transfers as it was not completed in the specified time. The most probable cause of the hang could be that multiple tasks are sharing the same semaphore.

    Regards,
    Ben Eapen Thomas

  • I checked trRespStatus during timeout and it was correct.

    It's indeed a semaphore quantity issue, but I don't know why. I only have one DMA copy thread, it may be due to an impact from elsewhere.

    Even though I have set UDMA_EVENT_MODE_EXCLUSIVE and the highest priority

        UdmaEventPrms_init(&cqEventPrms);
        cqEventPrms.eventType = UDMA_EVENT_TYPE_DMA_COMPLETION;
        cqEventPrms.eventMode = UDMA_EVENT_MODE_EXCLUSIVE;
        cqEventPrms.chHandle = g_udmaChHandle;
        cqEventPrms.masterEventHandle = Udma_eventGetGlobalHandle(&gUdmaDrvObj[CONFIG_UDMA0]);
        cqEventPrms.eventCb = gConfigUdma0BlkCopyCqEventCb[0];
        cqEventPrms.appData = NULL;  // Pass prms as app data to callback
        cqEventPrms.intrPriority = 0U; 

  • Hi,

    Are you using any other module with this DMA transfer? Could you please stop those and check with this DMA transfer only?

    Regards,
    Sivadeep

  • Hi,

    I discovered how to reproduce the semaphore blocking method.

    I wrote a test code:

    int32_t testApp_udmaMemcpy2D()
    {
        int32_t         retVal = UDMA_SOK;
        uint64_t        pDesc;
        uint32_t        trRespStatus;
        uint64_t        trpdMemPhy;
        img_select_2d_copy_params_t params;
        params.dest_addr =  (uint64_t) Udma_defaultVirtToPhyFxn(testdest, 0U, NULL);;
        params.dest_pitch = 240*4;
        params.src_addr =  (uint64_t) Udma_defaultVirtToPhyFxn(testsrv, 0U, NULL);;
        params.src_pitch = 240*4;;
        params.width = 240;
        params.height = 595;
        
        /* Initialize TRPD for 2D copy */
        App_udmaTrpdInit2D(g_udmaChHandle, g_udmaTrpdMem, &params);
        trpdMemPhy = (uint64_t) Udma_defaultVirtToPhyFxn(g_udmaTrpdMem, 0U, NULL);
        /* Submit TRPD to channel */
        retVal = Udma_ringQueueRaw(Udma_chGetFqRingHandle(g_udmaChHandle), trpdMemPhy);
        if (retVal != UDMA_SOK)
        {
            VX_PRINT(VX_ZONE_ERROR,"Failed to submit TRPD to UDMA channel\r\n");
            return retVal;
        }
        /* Wait for completion */
        int status = SemaphoreP_pend(&g_udmaDoneSem, 50);
        VX_PRINT(VX_ZONE_ERROR,"SemaphoreP_pend src%p dest%p   %dX%dstatus %d\r\n",params.src_addr,params.dest_addr,params.width,params.height,status);
        retVal = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(g_udmaChHandle), &pDesc);
        if (retVal != UDMA_SOK)
        {
            VX_PRINT(VX_ZONE_ERROR,"Failed to dequeue from completion ring\r\n");
            return retVal;
        }
        
       /* Check TR response status */
        CacheP_inv(g_udmaTrpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD);
        trRespStatus = UdmaUtils_getTrpdTr15Response(g_udmaTrpdMem, 1U, 0U);
        if (CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE != trRespStatus)
        {
            VX_PRINT(VX_ZONE_ERROR,"UDMA 2D transfer failed with status: %d\r\n", trRespStatus);
            retVal = UDMA_EFAIL;
            return retVal;
        }
           return retVal;
    }

    When calling this code using remote_Service,it will encounter the problems I mentioned.

    The method is as follows:

    int32_t appLhAlgRemoteServiceInit()
    {
        int32_t status;
    
        status = appRemoteServiceRegister(APP_LHALG_SERVICE_NAME, appLhAlgHandler);
        if (status != 0)
        {
            appLogPrintf("LHALG Remote Service: ERROR: Unable to register service \n");
        }
    
        return status;
    }
    
    int32_t appLhAlgHandler(char *service_name, uint32_t cmd, void *prm, uint32_t prm_size, uint32_t flags)
    {
        testApp_udmaMemcpy2D();
        return 1;
    }

    main.c:
    while (run)
    {
        uleep(40000);
        appRemoteServiceRun(APP_IPC_CPU_C7x_1, APP_LHALG_SERVICE_NAME, SYSTEM_CMD_TEST, NULL, 0, 0);
    }


    If I don't use remote_Service, it won't have any problems.

  • Hi,

    Could you please try increasing the timeout and check again?

    Also, could you confirm if the callback function has been properly configured? Please add a log to the callback function and verify its execution.

    Regards,
    Sivadeep

  • Hi,

    No matter how many are set, it will time out, and setting WAITFOROVER will permanently wait.

    The callback setting is correct.

    It doesn't always time out.

    When a timeout occurs, no callback is triggered.

    void App_udmaEventCb(Udma_EventHandle eventHandle, uint32_t eventType, void *appData)
    {    
    
        VX_PRINT(VX_ZONE_ERROR,"App_udmaEventCb eventType: %d\r\n", eventType);
    
        if(UDMA_EVENT_TYPE_DMA_COMPLETION == eventType)
        {
            SemaphoreP_post(&g_udmaDoneSem);
        }
    }

    [C7x_1 ] [118.755624][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [119.160624][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [119.160806][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [119.640783][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status -2
    [C7x_1 ] [120.042246][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [120.042308][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [120.450319][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [120.450426][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [120.855371][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [120.855487][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [121.263101][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [121.263218][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [121.670446][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [121.670535][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [122.075529][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [122.075598][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [1970-01-01 00:01:55][122.296381][I][app_run_avm_task:557] lh avm_capture fps : 29.558860 
    [C7x_1 ] [122.479859][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [122.479908][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [122.889362][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [122.889447][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [123.295916][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [123.296141][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [123.706360][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [123.706428][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [124.111754][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [124.111811][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [124.522298][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [124.522389][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [124.929517][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [124.929648][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0
    [C7x_1 ] [125.408235][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status -2
    [C7x_1 ] [125.811040][VX_ZONE_ERROR][App_udmaEventCb:128] App_udmaEventCb eventType: 1
    [C7x_1 ] [125.811161][VX_ZONE_ERROR][testApp_udmaMemcpy2D:414] SemaphoreP_pend srcd8800180 destd888b940   240X595status 0

    It seems to be related to remote_Service. Because I call DMA elsewhere and this situation did not occur. This situation only occurs when using remote_Service to call DMA.

  • Hi,

    Why do you require remote_service to call for DMA operations? Also can you set the timeout value to be usual than 2x and see if it times out, then can you check TR response? 

    Regards,

    Brijesh

  • hi,

    Our framework performs affine transformation by calling C7 core through remote_Service, which involves some copy operations.

    I have set many values for timeout, including 100/200/500/1000/2000/5000. They will all time out.

    CacheP_inv(g_udmaTrpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD);
    trRespStatus = UdmaUtils_getTrpdTr15Response(g_udmaTrpdMem, 1U, 0U);

    Although it timed out, but trRespStatus has been changed from its initial value to CSL-UDMAP_TR-REPONSE-STUS-COPLETE

  • Hi,

    Could you please try using a dedicated  task that waits on a semaphore and performs the DMA operation, instead of executing the DMA and blocking wait inside the remote_service handler.

    Regards,
    Sivadeep

  • Hi,

    What kind of dedicated task do you need?

    I tested the remote service and other threads calling DMA simultaneously. Other threads are normal.

    The other thread performs 35000 DMA operations. There have been 0 instances of timeout.
    The remote thread performs 35000 DMA operations. There have been 544 instances of timeout.

  • Hi,

    What kind of dedicated task do you need?

    Could you please modify the service handler to trigger a worker thread that will handle the actual DMA transfer? Specifically, inside appLhAlgHandler, instead of directly calling the DMA copy, trigger a worker thread.

    Additionally, could you share the full code for TRPD initialization? Also, please verify and compare the count of requests submitted versus the count of callbacks received.

    Regards,
    Sivadeep

  • Hi,

    thi is code for TRPD initialization

    static void App_udmaTrpdInit2D(Udma_ChHandle chHandle,
                                  uint8_t *trpdMem,
                                  const img_select_2d_copy_params_t *params)
    {
        CSL_UdmapTR15  *pTr;
        uint32_t        cqRingNum = Udma_chGetCqRingNum(chHandle);
    
        /* Make TRPD with TR15 TR type */
        UdmaUtils_makeTrpdTr15(trpdMem, 1U, cqRingNum);
        
        /* Setup TR for 2D copy */
        pTr = UdmaUtils_getTrpdTr15Pointer(trpdMem, 0U);
        pTr->flags    = CSL_FMK(UDMAP_TR_FLAGS_TYPE, CSL_UDMAP_TR_FLAGS_TYPE_4D_BLOCK_MOVE_REPACKING_INDIRECTION);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_STATIC, 0U);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EOL, CSL_UDMAP_TR_FLAGS_EOL_MATCH_SOL_EOL);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE, CSL_UDMAP_TR_FLAGS_EVENT_SIZE_COMPLETION);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_CMD_ID, 0x25U);  /* This will come back in TR response */
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_SA_INDIRECT, 0U);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_DA_INDIRECT, 0U);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EOP, 1U);
         /* Set source parameters for 2D copy */
        pTr->icnt0    = params->width;      /* Width in bytes */
        pTr->icnt1    = params->height;     /* Height in lines */
        pTr->icnt2    = 1U;                 /* Number of blocks */
        pTr->icnt3    = 1U;                 /* Number of sets */
        pTr->dim1     = params->src_pitch; /* Source pitch (stride) */
         pTr->dim2     = pTr->icnt0 * pTr->icnt1;
        pTr->dim3     = pTr->icnt0 * pTr->icnt1 * pTr->icnt2;
        pTr->addr     = params->src_addr;
        pTr->fmtflags = 0x00000000U;       /* Linear addressing, 1 byte per elem */
            /* Set destination parameters for 2D copy */
        pTr->dicnt0   = params->width;      /* Destination width in bytes */
        pTr->dicnt1   = params->height;     /* Destination height in lines */
        pTr->dicnt2   = 1U;                 /* Number of blocks */
        pTr->dicnt3   = 1U;                 /* Number of sets */
        pTr->ddim1    = params->dest_pitch; /* Destination pitch (stride) */
         pTr->ddim2    = pTr->dicnt0 * pTr->dicnt1;
        pTr->ddim3    = pTr->dicnt0 * pTr->dicnt1 * pTr->dicnt2;
        pTr->daddr    = params->dest_addr;
    
        /* Perform cache writeback */
        CacheP_wb(trpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD);
        return;
    }

    Is that what you mean?

    static void test_dma_fun(void* arg0, void* arg1)
    {
        appLogPrintf("test_dma_fun runing \n");
        while (1)
        {
            appRtosTaskSleepInMsecs(30);
            testApp_udmaMemcpy2D();
        }
        
    }
    static uint8_t gTskStackMain[64*1024];
    int32_t appLhAlgHandler(char *service_name, uint32_t cmd, void *prm, uint32_t prm_size, uint32_t flags)
    {
        static app_rtos_task_handle_t task =NULL;
        static app_rtos_task_params_t tskParams;
        if(task == NULL)
        {
            appLogPrintf("appRtosTaskCreate test_dma_fun \n");
            appRtosTaskParamsInit(&tskParams);
            tskParams.priority = 8u;
            tskParams.stack = gTskStackMain;
            tskParams.stacksize = sizeof (gTskStackMain);
            tskParams.taskfxn = &test_dma_fun;
            task = appRtosTaskCreate(&tskParams);
            if(task == NULL)
            {
                appLogPrintf("appRtosTaskCreate error \n");
            }
         }
    }

    This test will not cause a timeout. The result is normal.

  • Hi,

    Is that what you mean?

    Yes, but can you please use the appLhAlgHandler to just invoke the task instead of initializing the task there.

    This test will not cause a timeout. The result is normal.


    I think the issue was because service handlers should only be used for triggering a worker thread which will handle the actual DMA transfer. This keeps the service handler from blocking while waiting for the data.

    Regards,
    Sivadeep

  • Are you suggesting that I ignore this issue and implement our software framework in a different way? 

  • Hi,

    By using appLhAlgHandler to invoking the task you are not getting the error right? I think that's the right approach instead of calling DMA function from an IPC thread.

    Regards,
    Sivadeep

  • Hi,

    It's not like that.

    There issues with calling DMA copy from appLhAlgHandler.

    Are you suggesting that I put all algorithms into the new thread? Don't use remote_Service

  • Hi,

    Are you suggesting that I put all algorithms into the new thread? Don't use remote_Service

    Yes, use the remote_service to trigger the worker thread only.

    Regards,
    Sivadeep

  • Alright, let me give it a try

  • Hi,

    Sure. Thanks. Keeping the thread in waiting state.

    Regards,
    Sivadeep