# SPI1 flash 并发约束

[English]

指令/数据 cache（用以执行固件）与 SPI1 外设（由像 SPI flash 驱动一样的驱动程序控制）共享 SPI0/1 总线。因此，SPI1 外设上的操作会对整个系统造成显著的影响。这类操作包括调用 SPI flash API 或者 SPI1 总线上的其他驱动、任何 flash 操作（如读取、写入、擦除）或是由其他用户定义的 SPI 操作（对主 flash 或是其他 SPI 从机）。

在 ESP32 上，flash 读取/写入/擦除时，必须禁用 cache。

## 禁用 cache 时

此时，在 flash 擦写操作中，所有的 CPU 都只能执行 IRAM 中的代码，而且必须从 DRAM 中读取数据。如果使用本文档中的 API 函数，上述限制将自动生效且透明（无需额外关注），但这些限制可能会影响系统中的其他任务的性能。

为避免意外读取 flash cache，一个 CPU 在启动 flash 写入或擦除操作时，另一个 CPU 将阻塞。在 flash 操作完成前，会禁用所有在 CPU 上非 IRAM 安全的中断。

另请参阅 OS 函数 和 SPI 总线锁。

除 SPI0/1 以外，SPI 总线上的其他 flash 芯片则不受这种限制。

请参阅 应用程序内存分布，查看内部 RAM（如 IRAM、DRAM）和 flash cache 的区别。

### IRAM 安全中断处理程序

如果需要在 flash 操作期间运行中断处理程序（比如低延迟操作），请在 注册中断处理程序 时设置 `ESP_INTR_FLAG_IRAM`。

请确保中断处理程序访问的所有数据和函数（包括其调用的数据和函数）都存储在 IRAM 或 DRAM 中。参见 如何将代码放入 IRAM。

在未将函数或符号正确放入 IRAM/DRAM 的情况下，在 flash 操作期间，中断处理程序从 flash cache 中读取数据时，会导致程序崩溃。这可能是因为代码未正确放入 IRAM，产生了非法指令异常，也可能是因为常数未正确放入 DRAM，读取到了垃圾数据。

备注

在 ISRs 中处理字符串时，不建议使用 `printf` 和其他输出函数。为了方便调试，在从 ISRs 中获取数据时，请使用 `ESP_DRAM_LOGE()` 和类似的宏。请确保 `TAG` 和格式字符串都放置于 `DRAM` 中。

### 非 IRAM 安全中断处理程序

如果在注册时没有设置 `ESP_INTR_FLAG_IRAM` 标志，当禁用 cache 时，将不会执行中断处理程序。一旦 cache 恢复，非 IRAM 安全的中断将重新启用，中断处理程序随即再次正常运行。这意味着，只要禁用了 cache，就不会发生相应的硬件事件。

此文档对您有帮助吗？

- 反馈已收到，谢谢！
- 如果您有其他意见，欢迎填写乐鑫文档反馈表。

- 我们重视您的反馈。
- 您可以填写乐鑫文档反馈表告诉我们如何改进该文档。