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.

[参考译文] LCDKC6748上的中断延迟

Guru**** 2551300 points
Other Parts Discussed in Thread: MATHLIB

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/578043/interruption-delay-on-lcdkc6748

主题中讨论的其他器件:MATHLIB

您好!

首先、我要感谢 TI 为客户提供的所有文档和示例。 我们还发现论坛在大多数时候都非常有用。

我们将在 TMS32C6748上开发用于实时应用的项目。 我们遇到了中断延迟问题、我们找不到明显的原因/解决方案。
首先,让我简要介绍 一下系统的设计和实施:
DSP 连接到一个5兆波特双通道 UART ( 64字节 FIFO、可编程触发电平、多个状态/配置寄存器)

通过 EMIFA (根据 UART 芯片的数据表、48Mhz 速度、CS4存储器空间、异步、8位模式和时序)

此外,还连接到 GPIO 组0 (1和2)的2条中断线路。

功能设计:
每毫秒、DSP 接收的每通道总字节为192字节、分为3个64字节的数据包(FIFO 最大容量)、这需要180微秒、间隔为100微秒(以便 CPU 有时间为中断提供服务)
为了简单起见、让我们将从两个通道接收到的字节称为"数据样本"。
DSP 应该在2080个样本上运行一个算法、该算法除其他外、使用了 DSPLIB、MathLib。

实施:
为了最大限度地利用 CPU、中断服务由 ISR 完成、以检查状态寄存器、 随后将触发手动 EDMA3事件、以将传入的数据缓冲成乒乓式方式、并将其馈送到应在主程序中运行的算法中。
我们通过 Code Composer 7、XDS100v3和 C6748 Starterware 1.2.4以456Mhz 频率运行该板。 代码链接为在启用 L2缓存的情况下从 DDR2运行。
结果:
在每个64字节块之后、中断线路变为高电平、然后 CS4开始切换、这说明了 ISR 处理和 EDMA3读取。 它们都可以正常工作、并为我们提供预期结果。

D0:UART 通道0传入数据
D1:UART 通道1传入数据
D2:UART 通道0中断线
D3:UART 通道1中断线
D4:EMIFA CS4

问题:
当我们开始将缓冲区馈送到算法时会发生这种情况、而我们将2080个样本缓冲到"PingBuffer"(大小为1MB)中、然后将其传递给在主循环中运行的算法。 我们开始填写"Pong buffer"。 一切都在正常运行直到某个时间点、ISR 会异常延迟、我们会失去同步、因此我们无法满足最后期限。
以下快照说明了此行为。

我们通读了论坛和我们可用的大多数手册,并为此提出了多种可能的原因:
首先、编译器可以禁用中断。 我们重新编译了使用的所有代码、从我们的开始、到 C 标准库、Mathlib 和 DSP 库、其中-interrupt_treshold = 1。 我们研究了汇编输出、从未使用"DINT"指令(mathlib 中的某些汇编文件除外、我们尝试对其注释 DINT 或重新实现 C 中使用的函数。)
第二、我们研究了 mDDR/DDR2控制器的总线争用。 由于 GEL 文件正在为我们执行初始化、PBBPR 的默认值为0x20、我们将其降至0x10、而不会对问题产生任何影响。
第三、由于 CPU 不允许在硬件中嵌套中断、因此我们确保仅对 UART 中断进行编程(仅用于测试目的)
最后、主外设寄存器的当前配置为使用的 DMA 控制器提供了更高的优先级(默认配置和所需配置)、为 CPU 提供更高的优先级不会改变这个延迟中的任何内容。
既然我们已经尝试了所有这些,我们就开始怀疑这是一个缓存问题。 L1P 中的高速缓存缺失是否会导致此长延迟? 如果是、我们可以对此采取什么措施?

编辑:我们尝试将算法文本部分链接到 DDR2,其余部分都链接到 L2RAM 空间,结果相同。


我们还愿意接受任何建议、以帮助我们解决问题。

提前感谢您。
此致、

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

    我已将此事转发给设计专家。 他们的反馈应发布在此处。

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

    从逻辑分析器快照中、我假设 D0/D1实际上是 UART 的 Rx 输入线路、您说 D4是 EMIF CS4。 哪些物理信号是 D2、D3、D8、D10和 D11? 我对 D2-D3的假设是、这是两条 GPIO 线、但它们是来自 UART 的哪些物理信号;以及是什么清除它们? 此外、第二张图片中为什么没有显示 D8-D11? 能否捕获这些信息、以便对正在发生的情况进行一些了解?

    在第一张图片中、D3的宽度从最窄的脉冲到最宽的脉冲之间似乎变化了高达2倍。 这只是一个采样/显示伪影、还是表示 DSP 上需要更多时间才能完成某项任务?

    当故障发生时、D3会被拉伸、这意味着只有在 DSP 采取某种操作后才会清除。 该"操作"是指64B 或其他一些直接信号或命令的完整读数? 在这一点上、D2不会被清除、因此它的清除操作一定不会发生(dh、对吧?)。 这是否意味着您需要特别注意的事情?

    当死锁发生时、ISR 和 EDMA 最后会发生什么情况? 换句话说、您是否陷入 ISR 等待某件事? EDMA 的两项操作都完成了什么?

    我真的不想提出任何问题、但是您在将 ISR 代码移动到 L2SRAM、关闭其他中断以及处理优先级方面所做的实验都有力地暗示了这不是执行时间的问题。 由于这是导致实时问题的一个非常常见的原因、因此最好记住这一点、甚至可以不时尝试更多的操作。 例如、您可以关闭 L1P 缓存以及交替关闭 L1D 缓存和 L2缓存以查看效果。

    故障的可重复性如何? 开始向 UART 发送数据后、它是否会在相同的时间内发生? 它是否总是在192B 突发的第3次突发后开始停止?

    由于2080不能被192或64除以、在从 Ping 切换到 Pong 并启动 main 中的算法运行方面、会发生什么新情况?

    如果您跳过或注释掉算法代码、以便您所做的就是读取数据以及 ISR 执行的其他操作、问题是否仍然存在?

    ISR 中发生了什么情况?

    EDMA 传输所使用的参数是什么? EDMA 是仅从 EMIF 读取到存储器、还是在数据保存到 DDR 后移动数据?

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

    Randy、您好!
    您猜对了:D0/D1是 UART 接收器的物理位置,D4是 EMIF CS4,D2和 D3是连接到 GPIO 线路的中断线路。 很抱歉,我不知道所有其它线路与我们的事情无关(我们正在监视其它信号进入另一个 CPU)。

    关于中断线(D2/D3),如果 UART 有一个中断挂起(如组帧错误、溢出错误或最重要的情况,达到的触发级别),则会触发相应的中断线。 正如您在快照中看到的、这两行此刻都变为高电平、因为已达到触发级别。 更精确地说、中断在61字节的起始位上升、并且在 FIFO 中的字节下降到低于触发电平60时立即下降。 (如果其它中断没有挂起)
    因此、在快照中、您可以看到 CS4切换有2个连续的等量块、它们表示 EDMA3从2个 UART 通道读取的数据。 D3在第一个块开始运行时变为低电平、然后在执行相应的读取时 D2变为低电平。

    中断会出现条纹、因为一旦61字节进入 FIFO、中断就不会立即得到处理。 我们清除这些标志并手动触发从 FIFO 范围读取的 EDMA3。

    我们不会卡住、只是当中断延迟时、DMA 开始清空 FIFO 时、下一个64B 块已经开始发送。 当 FIFO 达到61个字节时、中断变为高电平- 但是如果 FIFO 在64字节块的开头不为空、那么我们将获得溢出并丢失关键数据。


    在我们完成前2080ms 的数据收集后、它始终发生在160ms。 通常在64字节的第一个块中、但在第二个块中频率较低。 但是、当我们尝试以所有可能的组合打开/关闭 L2、L1P、L1D 时、会发生相同的行为、但在不同的样本中。 (但对于每一个单独的审判,它们是一致的)

    当最后一个 DMA 传输耗尽其参数(Cidx = 2080的 AB 传输)时,它将触发一个完成中断,在该中断中,我们为 DMA 传输设置了一个新参数,并设置了一个全局变量,告诉算法在主循环中运行。

    我们在上一帖子中链接的第一个快照说明了在注释掉算法时一切如何正常工作。 我们从未遇到过任何问题,也从未失败(进行了长达2天的最长测试)

    ISR 中发生的情况如下: 禁用组中断、清除其标志、清除引脚中断、从不同的 UART 读取状态寄存器(这为最后3个字节锁存在 FIFO 中提供了足够的时间)、然后启用 EDMA3传输并可重新启用组中断。

    我们正在使用 DMA 的链接事件:
    参数1:外设到存储器(第一个 UART 通道到缓冲器)
    参数2:外设到内存(第二个 UART 通道到缓冲区)

    参数3:数据重新排序(内存到内存)
    参数4:内存到外设(我们将收集的内容直接发送到另一个异步外设,该异步外设连接到前面介绍的另一个 CPU)
    参数5: 存储器到存储器(乒乓缓冲器)

    正如我所述、DMA 传输被正确执行、我们获得了所需的行为和输出、是的、它的移动数据。
    从硬件设计的角度来看、您认为它与执行时间无关的原因是什么?
    谢谢、

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

    我想我对您在原始帖子中的"功能设计:"描述感到困惑。 样本和毫秒似乎可以互换使用、但这对我来说是不清楚和令人困惑的。 也许您可以用添加的一些详细信息来重述这一点、以帮助我、请吧?

    上图3月6日11:22图片左下角的三个展开的突发中、每个突发中有多少字节的数据? 我正试图准确地理解所有事情的发生、这是我唯一知道能够提出有用建议的方法。 从图片中可以看出、在 D3/D2变为高电平后、只有几个字节被添加到 FIFO 中、但在 D3变为低电平之前、会读取大量字节。 那么、在 D2变为低电平之前、会进行一组更密集的读取。

    在 D3仍然处于高电平时、从 UART 读取的速度明显较慢、这是什么原因?
    那么、在 D2为高电平时、读取速度更快的原因是什么? 可能存在类似问题、然后缺失?
    您是否有两个单独的 ISR、一个用于通道0、一个用于通道1? 或单个 ISR 等待其中一个? 或者还有什么呢?

    术语"链接"和"链接"在 EDMA3的使用中具有非常具体的含义。 您能否解释一下您正在使用多个参数的链接、请说明一下? 以及如何控制它。 您是不是说您总共使用5个 DMA 通道、根据时间的不同、从一个通道到另一个通道进行链接? 如果问题与执行时间无关、那么它很可能与 EDMA3资源管理有关-管理可用通道和传输控制器及总线等。

    我发现使用32位 TI 格式和每行8个字来提供 Param 区域的存储器浏览器图片很有帮助。 并确定哪个物理地址起始了您的逻辑参数集。 还包括您正在使用的任何链接集。

    您说您正在使用" Cidx = 2080.的 AB 转移"。 什么是 Acnt 和 Bcnt 值? 您的 EMIF 在总线尺寸方面配置了什么? 如何对 UART 进行布线以实现 FIFO 和寄存器访问-几条地址线、多条地址线或无地址线?

    另外、如何触发2080 DMA 传输中的每一个?

    打开和关闭 L1P 应该会对执行代码所需的时间产生很大影响。 对所有缓存执行相同的操作(全部关闭而全部打开)应轻松地将执行时间变化10倍。 由于这种大变化不会显著改变您的问题、因此不太可能发生这种变化。

    顺便说一下、注释掉库代码中的 DINT 指令可能会破坏正在运行的算法。 我们尝试非常谨慎地放置和使用这些中断、以最大限度地减少对中断延迟的任何影响、但如果在本应已进行 DINT 的循环中间发生中断、则数据将会发生不良情况。

    找出问题的原因:您列出了5个不同的 DMA 项目、其中大多数不会在常规数据传输期间发生。 当需要进行大量较大的传输时、情况会大幅放缓。 因此、存储器总线很可能处理过多的活动(不是最可能的原因)、或者 EDMA3处理过多的活动。 有关 DMA 配置和操作的更多详细信息将有助于弄清这一点。

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

    感谢您快速回答 Randy、

    一个数据样本由来自1个 UART 的3个64字节的块组成。 因此、在单个通道上、采样值等于192字节。 每1ms 会生成一个数据样本、因此这两者之间会产生混淆。
    UART 器件有2条连接到 GPIO 的互连线路,当它有需要处理的内容时,这些线路会变为高电平:例如:线路状态寄存器、FIFO 满、达到的触发电平等
    在本例中、当中断在每个64字节块的61个字节变为高电平时、我们使用 EMIFA_CS4的 CPU 从四路 UART 执行一些读取、这解释了快照"March 6 11:22"上 D4的形状。 第一个间隔的 CS 脉冲由 CPU 执行、当由同一 ISR 内的手动事件触发时、DMA 将执行2个密集脉冲。 第一次读取需要这么长的时间、原因是我们需要确保我们收到的字节正好为64字节、 由于发送这些字节的器件会在字节之间产生一些延迟、并且无法判断 FIFO 是否已满、因此我们需要确保为其提供足够的时间来填充 FIFO (在我们的情况下为34微秒)。
    此外、正如我之前所述、2条中断线路共享同一个 GPIO 组、因此我们仅启用 INT-0、您可以在 D2上看到该中断。 因此、我们只有1个 ISR。

    以下是系统的简要概述,它可能有助于您直观地显示它:
    以毫秒为基础、我们从每个 UART 通道接收1个样本(3 x 64B 块)。

    对于每个64字节块、我们在61字节上得到中断、这将清除线路状态寄存器并为最后3个字节的接收提供足够的时间、 然后、我们启用一个 DMA 传输、该传输链接到另一个传输、它们都从应答器 UARTx RHR 寄存器中读取数据。
    对每个样本(即每个通道的1毫秒或3个64字节的块)实现这一点后、我们会执行一些数据重新排序并使用 DMA 填充。
    此时、数据被视为已准备好进行处理和发送、因此我们手动发送一个 DMA 传输到 EMIFA_CS2 (下一个快照上的 D5)、该传输被链接到另一个传输、该传输将相同的数据放入算法可用的乒乓缓冲器中。


    以下是用于 DMA 传输的参数集:
    EDMA3CCPaRAMEntry PSet00 ={
       srcAddr   =(无符号整型)   SOC_EMIFA_CS4_ADDR + Quad_CS_A、
       .destAddr  =(无符号 int)   Data_Raw             、
       .aCnt      =(无符号短整型)   1.                   、
       .bCnt      =(无符号短整型)   64                   、
       .ccnt      =(无符号短整型)   1.                   、
       srcBIdx   =(短整型)         0                   、
       .destBIdx   =(短整型)         1.                   、
       .srcCIdx   =(短整型)         0                   、
       .destCIdx   =(短整型)         0                   、
       linkAddr   =(无符号短整型)   0xFFFFFFU                、
       .bCntReload =(无符号短整型)   0U                   、
       .opt      =(unsigned int)   0x00401004             、
    };
    EDMA3CCPaRAMEntry PSet01 ={
       srcAddr   =(无符号整型)   SOC_EMIFA_CS4_ADDR + Quad_CS_C、
       .destAddr  =(无符号整型)   Data_Raw+(64*3)      、
       .aCnt      =(无符号短整型)   1.                   、
       .bCnt      =(无符号短整型)   64                   、
       .ccnt      =(无符号短整型)   1.                   、
       srcBIdx   =(短整型)         0                   、
       .destBIdx   =(短整型)         1.                   、
       .srcCIdx   =(短整型)         0                   、
       .destCIdx   =(短整型)         0                   、
       linkAddr   =(无符号短整型)   0xFFFFFFU                、
       .bCntReload =(无符号短整型)   0U                   、
       .opt      =(unsigned int)   0x00101004             、
    };
    EDMA3CCPaRAMEntry PSetOrder00 ={
       .srcAddr   =(unsigned int)   Data_Raw             、
       destAddr  =(unsigned int)   Data_ordered         、
       aCnt      =(无符号短整型)   3*8                   、
       .bCnt      =(无符号短整型)   8.                   、
       .ccnt      =(无符号短整型)   1.                   、
       srcBIdx   =(短整型)         3*8                   、
       .destBIdx   =(短)         3*8*2                、
       .srcCIdx   =(短整型)         0                   、
       .destCIdx   =(短整型)         0                   、
       linkAddr   =(无符号短整型)   0xFFFFFFU                、
       .bCntReload =(无符号短整型)   0U                   、
       .opt      =(unsigned int)   0x00403004             、
    };
    EDMA3CCPaRAMEntry PSetOrder01 ={
       srcAddr   =(unsigned int)   Data_Raw +(64*3)      、
       destAddr  =(unsigned int)   Data_ordered +(3*8)      、
       aCnt      =(无符号短整型)   3*8                   、
       .bCnt      =(无符号短整型)   8.                   、
       .ccnt      =(无符号短整型)   1.                   、
       srcBIdx   =(短整型)         3*8                   、
       .destBIdx   =(短)         3*8*2                、
       .srcCIdx   =(短整型)         0                   、
       .destCIdx   =(短整型)         0                   、
       linkAddr   =(无符号短整型)   0xFFFFFFU                、
       .bCntReload =(无符号短整型)   0U                   、
       .opt =      (unsigned int)   0x00404004             、
    };

    EDMA3CCPaRAMEntry PSetPreSort ={
       .srcAddr   =(unsigned int)   Data_ordered         、
       destAddr  =(无符号 int)   Data_Intermediate +1   、
       aCnt      =(无符号短整型)   3.                   、
       .bCnt      =(无符号短整型)   64*2                、
       .ccnt      =(无符号短整型)   1.                   、
       srcBIdx   =(短整型)         3.                   、
       .destBIdx   =(短整型)         4.                   、
       .srcCIdx   =(短整型)         0                   、
       .destCIdx   =(短整型)         0                   、
       linkAddr   =(无符号短整型)   0xFFFFFFU                、
       .bCntReload =(无符号短整型)   0U                   、
       .opt =      (unsigned int)   0x00104004             、
    };
    EDMA3CCPaRAMEntry PSetOut ={
       srcAddr   =(unsigned int)   Data_Intermediate      、
       destAddr  =(unsigned int)   SOC_EMIFA_CS2_ADDR + CPLD_W_Push_ADDR、
       .aCnt      =(无符号短整型)   1.                   、
       .bCnt      =(无符号短整型)   64*2*4                、
       .ccnt      =(无符号短整型)   1.                   、
       .srcBIdx   =(短整型)         1.                   、
       .destBIdx   =(短整型)         0                   、
       .srcCIdx   =(短整型)         0                   、
       .destCIdx   =(短整型)         0                   、
       linkAddr   =(无符号短整型)   0xFFFFFFU                、
       .bCntReload =(无符号短整型)   0U                   、
       .opt      =(unsigned int)   0x00105004             、
    };
    EDMA3CCPaRAMEntry PSetSort ={
       srcAddr   =(unsigned int)   Data_Intermediate      、
       destAddr  =(unsigned int)   Data_Final_Ping         、
       .aCnt      =(无符号短整型)   4.                   、
       .bCnt      =(无符号短整型)   64*2                、
       .ccnt      =(无符号短整型)   2080                 、
       srcBIdx   =(短整型)         4.                   、
       .destBIdx   =(短型)         4*2080                、
       .srcCIdx   =(短整型)         0                   、
       .destCIdx   =(短整型)         4.                   、
       linkAddr   =(无符号短整型)   0xFFFFFFU                、
       .bCntReload =(无符号短整型)   0U                   、
       .opt      =(unsigned int)   0x00106004             、
    };
    此外、还会显示另一个快照、说明我们遇到的相同问题、但上面有 CS2 (D5)

    下面是 DMA 通道的初始化方式:

    void dma_set (void)

       /*请求 DMA 通道和 TCC */
       EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、0、0、0);
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、0、&PSet00);

       EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、1、1、0);
       CB_Fxn[1]= Snippet_Complete_ISR;
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、1、&PSet01);

       EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、2、2、0);
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、2、&PSetOrder00);

       EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、3、3、0);
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、3、&PSetOrder01);

       EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、4、4、0);
       CB_Fxn[4]= Presort_complete_ISR;
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、4、&PSetPreSort);

       EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、5、5、0);
       CB_Fxn[5]= Data_Out_ISR;
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、5、&PSetOut);

       EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、6、6、0);
       CB_Fxn[6]= Sort_Complete_ISR;
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、6、&PSetSort);

    函数表用于完成 ISR、以下是它们的实现方式(我们关注/使用 Starterware 提供的示例)

    void Snippet_complete_isr (unsigned int TCC、unsigned int status)

       ++Counter_Pivot;
       if (Counter_Pivot = 3){
            COUNTER_Pivot = 0;
           EDMA3 EnableTransfer (SOC_EDMA30CC_0_regs、2、EDMA3_TRIG_MODE_MANUAL);
       }
       PSet00.destAddr    =(unsigned int) Data_Raw+(64* Counter_Pivot);
       PSet01.destAddr    =(unsigned int) Data_Raw+(64*(3+Counter_Pivot));
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、0、&PSet00);
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、1、&PSet01);

    void Presort_complete_isr (unsigned int TCC、unsigned int status)

       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、2、&PSetOrder00);
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、3、&PSetOrder01);
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、4、&PSetPreSort);
       EDMA3 EnableTransfer (SOC_EDMA30CC_0_regs、5、EDMA3_TRIG_MODE_MANUAL);

    void Data_out_ISR (unsigned int TCC、unsigned int 状态)

       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、5、&PSetOut);
       //VSYNC
       (*(volatile uint16_t*)(SOC_EMIFA_CS2_ADDR + CPLD _W_VSYNC_ADDR))=(uint16_t) 0xAB;
       EDMA3 EnableTransfer (SOC_EDMA30CC_0_regs、6、EDMA3_TRIG_MODE_MANUAL);


    bool buff 交换= 1;
    void sort_complete_isr (unsigned int TCC、unsigned int status)

       if (buff 交换){
          PSetSort.destAddr  =(unsigned int)   Data_Final_Pong;
          buff _swap = 0;
       }
       否则{
          PSetSort.destAddr  =(unsigned int)   Data_Final_Ping;
          buff 交换= 1;
       }
       array_go = 1;
       EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、6、&PSetSort);


    我希望这方面的细节能够准确地说明系统的工作原理。
    谢谢、

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

    所有参数设置和 ISR 代码显示每个样本或 ms 会发生什么情况。 为了确认我对我的理解、我对它进行了以下修改:

    D0/D1上有三个 UART 突发、每个突发之后是 D4突发、此时 DMA 通道0/1被运行以读取传入的 UART 数据。 在每组三次突发中的第3次之后、DMA 通道2-4运行、随后是通道5、如 D5所示。 D5突发和最终写入(0xAB 数据值)发生在 D0/D1上下一个 UART 突发的中点、因此在 D0/D1变为高电平之前大约40-50us。

    在所有通过案例中、在 D0/D1变为高电平后、CS4上的 D4活动迅速开始。 但是、在最近的3月6日16:58图片中的故障情况下、D4活动开始之前会有额外的延迟。

    我从您上面的描述中假设、当收到2080个"样片"中的最后一个样片时、会发生这种故障情况。 这意味着完全相同的 DMA 活动一直通过所有 DMA ISR 发生、直到并包括 DMA 通道6的 sort_complete_isr。 对于最后一个样本、sort_complete_isr 的区别在于 array_go 设置为1、重新加载通道6的参数。

    当 array_go 设置为1时、主例程中会发生什么情况? 特别是、是否会发生任何其他 DMA 活动?

    是否有任何其他 DMA 通道用于上面显示的通道以外的任何其他通道?

    如果您在样本之间分散空间、问题是否会消失?

    一旦发生故障、有几个 EDMA3寄存器可以指示与 EDMA3相关的错误、例如 EMR 甚至 IPR。

    由于我们的帖子之间存在很大的滞后、如果您有额外的时间、我建议您查看 EDMA3用户指南、了解链接。 另外、请查找具有链接功能的 Starterware 示例。 我不熟悉 Starterware 代码、但我认为您使用 ISR 和手动触发的方法基于 Starterware 示例。 如果您可以向我发送这些示例中任何一个的名称、我可以看到我的 PC 上是否加载了这些示例。

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

    您好、Randy、
    再次感谢您花时间阅读和理解系统的所有部分。
    除了"有问题的部分"、您一切都很好。
    收到2080个样本(填充第一个 ping 缓冲区)后、我们设置"array_go"变量、该变量将算法设置为在程序主循环中对此数据运行。
    该算法在 PingBuffer 上完成工作大约需要700ms、同时 DMA 仍在填充 PongBuffer。
    将 array_go 设置为1后的160ms 内的程序执行是完美的(如果启用了所有缓存、否则会在以后发生)、在161ms (或161~3块样本)上、我们得到了这个奇怪的延迟。 如果 array_go 从未被设置为1、则乒乓缓冲器会逐个填充、DMA 传输不会被延迟。

    除了我在上一个帖子中提到的 DMA 通道之外、没有其他使用的 DMA 通道。

    DMA 不会记录任何错误、ISR 已在 Starterware 中作为 examples/SPI_EDMA 或 examples/UART_EDMA 下的描述实现。 处理完成和错误的例程在 EDMA3参考手册(第2.9.2节 EDMA3中断服务)中描述为伪代码,该代码会使这些 ISR 在 starterware 中的执行时间更长(检查 Edma3HandlerIsr 和 Edma3CCErrHandlerIsr)
    因此问题不在于 DMA 完成其任务、而在于中断不能立即得到处理。

    此外,并非所有 DMA 通道都是链式的*。 我们有0、1 chain*和2、3、4 chain*。 2由通道1之后完成 ISR 的回调函数触发。 通道5和6也是如此。 正如您可能想象的那样、有多种方法可以执行相同的操作、我们只选择了一种更可控的方法(我们可以在调试时检查所有传输的状态)。

    编辑:我们在64字节数据块之间放置更大的延迟,我们注意到失败发生在第76个样本而不是第161个样本。 您可以看到第5个 DMA 传输(显示在 D5上)也被延迟。
    这强烈表明它是一个执行问题、因为现在我们为 CPU 提供了更多的时间来执行算法、并且故障似乎更快发生。



    我们同意在本论坛上发帖之间存在很长的延迟-我们是否可以通过任何方式直接联系您或其他 FAE 来帮助加快此过程? 我们可以在此处发布解决方案、以使论坛受益。

    此致、

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

    很多很好的信息、这张最新的图片很好。

    我很好奇 EDMA3寄存器中的 IPR 和 IER 在故障发生后停止处理器后会是什么样的。 IPR 中是否设置了启用位、如位1或位6? 还是其他人?

    DMA 通道0是如何触发的? 是由 GPIO 上升沿触发事件、还是没有显示 ISR 来响应 GPIO 上升沿、读取 UART、然后决定是否手动触发 DMA 通道0?

    由于缓存打开/关闭确实会通过更早或更晚移动来显著改变故障的发生、因此这会改变事情。 这与700ms 处理开始后保持在大约相同时间点的故障匹配、该时间点是采样计数的较早或较晚值、具体取决于64B 块之间的间隔。 尤其是设置 array_go 永远不会完全避免这个问题、您已经确信它与处理器性能相关、而与 EDMA3资源无关(这是我向下的路径)。

    我可以看到两个方向中的一个或两个方向:1)确定代码中导致延迟的确切原因、2)减少 DMA 活动对处理器性能的依赖(例如、ISR 延迟)。 1)如果可能、您可以修复它、如果可能、也可以处理它。 和2)如果修复更困难,则可能是一种处理方法。

    由于故障是在主程序中首次通过算法时发生的、因此有多种方法可以找到它。 如果很容易重新启动代码和外部器件、则猜测160ms 点的位置并在此处返回将使您能够查看故障是否发生。 如果不是、请提前移动返回;如果是、请稍后移动返回。

    另一种方法是在代码中放入100ms 可中断延迟循环、而不是返回。 如果延迟导致问题在100ms 后移动、请提前移动、依此类推。

    我可以想到的两个最大的罪魁祸首是禁用中断或内存总线冲突。 中断可以通过不允许嵌套的另一个中断、或通过显式使用 DINT/EINT 或1-6周期紧密循环来禁用。 您应该知道是否有任何其他中断在坏时处于活动状态、并且它们必须重复很多次才能引起您在这里显示的内容。 为了实现某些算法的最大性能、需要显式使用 DINT/EINT;有时需要进行折衷、以减少 DINT/EINT 的使用、但会牺牲一些性能-这一点对于您的代码来说非常具体。 在 TI 库例程中、不可能出现紧密循环、可以使用您之前提到过的中断编译标志来避免紧密循环。

    因此、如果它是内存总线冲突、则意味着 DSP 在 DMA 通道6传输的同时、在一个小循环中以大块进行大量数据存储器访问、因为它是最长的数据通道、所以最有可能被挂起。 但同样、这一切取决于代码的运行方式及其执行的操作。

    在 EDMA3术语中、您将使用链来自动触发下一个通道上的传输。 链接对您的案例非常有用;这意味着在特殊的链接参数集中有另一个副本、说明您通常会在 ISR 中重新加载到每个通道的活动通道参数集中。 使用链接可以完全摆脱用于重新加载参数的某些 ISR。 您甚至可以连续使用多个链接参数集来设置通道0的三个不同地址或通道6的乒乓地址。 这样做将是实施#2的一种方法、"如果修复更困难、则应对"。 但是、除非您能找到实际原因、以便您知道在最坏的情况下、更多的中断延迟抗扰度会成功、而不仅仅是将问题移到更难找到的地方。

    D5和 D4之间的重叠对我来说非常困惑、因为您将所有 DMA 通道置于队列0 /传输控制器0上、它们"应该"始终按顺序发生、而不是并行发生。 但实际上、必须按顺序进行读取。 我的理论是、开始读取 Ch5/D5、当数据 FIFO 中有足够的数据时、将开始写入 Ch5/D5。 一旦所有 Ch5/D5读取完成(由于它们来自比 EMIF 更快的存储器)、那么可开始 Ch0/D4读取。 一旦数据 FIFO 中也有足够的 Ch0/D4数据、Ch0/D4可以开始写入内部或 DDR 存储器。 同时、Ch5/D5通过 EMIF 进行写入、同时通过 EMIF 进行 Ch0/D4读取。 由于它们共用 EMIF、因此它们轮流使用、并且都需要更长的时间才能完成每个器件。

    这里可能会发生错误的其他一些事情、只要是自由思考、就会:

    读取 UART 的长时间延迟会导致 UART 中的 FIFO 溢出、从而设置一些可能影响未来 GPIO 中断的不同位。
    EDMA 中断发送程序中的竞态条件不会导致更多 EDMA 中断;这将显示为在所有活动停止后设置的一个或多个 IPR 位。

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

    Randy、

    DMA 通道在 GPIOPin1Bank0上升沿被手动触发。


    void Quad_GPIO_ISR_DMA (void)

       GPIOBankIntDisable (SOC_GPIO_0_regs、SYS_INT_GPIO_B0INT);
       /*清除 DSPINTC 中的中断状态*/
       IntEventClear (SYS_INT_GPIO_B0INT);
       /*Get the Pending Event*/
       bool set =(bool) GPIOPinIntStatus (SOC_GPIO_0_regs、3);
       GPIOPinIntClear (SOC_GPIO_0_regs、3);

       静态 uint32_t dummy_delay;
       静态 uint8_t ISR_reg、LSRA 寄存器、LLRC_reg;
       for (dummy_delay;=0;dummy_delay;<25dummy_delay;++)
       {
          ISR_reg =(*(volatile uint8_t*)(SOC_EMIFA_CS4_ADDR + Quad_CS_C + Quad_Read_ISR);
          ISR_reg =(*(volatile uint8_t*)(SOC_EMIFA_CS4_ADDR + Quad_CS_A + Quad_Read_ISR);
          LSRA 寄存器=(*(volatile uint8_t*)(SOC_EMIFA_CS4_ADDR + Quad_CS_A + Quad_READ_LSR);
          LSRC_reg =(*(volatile uint8_t*)(SOC_EMIFA_CS4_ADDR + Quad_CS_C + Quad_READ_LSR);
       }
       if ((LSRA 寄存器和0x01)=0) QUADA_UART_ERROR =1;
       if (((LSRC_reg & 0x01)=0) QUADC_UART_ERROR =1;


       EDMA3 EnableTransfer (SOC_EDMA30CC_0_regs、0、EDMA3_TRIG_MODE_MANUAL);
       GPIOBankIntEnable (SOC_GPIO_0_regs、SYS_INT_GPIO_B0INT);
       

    虚拟读取是进入四路 UART 的间隔读取。 它们用于确保64块的最后3个字节在开始清空 FIFO 之前到达 FIFO。 (如果我们立即启动 DMA、则在这些字节被锁存之前 DMA 完成的情况经常发生)

    此外、DMA 事件会被链接、而不会被链接。 我在前一篇文章中改正了这一点、我们都在同一页上。
    我们认为这可能是一个总线争用问题、正如您可能知道的、DMA 在 SCR 中具有更高的优先级、我们将 EMIFDDR_PBBPR 限制为0x10。

    我正在与算法开发人员进行检查、以深入了解算法的过程-它是由不同的团队开发的。

    D4和 D5之间发生的仲裁是前3个 D4读取(64字节块)延迟的影响,之后是 D5写入。 在最后一次传输时、D4再次触发、DMA 必须在两个通道的读取和写入之间进行仲裁。
    您也是对的、丢失 FIFO 中断和/或未在正确的时间清空中断将使引脚保持高电平、因此我们将无法再处理它。 (这也是功能问题的影响)
    EDMA 中断正确。 当我们达到这个阶段时,知识产权中没有待定的标志。 因此、很可能不会及时处理中断。

    我们将尝试 DMA 的事件触发、而不是 ISR 中的手动触发。

    为了加快通信过程、是否可以请求与您或其他 TI FAE 进行某种直接联系?

    谢谢、

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

    [引用 user="RandyP"]


    我可以想到的两个最大的罪魁祸首是禁用中断或内存总线冲突。 中断可以通过不允许嵌套的另一个中断、或通过显式使用 DINT/EINT 或1-6周期紧密循环来禁用。 您应该知道是否有任何其他中断在坏时处于活动状态、并且它们必须重复很多次才能引起您在这里显示的内容。 为了实现某些算法的最大性能、需要显式使用 DINT/EINT;有时需要进行折衷、以减少 DINT/EINT 的使用、但会牺牲一些性能-这一点对于您的代码来说非常具体。 在 TI 库例程中、不可能出现紧密循环、可以使用您之前提到过的中断编译标志来避免紧密循环。

    [/报价]

    该处理器支持 SPLOOP、这意味着它可以在严格的循环中实现顶级性能、而无需禁用中断。 它只会给中断响应时间增加一些延迟、这是一个折衷方案。 但这是一个很好的折衷方案、因为否则--interrupt_threshold=1和无此类标志之间的性能差异可能会有几。 这自然前提是实际使用 SPLOOP。

    [引用 user="RandyP"]


    因此、如果它是内存总线冲突、则意味着 DSP 在 DMA 通道6传输的同时、在一个小循环中以大块进行大量数据存储器访问、因为它是最长的数据通道、所以最有可能被挂起。 但同样、这一切取决于代码的运行方式及其执行的操作。

    [/报价]

    上面提到的中断响应延迟通常只是几个额外的周期、但它确实取决于存储器存取停止。 换言之、如果数据处于缓存中、您几乎不会注意到差异、但在最坏的情况下、可能只有几微秒、但非常少。 又是什么比例? 这可能是我们在第6次和第7次 D2/3响应中看到的结果吗? 也就是说、到那时、计算部分开始并且表示中断响应时间中的额外延迟[由于存储器访问停止]? 然后、存储器总线冲突可以解释第8个响应。 这就是计算部分和 DMA [CAN]之间发生冲突的地方、这就是为什么它更长的原因、对吧? 但到第9个响应、计算部分和 DMA 之间没有冲突、但响应甚至超过第8个。 当然、计算部分可能会做一些不同于最初的事情、即在第6和第7次响应之前。 但是! 如果涉及 SPLOOP、则程序的不同部分之间的差异不应太大。 我的意思是、如果 SPLOOP 容易受到存储器访问延迟的影响、那么所有 SPLOOP 都可能增加大致相同的延迟、而不管它们在做什么。 [至少在高速缓存打开的情况下、由于高速缓存关闭、某些 SPLOOP 可能会比其他 SPLOP 增加更多的延迟。。]

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

    几个说明。

    [引用用户="Andy Polyakov"]

    上面提到的中断响应延迟通常只是几个额外的周期、但它确实取决于存储器存取停止。 换言之、如果数据处于缓存中、您几乎不会注意到差异、但在最坏的情况下、可能只有几微秒、但非常少。

    [/报价]

    在我看来、我似乎错误地计算了可能的额外延迟。 外部存储器存取可以是几百个周期、我估计它为1us、而它将小于1/2us。 换言之,附加处罚不可能超过1us。 请注意、非 SPLOOP 代码也容易受到类似的惩罚。 换句话说、影响中断响应时间的存储器访问停止并不是专门针对 SPLOOP 中断响应开销的东西。 只是 SPLOOP 有能力让它变得更糟糕、因为不得不等待几个摊位来替代其他摊位。 但无论如何、我们可能会考虑[sub-]微秒延迟。

    [引用用户="Andy Polyakov"]

    又是什么比例?

    [/报价]

    第2次和第5次响应之间的距离(在最后一张图片上)为1毫秒、对吧? 微秒是该值的1/1000、您不会在该图上看到[sub-]微秒变化。 第6个和第7个响应中的延迟似乎是100微秒的数量级。 换句话说、它看起来更像是被禁用/禁止的中断、而不是由内存总线冲突引起的惩罚。 换言之、在两个被推荐的罪犯中、我会说、首先更有可能...

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

    Randy 和 Andy、您好!
    我认为这不是数据访问问题、而是禁用中断。 我已经对所描述的行为进行了更多的测试,下面是方法:
    D14在 D2的上升沿触发的 GPIO ISR 进入中变为高电平、并在其即将退出时变为低电平。
    当调用 DMA 完成中断时、D14变为高电平、在跳转到回调函数之前变为低电平
    在回调函数进入时、D14 g OES 为高电平、在即将退出时变为高电平。
    在第一个快照中、您可以看到 DMA 2 64字节块传输完成后需要4微秒才能到达完成 ISR (实际上需要5微秒、但为了捕捉这一时刻、我们需要一个较大的量程)

    第二种方法还会在 D5完成时对 DMA 传输与其中断触发之间的相同延迟(大约4到5微秒)进行解串

    以下快照说明了首次发生延迟的时间:


    如您所见、D5上的 DMA 传输完成后、D14几乎会变为高电平、而不是正常行为下的4到5微秒。
    这会减慢来自 D2的中断的处理速度、该中断将触发 D4上的 DMA 读取。


    在 D4上 DMA 传输完成后、这种情况再次发生、我花了388微秒到达其完成中断。

    我认为问题是中断被禁用了。
    如果编译器未禁用中断、还可能导致这种情况的原因是什么?
    此致、

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

    这是许多很好的数据、但我需要一段时间才能完全理解它。 Andy 可能会更快。

    我认为、最直接的方法是将问题缩小到代码中出现的位置/时间。 由于问题是可预测、可重复和可控制的(可在以后通过代码更改移动)、因此您可以使用代码断点或延迟循环或早期退出来查找导致问题的至少一系列代码。

    我希望这是一条合理的尝试途径。

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

    [引用用户="bery Sairdi"]

    我认为问题是中断被禁用了。
    如果编译器未禁用中断、还可能导致这种情况的原因是什么?

    [/报价]

    所有可能性都已提及或暗示过。 正如 Randy 提到的、它可以是中断服务例程中的逻辑混合[未正确处理嵌套中断]。 不幸的是、这将是只有您才能解决的问题。 编译器可以在短时间内禁用中断、但它不应该这么做、尤其是在它生成 SPLOOPS 时。 换句话说、请仔细检查它。 使用-mv6748命令行选项并检查汇编输出。 您提到计算部分是由其他人提供的。 如果他们使用汇编语言、他们可能会使用短于6个周期的循环(正如 Randy 提到的、这类循环会在不明确禁用中断的情况下保持中断延迟)? 如果是、则应 使用 SPLOOP 重新实现代码。

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

    您在主程序中跟踪了哪些内容? 它是否缩小到单个例程或函数?

    在研究完屏幕截图后、我看到您的理由是它与中断相关、而不与总线争用相关。

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

    您好!

    很抱歉、由于延迟、我们无法在代码内进行双字搜索、因此找到了问题。
    以下是我们更改的内容列表:
    -禁用中断的算法是使用 interrupt_threshold=1000进行编译的、并使用了2个 mathlib 函数。 我们将中断阈值降低到1、并在纯 C 语言中重新执行函数
    我们意识到我们依赖错误的 PLL 配置、并且我们让电路板"真正"以456Mhz 运行、EMIFA 以100Mhz 运行。 遗憾的是、我们没有 EMIFA 时钟或任何其他 PLL 的测试点、因此我们完全依赖 AISgen 实用程序。
    然后、我们尝试使用 processors.wiki.ti.com/.../AM18xx 中的电子表格配置系统、并使用我们馈入的设置/选通/保持值相关的 EMIFA 时钟计算结果、我们现在正极板运行速度尽可能快。
    我们对同样以75MHz 时钟频率运行的 DDR2也做了同样的事情。 它的速度没有翻倍。
    所有这些更改的摘要:

    - Mathlib 在其代码中使用"DINT"指令。 因此、在没有该算法的情况下会重新实现该算法。

    -我们确保电路板以456Mhz、100Mhz EMIFA、150Mhz DDR2的速度运行。

    现在、系统满足了其硬时间期限、标志设置后的 ISR 称为3微秒。

    、感谢您投入我们的问题所花的所有时间和精力。 您非常乐于助人!

    也感谢您的贡献、您所关注的所有细节有助于将问题缩小到几个方面。
    此致、

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

    [引用用户="bery Sairdi"]

    - Mathlib 在其代码中使用"DINT"指令。 因此、在没有该算法的情况下会重新实现该算法。

    [/报价]

    如果好奇、哪2项功能? :-)

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

    您能否指定 MATHLIB 的版本、以便我们记录或提交此软件的错误报告。

    此致、
    Rahul
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Rahul、
    很抱歉耽误你的时间。 Mathlib/DSPLIB 没有错误。 根据设计、它旨在通过禁用中断来优化性能。
    我必须使用 C 自然版并使用--interrupt_threshold=1重新编译它们。
    谢谢、