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.

[FAQ] [参考译文] [常见问题解答] TMS570LC4357:如何解决通过 CPU 和 DMA 访问共享存储器时的高速缓存一致性问题?

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1158788/faq-tms570lc4357-how-to-solve-the-cache-coherency-issues-when-accessing-the-shared-memory-through-cpu-and-dma

器件型号:TMS570LC4357

在 CPU 更新了数据缓冲区后、DMA 仍在传输缓冲区中的旧内容、而不是更新后的内容。  

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

    TMS570LC43x 和 RM57Lx 具有 DMA 和数据缓存(DCache)。 我们可以使用 DMA 在外设和存储器之间或存储器和存储器之间进行数据传输。  DMA 传输不会通过 MCU DCache。 它将数据直接写入存储器。 SRAM 受 MPU 保护。 高速缓存策略和分配是可编程的。

    使用写分配(WBWA)进行回写可提供最佳性能。 高速缓存命中次数仅更新高速缓存。 高速缓存未命中写入时、将数据从主存储器复制到高速缓存。 因此、后续访问会导致缓存命中。 默认情况下、读分配是永久启用的。

    在 SRAM 上启用高速缓存、可高速缓存属性设置为使用写分配(WBWA)进行回写。 CPU 之前已读取 DMA 缓冲区、因此、由于读取分配策略、缓存中的相同数据可用。

    缓存一致性问题- DMA 写入 SRAM

    • DMA 从外设读取数据并更新 SRAM 中的接收缓冲区。
    • 当 CPU 尝试读取接收缓冲区时、它将读取缓存中存在的数据、而不是 SRAM 中可用的新数据。

    2.高速缓存一致性问题- DMA 从 SRAM 读取

    • 由于缓存策略设置为 WBWA、CPU 更新要在传输缓冲区中传输的数据、仅更新缓存、而不更新主存储器。
    • 当 DMA 读取发送缓冲区时、它读取出现在主存储器中的旧值、而不是 CPU 更新的最新值、而 CPU 仍在缓存中。

    有两种机制可以保持一致性:

    1.禁用缓存

    这是最简单的机制、但可能会降低 MCU 的性能。 为了获得最高性能、CPU 通过流水线实现快速运行、并从延迟极低的高速缓存运行。 对多次访问的数据进行高速缓存可显著提高性能并减少 SRAM 访问。 将数据标记为"非缓存"可能会影响性能。

    2.软件管理一致性

    软件管理一致性是解决数据共享问题的传统解决方案。 软件必须清除或清除缓存中的脏数据、并使旧数据无效、以实现与其他总线主控(CPU 或 DMA)的共享。

      当 DMA 写入 SRAM 条件时:

    • DMA 将数据写入 RX_buffer []
    • 使缓存的 rx_buffer 无效[]

          coreInvalidateDCByAddress (uint32 u32Address、uint32 u32Size);

    • CPU 尝试读取 RX_buffer []并导致缓存未命中,因为在步骤2中,RX_buffer []无效
    • 由于读取分配策略、将分配一个缓存行、并将数据从 SRAM 中的 Rx_buffer []复制到分配的缓存行。
    • 然后、CPU 从高速缓存读取将保持一致。

      当 DMA 读取 SRAM 条件时:

    • CPU 最初访问了传输缓冲区(TX_buffer [])、并将其缓存在 D-Cache 中。
    • CPU 将数据写入将由 DMA 传输的 TX_buffer []。
    • 执行缓存清理操作、在启用 DMA 传输之前将缓存的 TX_buffer []刷新到 SRAM 中。

          coreCleanDCByAddress (uint32 u32Address、uint32 u32Size);

    • 从 SRAM 读取的 DMA 现在将保持一致。