SPI1 Flash 并发约束

指令/数据 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 被禁用,将不会发生相应的硬件事件。