zoukankan      html  css  js  c++  java
  • 痞子衡嵌入式:串行NOR Flash的Continuous read模式下软复位后i.MXRT无法启动问题解决方案之SW Reset


      大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT上使能NOR Flash的Continuous read模式在软复位后无法正常启动问题的解决经验

      先回顾上篇 《串行NOR Flash的Continuous read模式下软复位后i.MXRT无法启动问题解决方案之RESET#》,利用RESET#引脚复位功能是痞子衡找到的第一种解决方案,今天痞子衡继续给大家介绍第二种解决方案。

    • 本系列会有多篇文章,每篇文章均从一个核心切入点出发,给出一系列具体实现方案。
    • 本系列均以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的软件复位时序有两种:一种是JEDEC标准规定的(严格来说其实算硬件复位,但因为其需CS#,SCK,IO0三根信号线配合完成,因此痞子衡将其归为软件复位时序类);另一种是厂商定义的软件复位命令(因为SOIC-8封装的Flash没有独立RESET#引脚,因此厂商增加这个软复位命令来代替缺失的独立RESET#引脚功能)。

    2.1 JEDEC标准复位时序

      JEDEC协会规定了一种Flash复位时序,需要CS#,SCK,IO0三根信号线配合完成,时序如下,保持SCK电平不变(高/低均可),拉四次CS#信号,通过SI信号线输出4'b0101(在CS#上升沿采样),则Flash会进入复位状态。

      JEDEC标准复位功能并不是所有Flash都集成的,华邦、芯成主流Flash型号均不支持JEDEC标准复位,痞子衡知道的Adesto ATXP032系列Flash里有JEDEC标准复位。

      ATXP032数据手册里关于JEDEC标准复位相关时序要求如下,进入JEDEC复位后需要 tXUDPD 时间来恢复。

    2.2 软件复位命令时序

      Flash数据手册命令集里通常都可以找到reset相关命令。在IS25WP128数据手册里我们可以找到如下软复位时序,它由0x66(RSTEN)和0x99(RST)命令组合完成,主芯片发完该命令组合后,Flash即进入复位状态。

      IS25WP128软件复位最大需要100us的恢复时间,在恢复期间内对Flash进行读写擦操作并不会生效。

    三、具体实现

      本章节描述的方法,如果是在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.MXRT1060系列ROM中串行NOR Flash启动初始化流程优化点》 里的2.3节。部分i.MXRT型号ROM里在串行NOR Flash启动流程里集成了JEDEC标准复位。

      如果要利用ROM里集成的JEDEC标准复位功能,则Flash本身必须支持JEDEC标准复位。本系列示例主芯片i.MXRT1170的fusemap表里关于JEDEC_RESET的相关定义如下,所以我们需要将fuse 0xC80[6]位烧写为1。

    3.2 仅App方面做相关处理

      上一小节里的方法先决条件是Flash要支持JEDEC标准复位,但实际客户项目中选型的Flash往往没有集成JEDEC标准复位。所以我们更多应该在厂商定义的软复位命令上做文章,这就要从App方面的角度来解决问题了。

      IS25WP128数据手册里找到如下两个关于reset的命令,reset_flash_to_normal() 函数里只需要按序发送这两个命令,并且延时等够软复位恢复时间即可。

      代码可以基于 SDK_2.9.1_MIMXRT1170-EVKoardsevkmimxrt1170driver_examplesflexspi orpolling_transfercm7下面的 flexspi_nor_polling_transfer.c 和 flexspi_nor_flash_ops.c,并新增如下代码:

    #define NOR_CMD_LUT_SEQ_IDX_RESETENABLE 14
    #define NOR_CMD_LUT_SEQ_IDX_RESET       15
    
    #define CUSTOM_LUT_LENGTH 64
    const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
        // ...
    
        /* 新增 Reset Enable */
        [4 * NOR_CMD_LUT_SEQ_IDX_RESETENABLE] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x66, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
    
        /* 新增 Reset */
        [4 * NOR_CMD_LUT_SEQ_IDX_RESET] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x99, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
    };
    
    status_t flexspi_nor_software_reset(FLEXSPI_Type *base)
    {
        flexspi_transfer_t flashXfer;
        status_t status;
    
        /* Write enable */
        flashXfer.deviceAddress = 0;
        flashXfer.port          = kFLEXSPI_PortA1;
        flashXfer.cmdType       = kFLEXSPI_Command;
        flashXfer.SeqNumber     = 1;
        flashXfer.seqIndex      = NOR_CMD_LUT_SEQ_IDX_RESETENABLE;
    
        status = FLEXSPI_TransferBlocking(base, &flashXfer);
        if (status != kStatus_Success)
        {
            return status;
        }
    
        flashXfer.seqIndex      = NOR_CMD_LUT_SEQ_IDX_RESET;
    
        status = FLEXSPI_TransferBlocking(base, &flashXfer);
    
        return status;
    }
    
    void reset_flash_to_normal(void)
    {
        __disable_irq();
    
        flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
        
        flexspi_nor_software_reset(EXAMPLE_FLEXSPI);
    
        // 这里需要插入足够的延时
        SDK_DelayAtLeastUs(100, SystemCoreClock);
        
        NVIC_SystemReset();
    }
    

      为了保证上述代码均执行在RAM里,工程链接文件里(以IAR示例)需做如下改动:

    initialize by copy { readwrite, 
                         section .textrw, 
                         object fsl_common.o,
                         object I64DivZer.o,
                         object I64DivMod.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主页知乎主页微信公众号 平台上。

    微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

      最后欢迎关注痞子衡个人微信公众号【痞子衡嵌入式】,一个专注嵌入式技术的公众号,跟着痞子衡一起玩转嵌入式。

    痞子衡嵌入式-微信二维码 痞子衡嵌入式-微信收款二维码 痞子衡嵌入式-支付宝收款二维码

      衡杰(痞子衡),目前就职于恩智浦MCU系统部门,担任嵌入式系统应用工程师。

      专栏内所有文章的转载请注明出处:http://www.cnblogs.com/henjay724/

      与痞子衡进一步交流或咨询业务合作请发邮件至 hengjie1989@foxmail.com

      可以关注痞子衡的Github主页 https://github.com/JayHeng,有很多好玩的嵌入式项目。

      关于专栏文章有任何疑问请直接在博客下面留言,痞子衡会及时回复免费(划重点)答疑。

      痞子衡邮箱已被私信挤爆,技术问题不推荐私信,坚持私信请先扫码付款(5元起步)再发。


  • 相关阅读:
    DotnetCore 使用Jwks验证JwtToken签名
    HashCode
    C# RedisRateLimiter
    Centos7 使用Dockerfile 制作自己的Dotnetcore程序镜像
    ES6 HttpApplication Middleware
    请转发!简单2分钟制作无接触式小区进出微信登记表!全免费!数据安全!所有数据均存在创建人登录的QQ腾讯文档里!
    理解虚基类、虚函数与纯虚函数的概念
    不无道理
    乔布斯:不要为明天忧虑!
    【心态不好,人生易老】
  • 原文地址:https://www.cnblogs.com/henjay724/p/14814681.html
Copyright © 2011-2022 走看看