繁体   English   中英

为什么 DSB 不刷新缓存?

[英]Why does DSB not flush the cache?

我正在使用 LWIP 和 HAL 驱动程序在 STM32H725VG 上调试 HTTP 服务器,所有这些驱动程序最初都是由 STM32CubeMX 生成的。 问题在于,在某些情况下,通过HAL_ETH_Transmit发送的数据HAL_ETH_Transmit一些八位字节替换为 0x00,并且这些损坏的内容成功到达客户端。

我已经检查过作为参数传递给HAL_ETH_Transmit的缓冲区中的数据在调用此函数之前和之后都完好无损。 因此,显然,损坏发生在从 RAM 到 MAC 的传输时,因为校验和是根据损坏的数据计算的。 所以我认为问题可能是由于缓存和 DMA 之间的交互造成的。 我试过禁用 D-cache,然后就不会发生损坏。

然后我想我应该只使用__DSB()指令将缓存的数据写入 RAM。 启用 D-cache 后,我在调用HAL_ETH_Transmit之前添加了__DSB() (它在low_level_output生成的 low_level_output 函数中),然后......什么也没发生:数据仍然损坏。

然后,经过一些实验,我发现在SCB_CleanDCache()之后(或代替SCB_CleanDCache()调用__DSB()解决了这个问题。

这让我感到奇怪。 DSB指令说明如下

数据同步屏障充当一种特殊的内存屏障。 此指令执行后,程序顺序中的指令不会执行,直到此指令完成。 该指令在以下情况下完成:

  • 在此指令完成之前的所有显式内存访问。
  • 在此指令完成之前的所有缓存、分支预测器和 TLB 维护操作。

并且SCB_DisableDCache描述有以下关于SCB_CleanDCache

禁用数据缓存时,您必须清除 ( SCB_CleanDCache ) 整个缓存以确保将任何脏数据刷新到外部存储器。

如果在“所有显式内存访问”完成时应该完成缓存, DSB为什么不刷新缓存,这似乎包括缓存的刷新?

dsb ish作为线程间内存顺序的内存屏障; 它只是命令当前 CPU 对一致性缓存的访问。 您不会期望dsb ish刷新任何缓存,因为这对于同一内部可共享缓存一致性域中的可见性而言不是必需的。 就像您引用的手册中所说的那样,它完成了内存操作。

写回缓存上的可缓存内存操作仅更新缓存; 等待它们完成并不意味着刷新缓存。

我认为您的 ARM 系统对于微控制器与 DSP 具有多个一致性域? 您的__DSB内部函数是否编译为__DSB dsb sy指令? 假设不刷新缓存,它们的意思大概是它对内存/缓存操作进行排序,包括显式刷新,这仍然是必要的。

我会把钱花在性能上。

刷新缓存是指将数据从缓存写入内存。 内存访问很慢。

L1 缓存大小(假设 ARM Cortex-A9)为 32KB。 您不想无缘无故地将整个 32KB 从缓存移动到内存中。 可能有 L2 缓存,很容易达到 512KB-1MB(可能更多)。 您也真的不想移动整个 L2。

事实上,您的整个 DMA 传输可能小于缓存的大小。 根本没有理由这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM