大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是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#的更多相关文章

  1. 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的Continuous read模式

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的Continuous read模式. 前面关于串行Flash传输时序的文章 <Fast R ...

  2. 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的QPI/OPI模式

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的QPI/OPI模式. 我们知道 Flash 读时序里有五大子序列 CMD + ADDR + MO ...

  3. 痞子衡嵌入式:串行NOR Flash的页编程模式对于量产时间的影响

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是串行NOR Flash的页编程模式对于量产时间的影响. 任何嵌入式产品最终都绕不开量产效率话题,尤其是对于主控是非内置 Flash 型 ...

  4. 痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT上使用16MB以上NOR Flash软复位无法正常启动问题的分析解决经验. 痞子衡这几天在支持一个i.MXRT1050客户项 ...

  5. 痞子衡嵌入式:实抓Flash信号波形来看i.MXRT的FlexSPI外设下AHB读访问情形(无缓存)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是实抓Flash信号波形来看i.MXRT的FlexSPI外设下AHB读访问情形. 上一篇文章 <i.MXRT中FlexSPI外设对A ...

  6. 痞子衡嵌入式:JLink Script文件基础及其在IAR下调用方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是JLink Script文件基础及其在IAR下调用方法. JLink可以说是MCU开发者最熟悉的调试工具了,相比于其他调试器(比如DAP ...

  7. 痞子衡嵌入式:链接函数到8字节对齐地址或可进一步提升i.MXRT内核执行性能

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT上进一步提升代码执行性能的经验. 今天跟大家聊的这个话题还是跟痞子衡最近这段时间参与的一个基于i.MXRT1170的大项目有 ...

  8. 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(2) - 识别当前i.MXRT型号

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(2)之识别当前i.MXRT型号. 文接上篇 <超级下载算法(RT-UFL)开发笔记(1) - 执行在不同CM ...

  9. 痞子衡嵌入式:深扒i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合. 在串行 NOR Flash 热启动过程 ...

随机推荐

  1. 使用python的虚拟环境virtualenv

    技术背景 在前面几篇博客中我们介绍了容器的使用(博客1.博客2.博客3.博客4.博客5),容器是一种系统级的隔离方案,更多的强调资源上的隔离.而这里我们要介绍的python的虚拟环境,更加强调的是依赖 ...

  2. 七大php主流框架,你用过几个?

    在php中,我们最常用的框架有七个,分别是Yii2.Laravel.Yaf.Thinkphp.Code Igniter.Zend Framework以及CakePHP,今天我们就来详细介绍一下他们.一 ...

  3. PAT (Advanced Level) Practice 1006 Sign In and Sign Out (25 分) 凌宸1642

    PAT (Advanced Level) Practice 1006 Sign In and Sign Out (25 分) 凌宸1642 题目描述: At the beginning of ever ...

  4. php添加excel更新数据表数据

    公司有个需求,是用excel更新数据的,把错误的行列放到一个数组返回出来,正常的数据则插入,且返回数量 1.先需要引入phpspreadsheet,这里使用composer 安装 composer r ...

  5. (九)Docker-PS 详解

    1. 作用 查看 docker 容器 2. 基本语法 docker ps [OPTIONS] OPTIONS说明: -a :显示所有的容器,包括未运行的. -f :根据条件过滤显示的内容. --for ...

  6. 使用vue-element-admin框架从后端动态获取菜单

    1.前言 ​ vue-element-admin是一个纯前端的框架,左侧菜单是根据路由生成的.实际开发中经常需要根据当前登陆人员的信息从后端获取菜单进行展示,本文将详细介绍如何实现该功能. 2.详解 ...

  7. SpringMVC请求参数解析

    请求参数解析 客户端请求在handlerMapping中找到对应handler后,将会继续执行DispatchServlet的doPatch()方法. 首先是找到handler对应的适配器. Hand ...

  8. scrapy爬虫框架调用百度地图api数据存入数据库

    scrapy安装配置不在本文 提及, 1.在开始爬取之前,必须创建一个新的Scrapy项目.进入自定义的项目目录中,运行下列命令 scrapy startproject mySpider 其中, my ...

  9. 5- MySQL数据库SELECT查询操作

    复习: 数据类型: 数值型:整数(int,tinyint,smallint,bigint,mediumint) 浮点型(float ,double,decimal) 字符型:char(固定长度) ,v ...

  10. 1.4.19- HTML标签之注释标签

    有的时候我们输入的代码,让你别人看,别人不知道你的思路,可能就看不懂,或者或一段时间自己就看不懂了,这个时候我们需要对代码进行注释,解释我们的代码什么意思: <!DOCTYPE html> ...