【问题标题】:ARM Cortex M7: can a cache clean overwrite changes made by DMA device?ARM Cortex M7:缓存清理可以覆盖 DMA 设备所做的更改吗?
【发布时间】:2021-09-28 05:15:44
【问题描述】:

我正在为 STM32H743 SoC 中的 DMA 总线主设备开发驱动程序,由 Cortex M7 CPU 驱动。假设我有两个内存位置,xy,它们映射到同一缓存行,它位于正常的可回写缓存内存,并假设以下事件序列:

  1. x = x1, y = y1 开头,缓存行无效。
  2. CPU 读取y
  3. DMA 设备集x = x2,在内存中
  4. CPU 集y = y2
  5. CPU 清理缓存行。

5.完成后,从DMA设备的角度来看x = ?

我认为 DMA 会看到 x = x1,这是我的推理:

  • 当 CPU 在 2. 中读取 y 时,缓存行被拉入缓存。它读取x = x1, y = y1,并被标记为有效。
  • DMA 然后更新内存中的x,但更改不会反映在缓存行中。
  • 当 CPU 设置y = y2 时,缓存行被标记为脏。
  • 当 CPU 清理缓存行时,由于它是脏的,它会被写回内存。
  • 当它被写回内存时,它会读取x = x1, y = y2,从而覆盖 DMA 更改为 x

这听起来像是一个很好的推理吗?

【问题讨论】:

    标签: caching arm stm32 cpu-cache cortex-m


    【解决方案1】:

    简而言之,如果我的问题是正确的,那么你的描述是正确的。

    从问题中不太清楚“两个内存位置,x 和 y”是什么。

    根据您在描述中使用它们的方式,我认为它类似于 2 个指针。

    int* x, y;
    

    并且“以x = x1, y = y1开头”表示为该指针分配地址,例如

    x = (int*)(0x2000); // x = x1
    y = (int*)(0x8000); // y = y1
    

    现在回答您的问题:“在 5. 完成后,从 DMA 设备的角度来看,x = ?”

    所以在第 3 步之后,x = x2, y = y1 在内存中,x = x1, y == y1 在缓存中。

    在第 4 步之后,x = x2, y = y1 在内存中,x = x1, y = y2 在缓存中。

    内存x/y指针的DMA访问值,缓存x/y指针的CPU访问值。因为缓存和内存不同步(缓存是脏的)在那个阶段CPU和DMA会得到不同的值。

    最后在第 5 步之后...
    这取决于。缓存控制器通过缓存线、某种大小的内存区域(如 32 字节、64 字节等)(可能更大或更小)进行操作。因此,当 CPU 清理/刷新包含某个地址的缓存行时,它会将整个缓存行的内容刷新到内存中。内存中的任何内容都会被覆盖。

    基本上有2种情况:

    • xy 指针都在同一个缓存行中。这意味着缓存中的值将覆盖内存,您是对的,x = x1, y == y2 将在内存和缓存中完成。
    • xy 指针位于不同的缓存行中。很简单,只有一个变量会受到影响,另一个缓存行仍然是脏的。

    【讨论】:

    • 感谢您的回复。实际上,当我写例如x = x1,我的意思是 *x = x1,抱歉,不清楚。在我写的步骤中,DMA 和 CPU 只改变 *x 和 *y,而不是 x 和 y。尽管如此,我相信你的观点仍然成立,因为 CPU 和 DMA 正在访问地址 x 和 y 的内存/缓存。如果 x 和 y 包含的地址在同一缓存行中,那么在这种情况下,清理操作将覆盖 DMA 所做的更改。
    猜你喜欢
    • 1970-01-01
    • 2021-10-24
    • 2019-12-14
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-09-24
    • 1970-01-01
    • 2012-09-28
    相关资源
    最近更新 更多