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:UDMA UDMA_ringQueueRaw 函数错误

Guru**** 2589265 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1575916/tda4ven-q1-udma-udma_ringqueueraw-function-error

器件型号:TDA4VEN-Q1


工具/软件:

您好的团队、

当我使用 UDMA 4 通道传输 1M 数据时、偶尔会遇到向队列提交 TRPD 请求的问题。 故障次数过多后,这部分代码将无法运行,问题只在高温下运行,而且很难重现,是什么原因引起问题,以及如何避免问题? 以下是我的操作方式:

int8_t bsp_udma_multi_ch_copy_data_func(uint8_t *destBuf, uint8_t *srcBuf, uint32_t width, uint32_t height)
{
    int8_t   l_int8_ret = 0;
    int32_t  l_int32_status = 0, l_int32_i = 0;
    uint32_t l_u32_length = UDMA_TEST_NUM_BYTES, l_u32_addr_offset = UDMA_CHANNEL_ADDR_OFFSET;
    udma_config_info_type *l_udma_multi_ch_config_info = NULL;

    uint8_t *l_pu8_dst_buf = (uint8_t *)destBuf;
    uint8_t *l_pu8_src_buf = (uint8_t *)srcBuf;

    /* check size */
    l_u32_length = width * height;
    if (l_u32_length <= UDMA_TEST_NUM_BYTES)
    {
        l_u32_length = UDMA_TEST_NUM_BYTES;
        l_u32_addr_offset = 0x2000;      // 32K四等分
    }

    /* init */
    g_udma_channel_complete_cnt = 0;
   
    for (l_int32_i = 0; l_int32_i < UDMA_CHANNEL_NUM; l_int32_i++)
    {
        l_udma_multi_ch_config_info = &g_udma_multi_ch_config_info[l_int32_i];

        /* set address */
        l_pu8_dst_buf = (uint8_t *)(destBuf + l_u32_addr_offset * l_int32_i);
        l_pu8_src_buf = (uint8_t *)(srcBuf  + l_u32_addr_offset * l_int32_i);

        /* Init buffers and TR packet descriptor */
        bsp_udma_trpd_init(l_udma_multi_ch_config_info->chHandle, l_udma_multi_ch_config_info->trpdMem, l_pu8_dst_buf, l_pu8_src_buf, l_u32_length);

        /* Submit TRPD to channel */
        l_int32_status = Udma_ringQueueRaw(Udma_chGetFqRingHandle(l_udma_multi_ch_config_info->chHandle), l_udma_multi_ch_config_info->trpdMemPhy);
        if (l_int32_status != UDMA_SOK)
        {
            l_int8_ret = 1;
        }
    }
   
    l_udma_multi_ch_config_info = &g_udma_multi_ch_config_info[0];
    /* Wait for return descriptor in completion ring - this marks transfer completion */
    SemaphoreP_pend(&l_udma_multi_ch_config_info->udma_done_sem, 10);   // SystemP_WAIT_FOREVER

    for (l_int32_i = 0; l_int32_i < UDMA_CHANNEL_NUM; l_int32_i++)
    {
        l_udma_multi_ch_config_info = &g_udma_multi_ch_config_info[l_int32_i];

        l_int32_status = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(l_udma_multi_ch_config_info->chHandle), &l_udma_multi_ch_config_info->pDesc);
        if (l_int32_status != UDMA_SOK)
        {
            l_int8_ret = 2;
        }

        // /* Check TR response status */
        // CacheP_inv(l_udma_multi_ch_config_info->trpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD);
        // l_int32_status = UdmaUtils_getTrpdTr15Response(l_udma_multi_ch_config_info->trpdMem, 1U, 0U);
        // if (l_int32_status != CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE)
        // {
        //     LOG_PRINT("[warn]l_int32_status:%d\r\n", l_int32_status);
        // }
    }

    return l_int8_ret;
}

我应该采取哪些措施来确保 UDMA 正常工作? 谢谢。

此致

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

     如果请求已满、则将请求提交到队列将失败、因此您可以确保队列足够空或其足够大以允许提交。  

    此致、

    Brijesh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    感谢您的答复! 将队列的长度设置为 1 有什么问题吗? 还是有一个函数来检查队列是否为空?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗯,如果你提交多个元素,是的,长度 1 是不够的。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    我将尝试增加队列的长度。 是否有一个函数可以检查队列是否已满?谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、很遗憾、我在 UDMA 驱动程序中看不到任何 API 来查看队列/振铃是否已满或空。  

    此致、

    Brijesh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、 如果向队列提交请求失败、如何保持 UDMA 运行、重新启用 UDMA 或重新初始化?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    如果队列失败、这意味着已经有一个待处理的请求、并且 UDMA 将运行以完成该请求、对吗? 无需重新启用或重新初始化、您可以等待前一个申请完成、然后提交新申请。  

    此致、

    Brijesh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,我会尝试它,并继续监视。谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    当然可以、谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、我发现  UDMA_ringQueueRaw  打印的异常值为–1、 UDMA_ringDequeueRaw  打印的异常值为–4。 我已将队列的长度更改为 6、但  drvHandle 为 NULL  或  drvInitDone 不等于 UDMA_INIT_DONE 的原因。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Leo、

    不确定、代码中似乎存在一些损坏。 您能否检查 RingHandle 是否正确并与之前的 RingHandle 匹配? 还是 drvHandle 以某种方式设置为空?  

    此致、

    Brijesh