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.

[参考译文] TMS320C6748:EDMA3 /编译器优化

Guru**** 2539500 points


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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/839588/tms320c6748-edma3-compiler-optimization

器件型号:TMS320C6748

我遇到了一个有趣的情况。  当代码以5速在3级进行优化时、EDMA3 (在我的情况下为 QDMA)不能按预期工作。  我使用 QDMA 读取16位端口 (同一端口) 16次、并将读数传输到存储器。

当在优化关闭的情况下编译代码(进行调试)时、QDMA 按预期工作。

当使用如上所述的优化集编译代码时、QDMA 第一次无法正常工作。  具体而言、QDMA 在所有16个值都传输时不发出完成信号、而是在第一个值读取/传输后发出完成信号。

这里可能会发生什么情况?

编译器版本为8.3.3

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

    您好!

    您能否分享您正在使用的处理器 SDK RTOS?

    此致、
    Yordan

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

    您好!

    您是否能够提供 EDMA 代码的快照:包括如何配置 ParamSet? 我想对 OPT 进行解码、还想了解源地址和目标地址对齐、ACNT、BCNT 等情况。 以及如何触发 QDMA?

    此致、Eric  

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

    不使用 RTOS。

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

    //====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

    //参数块

    #define PARAM_START 0x01c04000
    #define PARAM_SET_0 0x4000
    #define param_set_1 (param_set_0 + 32)
    #define param_set_2 (param_set_1 + 32)
    #define RF_IN (SOC_GPIO_0_regs + 0x70)
    #define NO_LINK 0xFFFF

    #define QCHMAP0 0x01c00200
    #define QER 0x01c01080
    #define QEER 0x01c01084
    #define QEECR 0x01c01088
    #define QEESR 0x01c0108c

    #define IER 0x01c01050
    #define IECR 0x01c01058
    #define IESR 0x01c01060
    #define IPR 0x01c01068
    #define ICR 0x01c01070
    #define QDMA_READY (HWREG (IPR)& 0x00000001)

    struct __attribute__(__packed__) T_Param {
    //在下方保留声明顺序!
    uint32 op;
    uint32 src;
    uint16 acnt;
    uint16位;
    uint32 dst;
    int16 srcbidx;
    int16 dstbidx;
    uint16链接;
    uint16 bcntrld;
    int16 srccidx;
    int16 dstcidx;
    uint16 ccnt;
    uint16 rsvd;
    };

    int16 data_readings[16];

    #pragma LOCATION (DATA_PARARAM、PARAM_START)
    struct __attribute__(__packed__) T_Param data_Param;//Param set 0

    //====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

    bool QDMA_DONE(){// DMA 传输完成?
    返回(QDMA_READY!= 0);

    //====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

    void StartQDMA(){

    //清除中断状态
    HWREG (ICR)= 0x00000001;
    //设置中断使能
    HWREG (IESR)= 0x00000001;
    //触发 DMA
    DATA_PARAM.OPT = 0x0010000c;//TCINTEN = 1、静态= 1、AB 同步

    //====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

    void InitQDMA(){//设置 DMA

    //清除中断状态
    HWREG (ICR)= 0x00000001;
    //启用 QDMA 通道0
    HWREG (QEESR)= 0x00000001;
    //初始化参数集0
    DATA_PARAM.src = RF_IN;
    DATA_PARAM.acnt = 2;
    DATA_PARAM.bcnt = 16;
    DATA_PARAM.srcbidx = 0;
    data_param.dstbidx = 2;
    DATA_PARAM.bcntrld = 0;
    DATA_PARAM.srccidx = 0;
    DATA_PARAM.dstcidx = 0;
    DATA_PARAM.ccnt = 1;
    //根据 EDMA3调整目标地址
    DATA_PARAM.DST =(uint32) DATA_REARINTEINS+0x11000000;
    data_param.link = no_link;
    //触发字;必须是函数中的最后一条赋值语句
    //设置中断使能
    HWREG (IESR)= 0x00000001;
    DATA_PARAM.OPT = 0x0010000c;//TCINTEN = 1、静态= 1、AB 同步

    //====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

    初始化时  调用 InitQDMA()。

    在主循环中、执行以下操作:

    if (qdma_done () ){

    //在此处执行必需的内容

    //通过 QDMA 开始下一个16样本采集

    StartQDMA();//触发 DMA 操作

    //执行其他操作 hererfout = AD4_GetRFOutAsime();

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

    以下是发生问题时缓冲区的外观:

    0x00810198 DATA_readings
    0x00810198 10382 0 0 0 0 0 0 0 0
    0x008101A6 0 0 0 0 0 0 0 0 0 0
    0x008101B4 0 0

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

    您好!

    QDMA 设置如下所示:A-B 同步、源地址和目标地址增量模式、源索引为0 (本质上无增量)、目标索引为2字节移动。 每次从 FIFO 中移动16 x 2个字节时。 位20表示传输完成中断置位。 并将静态用于 QDMA。


    新数据到达 GPIO FIFO 的速度有多快? 当您读取2到16次时、FIFO 数据是否可能未到达、因此使用优化可以得到零? 如果您测量从 StartQDMA()到 (QDMA_DOE()花费的时间,您是否会看到执行时间快得多?

    如果您仅使用 A-SYNC 并使用 中间传输完成中断使能(位21)、您会在优化和非优化情况下看到16个中断吗?

    此致、Eric  

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

    1.由于 QDMA_DONE()检查中断挂起标志以确定 DMA 完成,因此执行速度不应影响。  在调用 InitQDMA()之前,中断挂起标志错误地被置位,随后在调用 InitQDMA()之前调用 QDMA_DOE()。

    2.我通过在初始化之后和启动 QDMA 之前插入一个小延迟来重新排列代码。  这似乎修复了错误。