大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是导致串行NOR Flash在i.MXRT下无法正常下载/启动的常见因素之Write Protection。
i.MXRT系列MCU发布已两年多了,基于i.MXRT的客户产品也越来越多,可以说是全面开花了。痞子衡作为i.MXRT产品线的系统应用工程师,早期的时候还可以尽情做参考设计,现在基本大量时间都被客户支持占据了。
因为i.MXRT系列都没有内置Flash(RT1064, RT1024等SIP型号除外),因此为其搭配一块串行NOR Flash去启动是客户项目的头等大事,而串行NOR Flash厂商非常多,客户选择余地很大,因此我们不得不与客户一起同茫茫Flash型号打交道,痞子衡也常常调侃自己已沦为Flash测试工程师。
痞子衡在支持客户解决串行NOR Flash下载启动问题过程中主要遇到几个常见因素,这几个因素可能会影响Flash在i.MXRT下无法正常使用,上两篇痞子衡分别讲了 《SFDP因素》 和 《QE bit因素》, 今天痞子衡重点跟大家聊聊Write Protection这个因素。
痞子衡最近遇到一个智能电表厂商客户,他们项目板卡选用的是主控i.MXRT1051 + 华邦W25Q64JVSSIQ,应用程序是MBED bootloader + User App二级加载设计,其中MBED bootloader是由Arm Pelion物联网小组主导设计的,User App是这个电表厂商自己的功能代码。
客户的问题是烧写了一个特定版本的MBED bootloader运行之后,板卡Flash无法再次做烧写了,但是板子是能够正常从Flash启动的。客户之后尝试使用了各种下载工具都不管用(J-Flash/IDE/NXP Tool等),其中下载工具包括痞子衡设计的一站式下载工具 MCUBootUtility ,于是问题就转到了痞子衡这里(好像有点躺枪的感觉)。工具后台报的错是擦除或者写入时会返回 kStatus_FlexSPINOR_CommandFailure,导致无法下载。

既然问题和特定版本的MBED bootloader有关,那看起来就是这个bootloader引入的问题,但是痞子衡拿不到客户MBED bootloader源码,无法做白盒分析。鉴于痞子衡这么多年和Flash打交道的经验,痞子衡盲猜是bootloader使能了Flash的软件写保护功能(Software Write Protection)导致的问题,于是痞子衡让客户寄来了一块板卡,实测来证实痞子衡的猜想。
查看W25Q64JVSSIQ数据手册得知,软件写保护功能的配置集成在Flash器件内部非易失性Status Register中,这款Flash一共有3个8bit的Status Register(状态寄存器均支持易失性写入(即断电恢复)和非易失性写入(即断电保持),由前导的Write Enable命令类型0x06/0x50决定),并且每个Status Register都有不同的读写命令:
现在我们简单修改了下SDK里的如下flexspi nor例程(选择ram build),增加上述三个Status Register读取功能的支持,从而实测读取Status Register来做验证。
\SDK_2.9.1_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\flexspi\nor\polling_transfer
首先是在 app.h 和 flexspi_nor_polling_transfer.c 中将Status Register的读取命令加入到LUT表中。原来工程里已经有Status Register 1的读取支持,所以我们仅需增加Status Register 2/3的支持即可。因为这新增的两条命令,需要将CUSTOM_LUT_LENGTH由60改到64(i.MXRT1051上最大64,即支持16条LUT Sequence)。
然后在 flexspi_nor_flash_ops.c 中新增如下 flexspi_nor_get_status_register() 函数,这个函数直接仿照 flexspi_nor_get_vendor_id() 函数流程写即可,Flash端时序是一样的。
最后就是在 flexspi_nor_polling_transfer.c 中的 main() 函数里增加 flexspi_nor_get_status_register() 函数调用语句,将Status Register 1/2/3的值全部读取出来。
将上一节修改后的 flexspi nor 例程下载进RAM调试运行,可以读出Status Register 1/2/3的值分别为0x40、0x42、0x60,看起来Status Register确实被MBED bootloader修改过。痞子衡标出了W25Q64JVSSIQ内部状态寄存器中所有与写保护相关的bit位如下,我们需要对照Flash数据手册具体查看读出来的值对应了什么样的写保护设置:
首先Status Register1[SRP],Status Register2[SRL]以及外部WP#引脚共同决定Status Register设置条件,本例中SRL和SRP均为0,则WP#引脚控制不生效,Status Register可以直接被设置。
Status Register中其他写保护相关的bit位解释如下,其中WPS是核心设置,它决定了写保护是用单独的Block lock命令来控制(见Flash命令集)还是直接由Status Register1/2中的CMP,TB,SEC,BPx位来决定。
综合上面分析,最后我们发现MBED bootloader将全部的8MB Flash空间都保护起来了,所以各种下载工具都无法正常烧写这款Flash了。
要想重新使能Flash烧写,需要一个单独的嵌入式小工程将Status Register1/2/3值再改回到默认状态(WPS=0, CMP=0),可按照第2节里读SR功能修改步骤,代码如下。代码工程修改完成后借助调试器下载到RAM运行一次即可,需要注意应在芯片SDP模式下运行,运行结束后,立刻借助其他下载工具将Flash里旧固件更新掉,保证这个过程中不存在软复位而导致旧固件被再次运行的可能。(此处是将Flash里的MBED bootloader换掉,因为是它在使能Flash的写保护功能)
这里仅以华邦Flash为例介绍Write Protection,其他厂商Flash对于这个Write Protection特性设计也许有所不同,需要查看数据手册具体分析。此外鉴于Flash这种种因素会导致在i.MXRT无法下载或正常启动,痞子衡之前计划做的全新上位机工具MCUTestSuite,会考虑将串行NOR Flash状态信息查询功能(SFDP/QE bit/Write Protection等)也放进去,敬请关注这个新项目:
MCUTestSuite工具项目:https://github.com/JayHeng/NXP-MCUTestSuite
至此,导致串行NOR Flash在i.MXRT下无法正常下载/启动的常见因素之Write Protection痞子衡便介绍完毕了,掌声在哪里~~~
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。
最后欢迎关注痞子衡个人微信公众号【痞子衡嵌入式】,一个专注嵌入式技术的公众号,跟着痞子衡一起玩转嵌入式。
衡杰(痞子衡),目前就职于恩智浦MCU系统部门,担任嵌入式系统应用工程师。
专栏内所有文章的转载请注明出处:http://www.cnblogs.com/henjay724/
与痞子衡进一步交流或咨询业务合作请发邮件至 [email protected]
可以关注痞子衡的Github主页 https://github.com/JayHeng,有很多好玩的嵌入式项目。
关于专栏文章有任何疑问请直接在博客下面留言,痞子衡会及时回复免费(划重点)答疑。
痞子衡邮箱已被私信挤爆,技术问题不推荐私信,坚持私信请先扫码付款(5元起步)再发。