Memory 为什么要将内存区域标记为非缓存?

Memory 为什么要将内存区域标记为非缓存?,memory,caching,embedded,Memory,Caching,Embedded,在嵌入式应用程序中,我们有一个表,描述在目标板上有效的各种地址范围。此表用于设置MMU。 RAM地址范围标记为可缓存,但其他区域标记为不可缓存。为什么会这样?可能它用于内存映射I/O?任何用于DMA或其他硬件交互的内存区域都不应缓存。这样做是为了使处理器不会因为缓存而使用过时的值。 当您访问(常规)缓存RAM时,处理器可以“记住”您访问的值。下次您查看同一个内存位置时,处理器将返回它记住的值,而不查看RAM。这是缓存 如果位置的内容可以在处理器不知道的情况下更改,就像您有一个内存映射设备(例如返

在嵌入式应用程序中,我们有一个表,描述在目标板上有效的各种地址范围。此表用于设置MMU。

RAM地址范围标记为可缓存,但其他区域标记为不可缓存。为什么会这样?

可能它用于内存映射I/O?

任何用于DMA或其他硬件交互的内存区域都不应缓存。

这样做是为了使处理器不会因为缓存而使用过时的值。 当您访问(常规)缓存RAM时,处理器可以“记住”您访问的值。下次您查看同一个内存位置时,处理器将返回它记住的值,而不查看RAM。这是缓存

如果位置的内容可以在处理器不知道的情况下更改,就像您有一个内存映射设备(例如返回一些数据包的FPGA),那么处理器可能会返回上次“记住”的值,这是错误的


要避免此问题,请将该地址空间标记为不可缓存。这可确保处理器不会试图记住该值。

如果硬件和软件同时访问内存区域(例如:DMA的硬件配置寄存器或分散收集列表),则该区域必须定义为非缓存。对于实际的DMA,内存缓冲区可以定义为缓存,在大多数情况下,建议缓存缓冲区,以允许应用程序级快速访问该缓冲区。在将缓冲区传递给DMA或应用程序之前,驱动程序负责刷新/使缓存失效


如果我们有一个专门的硬件,即缓存一致性互连(CCI),它将同步各种硬件块对内存的访问,则上述必须的小更新是不正确的

某些区域(如闪存)可以在一个周期内读取,因此不需要缓存。

现代控制器可以将二级缓存用于DMA,这意味着它们保留了用于DMA访问的缓存内存区域的一致性。这也称为控制器(通过DMA)执行的“可窥探内存事务”。

考虑到缓存一致性。假设内存中有一个位置X可供使用DMA的设备访问,因此当设备将新值写入X时,cpu不会被唤醒。如果cpu以前缓存过X的内容,当cpu需要该值时,它将从缓存中获取该值。在这种情况下,cpu会得到过时的值。类似地,使用DMA的设备也可能读取过时的值


在wiki上,我正在做一个这样的嵌入式项目,其中DRAM的一部分被标记为不可缓存的阴影内存。这实际上是我物理内存的一部分,而不是内存映射设备。这种用于草稿行和错误检查的内存区域不会被缓存。我需要一些1纳秒的闪存。我不知道有哪种闪存可以在一个时钟周期内访问。事实上,我完全不知道在一个时钟周期内会发生什么操作。据我所知,在大多数体系结构上,即使NOP也需要大约4个周期。