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.

[参考译文] TMS320F28377D:降低 DMA 开销/延迟

Guru**** 2539500 points
Other Parts Discussed in Thread: CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/596014/tms320f28377d-reducing-dma-overhead-latency

器件型号:TMS320F28377D
Thread 中讨论的其他器件:controlSUITE

您好!

我有一个客户使用 DMA 来减少 CPU 上的内存传输开销。 现在、128字节(32x32位)的数据正在从 GS 存储器传输到 EMIF1。

使用 CPU 完成此过程大约需要8us。 在16位 DMA 模式下、相同的传输需要32.8us、在32位 DMA 模式下、传输持续 27.4us。 由于使用32位模式将传输减少一半、这表明实际的 DMA 传输需要~5us。  

时序由 IPC 计数器完成、从触发 DMA 之前的右侧开始、并在触发 DMA 完成中断后结束。  

以下是用于配置 DMA CH1的值:

DMARegs.CH1.burse_size.all = 31U;//在突发中将32个16位字(X-1) x 首选。
DmaRegs.CH1.SRC_BURST_STEP = 1U;//在每个字 x 首选之间递增源地址。
DmaRegs.CH1.dst_burst_step = 1U;//在每个字 x 首选之间递增 dest addr。

//设置传输寄存器:
dmaRegs.ch1.transfer_size = 7U; //每次传输4次突发(X-1)、DMA 中断将在传输完成后发生。
DMARegs.CH1.SRC_TRANSFER_STEP = 1U; //发生换行时忽略 transfer_step。
DmaRegs.CH1.dst_transfer_step = 1U; //发生换行时忽略 transfer_step。

DmaClaSrcSelRegs.DMACHSRCSEL.bit.CH1 = 0U;//源选择
DmaRegs.CH1.MODE.bit.PERINTSEL = 1U; //应硬编码到通道,现在选择源
DmaRegs.ch1.mode.bit.PERINTE = 1U; //外设中断使能
DmaRegs.CH1.MODE.bit.OneShot = 1U; // OneShot 使能
DmaRegs.ch1.mode.bit.continuous = 1U; //连续使能
DmaRegs.ch1.mode.bit.OVRINTE = 0U; //启用/禁用溢出中断
DmaRegs.ch1.mode.bit.DATASIZE = 1U; // 16位/32位数据大小传输
DMaRegs.ch1.mode.bit.CHINTMODE = 1U; //在传输 DmaRegs.ch1.mode.bit.CHINTE
= 1U 时向 CPU 生成中断; //通道中断到 CPU 使能

//清除任何伪标志:中断标志和同步错误标志
DmaRegs.ch1.control.bit.PERINTCLR = 1U;
DmaRegs.ch1.control.bit.ERRCLR = 1U;

感谢您提供有关缩短此传输时间的任何意见!

Munan

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

    您好!

    [引用]由于使用32位模式将传输减少一半、这表明实际的 DMA 传输花费~5us。  [/报价]

    这不是真的。 在这种情况下 、大部分时间由 EMIF 接口占用、即使在32位模式下也几乎保持不变、因为外部接口仍然是16位、因此即使 DMA 进行32位传输、EMIF 也会将32位访问拆分为两个16位访问(在16位模式下就是这种情况)。

    希望这一点很清楚。

    此致、

    Vivek Singh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在这两种情况下、为什么使用 DMA 系统进行传输所需的时间比使用 CPU 复制相同数据所需的时间长3倍以上? 在这两种情况下、EMIF 的延迟都应相同... 是否有方法可以缩短此时间?
    此外、32位与16位 DMA 的区别是什么?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    [引用]在这两种情况下、为什么使用 DMA 系统进行传输所需的时间比使用 CPU 复制相同数据的时间长3倍以上? [/报价]

    与 DMA 相比、通过 CPU 进行的数据传输效率高得多。 请注意、DMA 传输不是流水线型的。 但这绝对不应花费3倍的时间。 我会检查您的 DMA 代码、但您可能需要再次检查这些数字。

    [引用]此外、32位与16位 DMA 的区别是什么? [/报价]

    这里有两个组件。 DMA 花费的时间+ EMIF 花费的时间。 当您从16位切换到32位时、DMA 所花费的时间会减少1/2、因此即使 EMIF 访问所花费的时间几乎相同(在32位模式下节省了一些周期)、总时间也会有所改善。

    此致、

    Vivek Singh

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

    您好、Vivek、

    DMA 有一个四周期管道、最后一个周期是 EMIF 写入。 从16位切换到32位时节省的周期数应该只大约为130 (大约为35ns)、而不是5us。 是的、CPU 的效率可能会稍微高一点、但是传输时间仍将由 EMIF 写入周期决定。 在我们的设置下、EMIF 传输大约需要6uS、当我们使用 CPU 时看到传输时间刚好超过7uS 时、这是合理的、但 DMA 应该位于该焊球公园中。 没有其它 DMA 通道被启用、CPU 正在从 LS 存储器中运行、并且 DMA 传输是从 GS 存储器到 EMIF 的。 寄存器设置显示在这个线程的顶部。 读取 IPC 计数器、然后向 DMA 发出软件触发信号。 传输结束时会生成中断、在此期间将再次读取 IPC 计数器以确定执行时间。

    我将进一步进行调用、以查看是否可以确定大部分时间花在何处、如果我发现任何问题、我将发布结果。 同时、是否有任何具有异步访问 EMIF 的时序的示例代码?

    此致、

    Orval

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

    我同意、当总时间由 EMIF 访问时间决定时、DMA 不应占用比 CPU 多的周期。 在计算总时间时、DMA 启动和 ISR 最终会产生一些开销、但即使这样也不会造成这么大的数量。 DMA 读取的 GSx RAM 不被任何其他主器件访问。 对吧?

    我们在 controlSUITE 中有 EMIF 异步示例、但没有时序示例。 CCS 具有分析功能、客户可以使用该功能来检查计时。

    此致、

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

    Vivek、

    没有其他主器件正在访问 GS RAM、CPU 正在从 LS RAM 运行、并且正在旋转以等待 DMA 完成。 我已经在16位和32位模式下运行了更多测试、执行从 GS 到 GS RAM 的相同传输。 32位模式采用 2.570us、16位模式采用 4.475us。  

    数据表显示16位模式应该为258个 SYSCLK 周期、32位应该为130个周期。 这意味着周期时间为5ns、16位时应为1.29us、32位模式时应为650ns。 它们几乎关闭了4倍。 有什么关于这种情况的想法吗?

    此致、

    Orval

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

    您好 Orval、

    请分享您的 EMIF 设置代码。

    Vivek Singh

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

    Vivek、

    我已经完成了对我预期的执行时间的计算。

    2个突发*[((3个周期/字+(8个 EMIF 周期* 2) )* 32个字/突发)+ 1 ]= 1218个周期* 5ns = 6.09us

    我们的 EMIF 总线使用8个周期/写入、并在 SYSCLK/2下运行。 上面的计算适用于16位模式。 我看到的结果是这4倍、与我进行存储器到存储器传输时的结果相同。

    我在下面包含了 EMIF 配置代码。

    EALLOW;
    
    //对 EMIF1执行模块软复位
    DevCfgRegs.SOFTPRES1.ALL = 0x1U;
    _asm (" nop");
    DevCfgRegs.SOFTPRES1.ALL = 0x0U;
    
    //该位选择 EMIF1模块是使用/1还是/2时钟运行。
    ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV = EMIF_CLOCK _SEL_DIV_BY_2;
    
    //针对 Core1抓取 EMIF1
    // LVD_lint -(C1)从 TI 头文件定义。
    EMIF1ConfigRegs.EMIF1MSEL.all = EMIF1_KEY | EMIF1_CORE_RACRACed;
    
    //检查写入 Emif1ConfigRegs 是否成功
    if (emif1ConfigRegs.EMIF1MSEL.all!= 0x1u)
    {
    错误计数++;
    }
    
    //禁用访问保护
    EMIF1ConfigRegs.EMIF1ACCPRT0.ALL = 0x0u;
    
    //检查写入 Emif1ConfigRegs 是否成功
    if (emif1ConfigRegs.EMIF1ACCPRT0.ALL!= 0x0u)
    {
    错误计数++;
    }
    
    //永久锁定写入以访问保护和主器件选择
    EMIF1的//字段
    EMIF1ConfigRegs.EMIF1COMMIT.ALL = 0x0u;
    
    //检查写入 Emif1ConfigRegs 是否成功
    if (emif1ConfigRegs.EMIF1COMMIT.ALL!= 0x0u)
    {
    错误计数++;
    }
    
    //锁定写入以访问保护和的主选择字段
    //EMIF1.
    EMIF1ConfigRegs.EMIF1LOCK.ALL = 0x0u;
    
    //检查写入 Emif1ConfigRegs 是否成功
    if (emif1ConfigRegs.EMIF1LOCK.ALL!= 0x0u)
    {
    错误计数++;
    }
    
    //配置 ASYNC_CS2_CR 寄存器
    //EMIF_ASYNC_SS_ENABLE -启用选通选择模式
    //EMIF_ASYNC_ASIZE_16 - 16位数据总线接口
    //EMIF_ASYNC_TA_2 -周转时间2 EMIF 时钟
    //EMIF_ASYNC_RHOLD_1 - 1个 EMIF 时钟的保持时间
    //EMIF_ASYNC_RSTROBE_6 -读选通信号时间为6
    //EMIF_ASYNC_RSETUP_1 - 1个 EMIF 时钟的读取建立时间
    //EMIF_ASYNC_whold_1 -写入保持时间为3
    //EMIF_ASYNC_WSTROBE_3 -写入1个 EMIF 时钟的选通时间
    //EMIF_ASYNC_WSETUP_1 - 1 EMIF 时钟的写入建立时间
    //EMIF_ASYNC_EW_DISABLE -扩展等待禁用。
    
    // | 写入| 主机 IRQ |
    // SS |EW | SU | STRB |HLD| SU | STRB |HLD|TA|SZ|
    //|-|-|-|-|---- |-|-|-|---- |-|-|-|-|
    // 1 0 0000 000011 000 0000 000110 000 01
    //Emif1Regs.ASYNC_CS2_CR.ALL =(0x80300305u);
    
    //这可以解决32位读取问题- Chris 正在研究一个永久性的修复。
    // | 写入| 主机 IRQ |
    // SS |EW | SU | STRB |HLD| SU | STRB |HLD|TA|SZ|
    //|-|-|-|-|---- |-|-|-|---- |-|-|-|-|
    // 1 0 0000 000100 001 0000 000111 001 01
    EMif1Regs.ASYNC_CS2_CR.ALL =(0x80420395u);
    
    EDIS;
    

    此致、

    Orval

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

    只是想检查您是否仍然存在此问题、以便我进一步了解这一点吗? 很抱歉耽误你的回答。

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

    Vivek、

    仍然存在问题。 我还对从 GS 到 GS 内存的相同大小传输进行了测试、在32位模式下执行时间为2.570us、在16 IBT 模式下执行时间为4.475us、我们以200MHz 运行。 这些数字似乎仍然很慢。 数据表显示16位模式应该为258个 SYSCLK 周期、32位应该为130个周期。 这意味着周期时间为5ns、16位时应为1.29us、32位模式时应为650ns。 它们几乎关闭了4倍。 这是我从 GS 传输到 EMIF1总线时看到的同样慢的因数。  有什么关于这种情况的想法吗?

     

    提前感谢、

    Orval

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

    您是否在代码中设置 PD 位(Emif1Regs.SDRAM_CR.bit.PD=1)? 如果不是、请在 EMIF 初始化期间设置此项、并查看此项是否有用。 TRM (第25.3.6.3节:为异步访问配置 EMIF)对此进行了说明。

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

    Vivek、

    我并没有这样做,但这样做并没有产生很大的影响。 DMA 传输时间从27.3us 减少到26.1us。 我不断回到的问题是、当从一个 GS 存储器块传输到另一个块时、将 EMIF 从方程中取出、传输时间是 TRM 中所述公式的4倍吗?

    Orval