痞子衡嵌入式:串行NOR Flash的Continuous read模式下软复位后i.MXRT无法启动问题解决方案之RESET#
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT上使能NOR Flash的Continuous read模式在软复位后无法正常启动问题的解决经验。
前一篇文章 《在i.MXRT启动头FDCB里使能串行NOR Flash的Continuous read模式》 里,痞子衡简单介绍了Flash的Continuous read模式作用与意义,并且在MIMXRT1170-EVK上尝试使能了芯成IS25WP128的Continuous read模式做了一次实践(主要是文中第三节FDCB启动头的改动)。
但其实在i.MXRT上使能Flash的Continuous read模式是有点小陷阱的,如果你在App代码里直接插一句 NVIC_SystemReset() 函数的调用,即对主控芯片做一次软复位,你会发现芯片没有从Flash正常启动,这是因为Flash此时仍处于Continuous read模式,这种情况下BootROM有时不能正常配置读取Flash内容去启动App。今天痞子衡就来跟大家探讨解决这个问题。
- 本系列会有多篇文章,每篇文章均从一个核心切入点出发,给出一系列具体实现方案。
- 本系列均以MIMXRT1170-EVK板为示例目标对象,板载Flash型号为芯成IS25WP128(其他i.MXRT芯片和Flash型号下实现流程也差不多,需查看对应数据手册)。
一、解决思路
我们知道无法启动问题是由于主芯片发生软复位但Flash仍处于Continuous read模式造成的,要解决这个问题无非如下三个角度,痞子衡会在后面具体实现方案里按这些角度全部搞一次(如果适用的话)。
- 一、ROM方面不做任何相关处理,但App在调用NVIC_SystemReset()做复位前将Flash先切回到Normal模式;
- 二、App方面不做任何相关处理,对BootROM相关配置做一些调整,让BootROM也能正常处理处于Continuous read模式的Flash;
- 三、ROM和App联合对Flash模式切换做一些特殊处理。
二、核心切入点(借助Flash的硬复位引脚功能)
本文找的核心切入点是利用Flash的硬件复位引脚。Flash的硬件复位引脚有两种:一种是独立的,常见于SOIC-16封装上(这种情况下对板级设计有要求,需要在板级设计时将Flash复位引脚连到主芯片i.MXRT的GPIO上);另一种是复用在IO3上的,常用于SOIC-8封装上。
如果是独立的复位引脚(RESET#),则主芯片GPIO直接做拉低操作即可(注意低电平持续时间的要求,详见Flash数据手册);如果是复用的复位引脚(RESET#/IO3),则需要先激活IO3的复位功能,然后做拉低操作。
在IS25WP128数据手册里可以找到RESET#信号低电平至少需要持续1us:
三、具体实现
本章节描述的方法,如果是在App里(这里均指XIP App)完成,那么App里增加的相关处理代码(注意是执行到的全部代码)需要是 ramfunc 属性(即运行在内部RAM里),这样操作Flash时可以不受限制。此外代码运行前需要把全局中断关掉,防止执行过程中有中断触发,导致Flash里的相关IRQHandler函数被执行。
#if (defined(__ICCARM__))
__ramfunc
#endif
void reset_flash_to_normal(void)
{
__disable_irq();
// 处理代码,使Flash返回到Normal模式
NVIC_SystemReset();
}
3.1 仅ROM方面做相关处理
我们先仅从ROM单方面角度来解决问题,可以先看下痞子衡之前的旧文 《深入i.MXRT1050系列ROM中串行NOR Flash启动初始化流程》 里的2.1节。i.MXRT全系列ROM里关于串行NOR Flash启动流程大同小异。
如果要利用ROM里集成的Flash硬件复位功能,则Flash本身必须包含独立的硬件RESET#引脚。本系列示例主芯片i.MXRT1170的fusemap表里关于RESET_PIN的相关定义如下,那么板级设计时Flash RESET#引脚应该连接到GPIO4[3]或者GPIO2[8](根据fuse 0xC80[5]位而定),并且我们还要将fuse 0xC80[7]位烧写为1。
3.2 仅App方面做相关处理
上一小节里的方法先决条件是Flash要包含独立RESET#引脚,但实际客户项目中SOIC-8封装的Flash选择更多。所以我们更多应该在复用的RESET#/IO3引脚上做文章,这就要从App方面的角度来解决问题了。
我们先从IS25WP128数据手册看看RESET#/IO3引脚详细功能解释,主要如下两点:
1. IO3引脚仅当QE模式不使能(Flash内部Status Register[6] = 0)的时候,其功能才是HOLD#/RESET#
2. IO3引脚复用功能HOLD#/RESET#由Flash内部Read Register[7]位决定,默认值为0,是HOLD#功能
所以 reset_flash_to_normal() 函数里我们需要先设Status Register将Flash切到QE不使能的状态(i.MXRT启动运行App时,Flash应处于QE使能的状态),然后再设Read Register将IO3复位功能指定为RESET#,然后拉低IO3对应的GPIO直到满足复位最小时间要求,最后再将之前改写的Status Register/Read Register全部恢复。过程中主要涉及如下命令:
代码可以基于 \SDK_2.9.1_MIMXRT1170-EVK\boards\evkmimxrt1170\driver_examples\flexspi\nor\polling_transfer\cm7下面的 flexspi_nor_polling_transfer.c 和 flexspi_nor_flash_ops.c,并新增如下代码:
#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 9
#define NOR_CMD_LUT_SEQ_IDX_SETREADPARAM 14
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
// ...
/* 原来 Write Status Register */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
// 新增 Set read parameter
[4 * NOR_CMD_LUT_SEQ_IDX_SETREADPARAM] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x63, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
};
status_t flexspi_nor_set_flash_register(FLEXSPI_Type *base, uint32_t seqIdx, uint32_t regValue)
{
flexspi_transfer_t flashXfer;
status_t status;
uint32_t writeValue = regValue;
/* Write enable */
status = flexspi_nor_write_enable(base, 0);
if (status != kStatus_Success)
{
return status;
}
flashXfer.deviceAddress = 0;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = seqIdx;
flashXfer.data = &writeValue;
flashXfer.dataSize = 1;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
return status;
}
// MIMXRT1170-EVK上GPIO10[20]引脚连到了Flash的IO3上
void reset_flash(void)
{
gpio_pin_config_t gpio_config = {
.direction = kGPIO_DigitalOutput,
.outputLogic = 0U,
.interruptMode = kGPIO_NoIntmode
};
GPIO_PinInit(GPIO10, 20U, &gpio_config);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_11_GPIO10_IO20, 0U);
// Pin拉高
GPIO_PinWrite(GPIO10, 20U, 1U);
SDK_DelayAtLeastUs(10, SystemCoreClock);
// Pin拉低10us
GPIO_PinWrite(GPIO10, 20U, 0U);
SDK_DelayAtLeastUs(10, SystemCoreClock);
// Pin拉高
GPIO_PinWrite(GPIO10, 20U, 1U);
}
void reset_flash_to_normal(void)
{
__disable_irq();
flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
// Disable quad mode.
flexspi_nor_set_flash_register(EXAMPLE_FLEXSPI, NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG, 0x00);
// Set IO3 pin to Reset func
flexspi_nor_set_flash_register(EXAMPLE_FLEXSPI, NOR_CMD_LUT_SEQ_IDX_SETREADPARAM, 0x80);
// Drive IO3 to low for at least 1us
reset_flash();
// Set back IO3 pin func
flexspi_nor_set_flash_register(EXAMPLE_FLEXSPI, NOR_CMD_LUT_SEQ_IDX_SETREADPARAM, 0x00);
// Enter quad mode.
flexspi_nor_set_flash_register(EXAMPLE_FLEXSPI, NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG, 0x40);
NVIC_SystemReset();
}
为了保证上述代码均执行在RAM里,工程链接文件里(以IAR示例)需做如下改动:
initialize by copy { readwrite,
section .textrw,
object fsl_common.o,
object I64DivZer.o,
object I64DivMod.o,
object fsl_gpio.o,
object fsl_flexspi.o,
object flexspi_nor_flash_ops.o,
object flexspi_nor_polling_transfer.o,
section CodeQuickAccess };
3.3 ROM和App联合处理
关于ROM和App联合处理角度,在复位引脚这个切入点上并没有什么优势,此处略去。
至此,i.MXRT上使能NOR Flash的Continuous read模式在软复位后无法正常启动问题的解决经验痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:串行NOR Flash的Continuous read模式下软复位后i.MXRT无法启动问题解决方案之RESET#的更多相关文章
- 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的Continuous read模式
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的Continuous read模式. 前面关于串行Flash传输时序的文章 <Fast R ...
- 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的QPI/OPI模式
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的QPI/OPI模式. 我们知道 Flash 读时序里有五大子序列 CMD + ADDR + MO ...
- 痞子衡嵌入式:串行NOR Flash的页编程模式对于量产时间的影响
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是串行NOR Flash的页编程模式对于量产时间的影响. 任何嵌入式产品最终都绕不开量产效率话题,尤其是对于主控是非内置 Flash 型 ...
- 痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT上使用16MB以上NOR Flash软复位无法正常启动问题的分析解决经验. 痞子衡这几天在支持一个i.MXRT1050客户项 ...
- 痞子衡嵌入式:实抓Flash信号波形来看i.MXRT的FlexSPI外设下AHB读访问情形(无缓存)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是实抓Flash信号波形来看i.MXRT的FlexSPI外设下AHB读访问情形. 上一篇文章 <i.MXRT中FlexSPI外设对A ...
- 痞子衡嵌入式:JLink Script文件基础及其在IAR下调用方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是JLink Script文件基础及其在IAR下调用方法. JLink可以说是MCU开发者最熟悉的调试工具了,相比于其他调试器(比如DAP ...
- 痞子衡嵌入式:链接函数到8字节对齐地址或可进一步提升i.MXRT内核执行性能
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT上进一步提升代码执行性能的经验. 今天跟大家聊的这个话题还是跟痞子衡最近这段时间参与的一个基于i.MXRT1170的大项目有 ...
- 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(2) - 识别当前i.MXRT型号
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(2)之识别当前i.MXRT型号. 文接上篇 <超级下载算法(RT-UFL)开发笔记(1) - 执行在不同CM ...
- 痞子衡嵌入式:深扒i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合. 在串行 NOR Flash 热启动过程 ...
随机推荐
- java例题_43 求0—7所能组成的奇数个数
1 /*43 [程序 43 求奇数个数] 2 题目:求 0-7 所能组成的奇数个数. 3 */ 4 5 /*分析 6 * 1.0不能作最高位且最低位只能是1,3,5,7; 7 * 2.没有限定是几位数 ...
- Java例题_39 判断奇偶后分数累加
1 /*39 [程序 39 分数累加] 2 题目:编写一个函数,输入 n 为偶数时,调用函数求 1/2+1/4+...+1/n,当输入 n 为奇数时,调用函数 3 1/1+1/3+...+1/n 4 ...
- Java基础回顾_第一部分
Java基础回顾 基本数据类型 数值类型 什么是字节? 位(bit):是计算机中数据的最小单位 字节(byte):是计算机中数据处理的基本单位,习惯上用大写字母B来表示 1 B = 8 bit 字符: ...
- 懵了!女朋友突然问我MVCC实现原理
前言 都知道事务的可重复读级别实现原理是使用MVCC实现的,那么你对MVCC的底层实现原理知道多少呢?面试高频点,你值得拥有. 一.MVCC到底是什么? MVCC即多版本控制器,其特点就是在同一时间, ...
- 全网最详细的Linux命令系列-rm命令
今天学习一下linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除 ...
- 它来了,它来了,HarmonyOS应用开发在线体验来了
接下来是我们的两分钟科普,一分钟玩转HarmonyOS应用开发在线体验,一分钟简单了解"一次开发.多设备部署"的原理.萌新的开发者也能第一时间掌握,往下看吧~ 一分钟玩转Harmo ...
- PAT B1030/A1085 完美数列
给一个整数数列和正整数p,设这个数列中最大值M,最小值m,如果有M<=m*p,则称这个数列为完美数列,给一个p和一些正整数,从里面选择尽可能多的数,使他们构成一个完美数列,并输出最多可以选择的数 ...
- 它来了!!!有史以来第一个64位Visual Studio(2022)预览版将在今夏发布!
美国时间2021年4月19日,微软产品研发部一位负责人Amanda Silver在其博客上发布一则<Visual Studio 2022>的消息,表示将在今年(2021年)夏天发布Visu ...
- Go-08-函数与指针
Go语言的函数本身可以作为值进行传递,既支持匿名函数和闭包,又能满足接口. 函数声明 func 函数名 (参数列表)(返回参数列表){ // 函数体 } func funcName(parameter ...
- Ambassador-08-跨域
官方文档:https://www.getambassador.io/docs/latest/topics/using/cors/ Cross-Origin Resource Sharing-CORS ...