大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是i.MXRT上使用16MB以上NOR Flash软复位无法正常启动问题的分析解决经验。
五年前痞子衡写过一篇文章 《IS25WP256D的Bank Address Register[0]使用对RT1050软复位启动的影响》,这篇文章介绍了对大容量 Flash(>16MB) 的3字节地址命令下高/低地址空间(128Mb segment)切换特殊设计的利用需要注意,如果主芯片 App 程序中包含内核软复位设计,记得内核复位前先将 Flash 设置到初始状态。
最近有一个 RT1180 客户,启动 Flash 选用得是 IS25LP256H,App 程序里使用 Zephyr Flash 驱动时发现只要调用了 flash_flexspi_nor_4byte_enable() 函数后再做内核软复位,芯片就不能再次启动了,这其实还是大容量 Flash 地址模式搞的鬼。今天痞子衡就和大家聊聊这个问题:
一、大容量Flash地址模式设计
痞子衡列出了下面 6 个主流 Flash 厂商的代表大容量 QSPI NOR 型号,将其关于地址模式的信息整理在了一起,开头提及的文章里 4.3 关于Flash的3/4字节地址 小节说了,大容量 Flash 一般都支持 3/4B 地址两套命令,4B 地址命令只接受 4B 地址(不受地址模式影响),3B 地址命令则根据当前地址模式来决定到底跟 3/4B 地址。
| Flash | 地址模式设计 |||||
| Flash |
|-------------|--------------|------------------------------------------------------------------------|-----------|----------------------------------------------------|-----------|
| 进/出4B地址命令 | 高低Segment配置位 | 高低Segment寄存器写命令 | 3/4B地址配置位 | 3/4B地址寄存器写命令 |
| IS25LP256H | 0xB7/0xE9 | Bank Address Register[0] - BA24 | 0x18/0xC5 | Bank Address Register[7] - EXTADD | 0x18/0xC5 |
| W25Q256JV | 0xB7/0xE9 | Extended Address Register[0] - A24 | 0xC5 | Status Register-3[1:0] - ADP,ADS | 0x11 |
| GD25Q256M | 0xB7/0xE9 | Extended Address Register[0] - A24 | 0xC5 | Status Register-2[13:12] - ADS,ADP | 0x31 |
| MX25L25645G | 0xB7/0xE9 | Extended Address Register[0] - A24 | 0xC5 | Configuration Register[5] - 4BYTE | 0x01 |
| S25FL256L | 0xB7/0xE9 | N/A | N/A | Configuration Register 2 Volatile[1:0] - ADP,ADS | 0x71 |
| MT25QL256A | 0xB7/0xE9 | Extended Address Register[0] - A24 16bit Configuration Register[0] | 0xC5,0xB1 | N/A | N/A |
上表里我们可以看到所有厂商对于进入/退出 4B 地址模式的命令设计都是一样的(初始情况下 Flash 都是 3B 地址模式),关于高低 Segment 配置设计除了 Infineon 之外,其他厂商都支持并且设计上也兼容。最后就是 3/4B 地址模式切换除了有专用命令设计外,除 Micron 之外的其他厂商也提供直接写配置寄存器的方式,但是这里分为两派:一派是 Winbond、GigaDevice、Infineon,其写寄存器切换地址模式仅在 POR 或者 reset 时才会生效,而另一派 ISSI、MXIC 则写了相应配置寄存器后新地址模式直接生效。
二、Zephyr下flash_flexspi_nor_4byte_enable()
了解了大容量 Flash 的地址模式以及切换方法,我们再来看看 Zephyr 驱动里是怎么处理的,我们找到这个函数实现,其 en4b 参数区分了好几种不同处理,最主要的方式就是发 0xB7 专用命令切到 4B 地址模式。
text
en4b & BIT(6) - Flash is always in 4 byte mode. We just need to configure LUT
en4b & BIT(0) - Issue instruction 0xB7
en4b & BIT(1) - Issue write enable, then instruction 0xB7
en4b & BIT(4) - Set bit 0 of 16 bit configuration register via 0xB1 cmd
Other methods not supported. Include:
BIT(2): 8-bit volatile extended address register used to define A[31:24] bits.
BIT(3): 8-bit volatile bank register used to define A[31:24] bits.
BIT(5): Dedicated vendor instruction set.

从这个函数设计我们知道 Zephyr Flash 驱动使用了 3B 地址命令结合地址模式切换来支持所有容量 Flash 的全部空间访问,并没有启用 4B 地址命令(毕竟 4B 地址命令仅在大容量 Flash 上支持)。
三、RT系列对于Flash地址模式处理
我们知道 RT 系列芯片上电 ROM 默认是用 0x03 命令 + 3B 地址来获取 FCB 的,当第一次启动成功之后,如果 App 程序里将 Flash 切换到 4B 地址模式,然后做内核软复位重新启动,此时 ROM 再用 0x03 命令 + 3B 地址就不能再拿到正确的 FCB 了,这就是再次启动失败的原因。
3.1 RT10xx系列ROM设计
在 RT10xx 上 ROM 在 BT_CFG 的 FLASH_TYPE 里放了 3'b000 和 3'b001 两种配置,分别对应 Flash 是 3B/4B 地址模式两种情况,从而用 0x03 命令 +3/4B 地址来获取 FCB。这样的设计仅对 RT 芯片 POR 时有效,但如果是切换 Flash 地址模式后内核软复位的情况依然失效(因为 BT_CFG 不能动态更改)。
更进一步的理解是这种设计是针对 Flash 默认地址模式是 4B 的情况,但实际上几乎没有 Flash 默认地址模式是 4B,毕竟已经有一套专门 4B 地址命令在这了。

3.2 RT11xx/RT3digits系列ROM设计
为了改进 RT10xx 上 ROM 缺陷,在 RT11xx ROM 里 xSPI_FLASH_TYPE 干脆就拿掉了 3'b001 配置(注意这里仅仅是文档方面移除,代码里实际上支持还在),取而代之的是真正解决地址模式切换问题的手段,详见痞子衡旧文 《RT系列ROM中集成的NOR SW Reset功能》,简单来说就是假设 Flash 软复位后状态是 3B 地址模式,ROM 上电后先对 Flash 做一次软复位,再用 0x03 命令 +3B 地址来获取 FCB,这个设计逻辑看起来通顺了,唯一需要注意的是软复位能不能将 Flash 地址模式恢复到默认状态,这个需要检查具体 Flash 数据手册。

四、通用解决方案
上一节讲得都是依赖 ROM 来解决 Flash 地址模式切换问题,这其实还是没有把控全局的感觉,毕竟 Flash 地址模式是在 App 程序里切换的,那显然 App 程序在做内核软复位的时候自己主动将 Flash 地址模式再切回来不就完了吗!就像痞子衡旧文 《SW Reset退出NOR Continuous read模式》 里做法那样,App 程序里加上 Flash 复位命令相关代码(对本文来说也可以是退出 4B 地址模式命令相关代码),在需要的地方调用一下即可。
至此,i.MXRT上使用16MB以上NOR Flash软复位无法正常启动问题的分析解决经验痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。
