ARM Cortex M7:缓存是否可以清除 DMA 设备所做的更改?
ARM Cortex M7: can a cache clean overwrite changes made by DMA device?
我正在为 STM32H743 SoC 中的 DMA 总线主设备开发驱动程序,由 Cortex M7 CPU 提供支持。假设我有两个内存位置,x
和 y
,它们映射到同一个缓存行,在 正常的可回写缓存内存 中,并假设以下事件顺序:
- 从
x = x1, y = y1
开始,缓存行无效。
- CPU 读取
y
- 内存中的 DMA 设备集
x = x2
- CPU 集
y = y2
- 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
.
这听起来像是一个很好的推理吗?
很快,如果我答对了你的问题,那么你的描述是正确的。
“两个内存位置,x 和 y”的问题不是很清楚。
根据您在描述中如何使用它们,我认为它类似于 2 个指针。
int* x, y;
和“Start with 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 访问值,CPU x
/[= 的访问值18=] 缓存 中的指针。因为在那个阶段缓存和内存不同步(缓存是脏的)CPU 并且 DMA 会得到不同的值。
最后在第 5 步之后...
这取决于。缓存控制器由缓存行操作,缓存行是一定大小的内存区域,例如 32 字节、64 字节等(可能更大或更小)。因此,当 CPU 执行 clean/flush 包含某个地址的缓存行时,它会将整个缓存行的内容刷新到内存中。内存中的任何内容都会被覆盖。
基本上有2种情况:
x
和 y
指针都在同一缓存行中。这意味着缓存中的值会覆盖内存,你是对的,x = x1, y == y2
会在内存和缓存中完成。
x
和 y
指针在不同的缓存行中。就这么简单,只有一个变量会受到影响,另一个缓存行仍然是脏的。
我正在为 STM32H743 SoC 中的 DMA 总线主设备开发驱动程序,由 Cortex M7 CPU 提供支持。假设我有两个内存位置,x
和 y
,它们映射到同一个缓存行,在 正常的可回写缓存内存 中,并假设以下事件顺序:
- 从
x = x1, y = y1
开始,缓存行无效。 - CPU 读取
y
- 内存中的 DMA 设备集
x = x2
- CPU 集
y = y2
- 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
.
这听起来像是一个很好的推理吗?
很快,如果我答对了你的问题,那么你的描述是正确的。
“两个内存位置,x 和 y”的问题不是很清楚。
根据您在描述中如何使用它们,我认为它类似于 2 个指针。
int* x, y;
和“Start with 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 访问值,CPU x
/[= 的访问值18=] 缓存 中的指针。因为在那个阶段缓存和内存不同步(缓存是脏的)CPU 并且 DMA 会得到不同的值。
最后在第 5 步之后...
这取决于。缓存控制器由缓存行操作,缓存行是一定大小的内存区域,例如 32 字节、64 字节等(可能更大或更小)。因此,当 CPU 执行 clean/flush 包含某个地址的缓存行时,它会将整个缓存行的内容刷新到内存中。内存中的任何内容都会被覆盖。
基本上有2种情况:
x
和y
指针都在同一缓存行中。这意味着缓存中的值会覆盖内存,你是对的,x = x1, y == y2
会在内存和缓存中完成。x
和y
指针在不同的缓存行中。就这么简单,只有一个变量会受到影响,另一个缓存行仍然是脏的。