大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT1064片内Flash的RESET#引脚对程序启动和运行的影响。
上一篇文章 《i.MXRT1024/1064片内4MB Flash的SFDP表易丢失导致的烧录异常》 痞子衡带大家初步了解了 i.MXRT 上片内合封的 4MB Flash,合封 Flash 方式一般来说比外挂方式要省事省心,但前提是你充分了解了它的合封方式、信号连接等细节。如果对这些细节没有完全掌握,合封就像是一个黑盒子,还真不一定就比外挂可靠。
近期另有一个 RT1064 客户反馈,产品在运行过程中会发生极小概率的宕机,分析发现宕机时(不断电情况下)内部 Flash 读回的程序数据竟然全是 0x00,看起来 Flash 内容被篡改了,但是重新上电又能正常工作,这是怎么回事?今天痞子衡就和大家聊聊这个话题:
- Note:本文所述问题仅在 RT1064 上发生,不存在于 RT1024 上。
一、RT1024/1064片内Flash连接差异
1.1 W25Q32JV不同封装
我们知道 RT1024/RT1064 内部合封得是 Winbond W25Q32JV 裸 Die,而 W25Q32JV 作为单独产品售卖时实际上提供了非常多的封装形式,这其中我们最熟悉得是经典的 8 个引脚的 SOIC-8 208-mil 封装。
从 W25Q32JV 裸 Die 本身角度来说,其一共有 9 个信号线,在 SOIC-8 上将本该单独引出的 RESET# 信号复用到了 IO3 上(虽然这个脚本身还有一个 HOLD# 复用),而在 SOIC-16 或者 TFBGA-24 上我们就能看到这个单独的 RESET# 信号了:
1.2 RT1024片内RESET#连接
在 RT1024 上,内部 Flash 的 RESET# 信号保留悬空(或其它处理),并没有和 RT1020 之间有信号连接,这里 GPIO_AD_B1_13 被着重强调,是因为 RT1024 BootROM 会根据 efuse 配置情况控制这个 I/O 来复位 Flash(显然这里是无效的)。
1.3 RT1064片内RESET#连接
在 RT1064 上,内部 Flash 的 RESET# 信号被连接到了 RT1060 内部信号 GPIO_SPI_B0_13 上,当然 RT1064 BootROM 也会根据 efuse 配置情况控制这个 I/O 来复位 Flash(这时就会产生一定作用)。
二、不处理片内Flash RESET#信号带来的风险
在痞子衡旧文 《深入i.MXRT系列ROM中串行NOR Flash启动初始化流程》 一文 2.1 复位Flash芯片 小节里,我们知道如果 efuse 里 RESET# 相关 bit 被烧写使能后,RT1064 BootROM 才会初始化 GPIO_SPI_B0_13 引脚为 GPIO 输出模式,并且拉低拉高一次来复位 Flash,等复位结束 GPIO_SPI_B0_13 会保持高电平输出。
// RT1064 上 RESET# 相关的 fuse
fuse 0x6e0[7] - FLEXSPI_RESET_PIN_EN
0 - Disable
1 - Enable
fuse 0x6e0[31] - FLEXSPI_RESET_PIN_SEL
0 - GPIO_SPI_B0_00
1 - GPIO_SPI_B0_13
但是默认情况下,RT1064 芯片出厂以及客户都不会去烧写跟这个 RESET# 相关的 efuse,这意味着 GPIO_SPI_B0_13 内部引脚会一直保持上电默认状态,那么默认是什么状态呢?这从 IOMUXC_SW_PAD_CTL_PAD_GPIO_SPI_B0_13 寄存器默认值 0x10B0 可以得知其为输入 Keeper 状态。
我们知道 RESET# 信号对 Flash 来说也是输入(从 Winbond 技术人员处得知,该信号内部有 280K 欧姆上拉),两个引脚相连,各自都是输入状态,显然有点不太可靠。说一种极端情况,芯片上电过程中,在 Flash 端弱上拉对 RESET# 作用让电压爬升到有效高电平 VCC x 0.7 之前,RT1060 的 GPIO_SPI_B0_13 端输入 Keeper 状态先产生作用,这时就会产生一个弱下拉,由于不同芯片的器件特性差异,这里的弱上拉/下拉都存在一定的误差范围,最终极有可能导致 RESET# 电平处于中间不定态。此外哪怕芯片上电过程中没问题,实际运行中,由于片内温度电磁环境等各方面因素,导致 RESET# 信号发生翻转,对 XIP 程序运行稳定性也是毁灭性打击。
三、解决RESET#信号稳定性的方案
为了验证 GPIO_SPI_B0_13 信号状态对于 RT1064 影响,痞子衡在测试 SFDP 工程里加上了这个信号的控制,当 GPIO_SPI_B0_13 输出为低时,即 Flash RESET# 处于有效状态,此时 Flash SFDP 都不能正常读出,更别提内存数据读取操作了。
那么该如何解决这个问题呢?上述原理知道后,其实方法就特别简单了:
- 解决启动问题:烧写 fuse 0x6e0[31,7] 两个位,让 BootROM 去初始化 GPIO_SPI_B0_13 引脚。(大约增加 750us 启动时间)
- 解决跑飞问题:假如芯片没有启动问题,但你不想额外烧写 fuse,那么 XIP App 运行起来后第一件事就是初始化 GPIO_SPI_B0_13 为 GPIO 输出模式,并且设为高电平。(为了可靠性,这部分代码可以 RAMFUNC 运行)
至此,不处理i.MXRT1064片内Flash的RESET#引脚可能会导致无法启动或程序跑飞痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园、CSDN、微信公众号、知乎、与非网、电子技术应用AET、电子星球、51CTO 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。