SPI Flash Modes 介绍


该文章翻译来源为 https://github.com/espressif/esptool/wiki/SPI-Flash-Modes

它主要介绍了我们烧录 ESP8266 和 ESP32 时对 SPI 接入方式该如何选择,每次我看到什么 DIO,DOUT,DIO 和 QOUT 都一脸懵B不知道该选什么,网上好像也没有什么专门讲这个的文章,至到我找网上翻到官方的文档,所以这里把它记录并翻译过来供大家参考,如果翻译错了请到 https://github.com/Caffreyfans/Caffreyfans.github.io.git 提交 issues 指出问题,我会即时修改。

ESP8266 和 ESP32 支持 4 种不同的 SPI flash 接入模式:DIO,DOUT,DIO 和 QOUT。他们可以在使用 esptool.py write_flash 使用 --flash_mode 选项。

这些选择控制多少 I/O 引脚被来与 SPI 闪存芯片连接,传输数据,和用哪种 SPI 命令。

ESP8266 和 ESP32 在从当从 SPI 闪存芯片读或执行代码和数据时用这些命令。读取数据,然后内部缓存到芯片。

总结

按性能排序:

选项 模式名 引脚使用 速度(ESP8266 & ESP32)
qio 四路 I/O 4 个引脚用于地址和数据 最快
qout 四路输出 4 个引脚用于数据 qio 模式约慢 15%
dio 两路 I/O 2 个引脚用于地址和数据 qio 慢约 45%
dout 两路输出 2 个引脚用于数据 qio 约慢 50%

一般来说,应该为你的设备选择最快的 flash 模式。但是不是所有设备都支持所有工作模式。详情见下列 FAQ 部分。

工作模式描述

常规 SPI

一个传统的“单独”SPI(串行外设接口)总线使用 4 个引脚进行通信:

所有这些信号都是单向的。在单独的 SPI 模式,数据通过MISO引脚从设备发送到主机,并通过MOSI引脚从主机发送到设备。

正常 SPI 的最大数据速率是时钟速率(以位为单位)-所以一个 40MHz 的时钟 = 40Mbits/每秒 = 5Mbytes/每秒。

双路 SPI

为了提升性能,SPI 闪存厂商引进了“双路 SPI”。在双路 SPI 模式下,MOSI 和 MISO 引脚都被同时用来读取或写数据,每个时种周期为 2 位。相对于单独 SPI,一些指令就有两倍速率。

dout 模式下,主机使用“双输出快速读取”(3BH)命令去读取数据。每个读取指令和读取地址都通过常规 SPI 发送到闪存芯片,但主机同时通过 MOSI 和 MISO 引脚以每个时钟周期 2 位的速率读取数据。与仅使用 MISO 读取数据的单个 SPI 相比,这传数据传输速率提高了一倍。

dio 模式下,主机使用“双 I/O 快速读取”(BBH)命令去读取数据。每个读取指令都通过常规 SPI 发送到闪存芯片,但地址通过 MOSI 和 MISO 引脚以每个时钟周期 2 位的速率发送到闪存芯片。在这之后,主机以“双输出快读取”相同的方式读取每个时钟具有 2 位的速率。

对于 ESP8266 和 ESP32,每次指令读取 32 个字节,并且 dio 模式大约快 dout 快 5%。

请查阅您的特定 SPI 闪存芯片的数据表,以确定它是否支持这两个命令的一个或两个。

四路 SPI

为了进一步提高 SPI 闪存数据传输的性能,SPI 闪存厂商引进了“四路 SPI”模式。这种模式增加两个附加引脚(否则用于闪存芯片 WP 信号和 HOLD 信号)用于数据传输。这是使两 SPI 的数据传输速率提高一倍。

并不是所有 flash 芯片都支持四路 SPI 模式,而且并不是所有 ESP8266 和 ESP32 芯片都有这些引脚连接到 SPI 闪存芯片。一些闪存芯片要求特殊的指令实现四路模式(见下方)。

qout 模式,主机使用“四输出快速读取”(6BH)指令读取数据。这种命令与“双路输出快速读取”相同,只是数据读取用 4 个引脚代替了 2 个引脚,也就是每个时钟 4 位的速率。这使得传输数据实际快“双路输出快速读取”一倍。

qio 模式,主机使用“四路 I/O 快速读取”(EBH)指令读取数据。这命令与“双路 I/O 快速读取”相同,每个地址和数据传输用 4 个引脚代替了 2 个引脚,也就是每个时钟周期 4 位的速率。这使得地址和数据传输速度都比“双路 I/O 快速读取”快一倍。

常问问题

为什么我的乐鑫芯片或模组不能使用 qio 或 qout 模式?

这通常是以下原因:

  • SPI 闪存芯片上的 WP 和 HOLD 引脚没有与乐鑫上的 GPIO 引脚正确连接。这些引脚必须正确连接才能让 quad 模式工作,不是所有板子和模组都连接了它们的。
  • SPI 闪存芯片不支持 quad 模式。查看 闪存芯片的数据表看它是否支持。你可以直接看闪存芯片上面印的型号或者使用 esptool.py flash 命令。
  • 此芯片型号未正确启用 Quad 模式。SPI 闪存不是标准的,每个厂商实施它们芯片的方式都不一样。大多数闪存芯片需要发送某些命令才能启用 Quad SPI 模式,这些命令会有所不同。对于 ESP8266 和 ESP32,这通常意味着芯片第一次以双路 SPI 模式启动然后软件(ESP32 的启动引导或者 ESP8266 的SDK)检测芯片类型并尝试使能四路 SPI 模式。如果具体的芯片类型不被软件支持那么它将无法进入四路模式。

为什么 qout 和 dout 模式正常但是 qio 和 dio 模式不正常?

一些 SPI 闪存芯片类型只支持“双路输出快速读取”和“四路输出快速读取”指令,而不是等效的“双路 I/O”和“四路 I/O”。

与四路 SPI 相比,我的代码在双路 SPI 模式下的运行速度快一半吗?

不是。ESP8266 和 ESP32 都是从 flash 里直接执行代码,但是,由于从闪存读取速度很慢,因此数据会透明地缓存在 RAM 中。仅在发生高速缓存未命令时发送闪存读取指令。但是,使用双路 SPI 读取重新填充缓存的速度大约是四路 SPI 的一半。

如果你不能使用四路 SPI 模式,请确保你配置的最快 SPI 闪存时钟速率能够让你的板子或者模组可靠地工作。两路 I/O 模式下的 80Mhz 时钟比四路 I/O 模式下的 40HMz SPI 时钟快。

闪存是如何与 ESP8266 或 ESP32 通信的?

启动引导 .bin 文件,被烧录在 SPI 闪存里,头部包含闪存速度,闪存工作模式,和其他元数据。初始主机模式由 ROM 代码确定,当它在重置后会读取到该头部。esptool.py 为 -flash_mode 传入参数当文件被烧录到 flash 里时会更新头部。

这仅确定用于从复位进行初始引导的模式。然后,在启动过程中,软件可能会不同涤配置闪存模式。

比如,在 ESP32 上,如果将 ESP-IDF 配置为 qio/qout 模式,则实际上以 dio/dout 模式刷新 IDF 软件引导程序。当 ROM 代码从闪存引导该引导加载程序时,引导加载程序软件会检查闪存芯片型号,并在其余的引导过程中启用正确的四路 SPI 模式。这是因为有很多不同的方法可以在不同的芯片型号上启用四路 SPI。


文章作者: Caffreyfans
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Caffreyfans !
  目录