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

  在串行 NOR Flash 热启动过程中(非首次上电复位,而是单纯系统软复位 NVIC_SystemReset),有很多场景下均需要先复位一下 Flash ,将其恢复到默认的 Normal 模式,然后 Flash 才能被i.MXRT BootROM 正常启动。

  《了解i.MXRTxxx系列ROM中灵活的串行NOR Flash启动硬复位引脚选择》 一文里介绍的硬复位 Flash 的方法适用包含独立 RESET# 引脚的 Flash,但很多 Flash 型号并不包含这个专用引脚(尤其是 SOIC-8 封装),有没有一种更通用的复位 Flash 方法呢?当然是有的,《串行NOR Flash的Continuous read模式下软复位后i.MXRT无法启动问题解决方案之SW Reset》 一文里介绍了一种利用 Flash 里普遍支持的 SW Reset 软复位命令的方法,并在用户应用程序里给出了示例代码。

  我们知道大部分早期 i.MXRT1xxx 型号 BootROM 里并没有集成 Flash SW Reset 功能,需要用户代码里去集成这个 Flash SW Reset 命令功能,这有点不方便,因此在更新的 i.MXRTxxx 系列型号 BootROM 里就集成了这个 Flash SW Reset 软复位功能。今天痞子衡就介绍下这个功能在 BootROM 里实现细节:

  • 备注1:本文主角是i.MXRT500/600,但内容也基本适用i.MXRT1160/1170。
  • 备注2:本文主要适用普通四线 QSPI NOR 或者八线 Octal Flash

一、BootROM中Flash SW Reset功能介绍

1.1 FlexSPI Boot初始化流程

  关于 i.MXRT 系列的串行 NOR Flash 启动初始化流程,痞子衡一共写过三篇文章,这些文章虽针对早期 i.MXRT1xxx 系列型号写的,但内容基本也适用 i.MXRTxxx 系列型号,后续更新的 i.MXRT 型号在这个方面特性只会微调和增强。

  1. 《深入i.MXRT1050系列ROM中串行NOR Flash启动初始化流程》
  2. 《了解i.MXRT1060系列ROM中串行NOR Flash启动初始化流程优化点》
  3. 《自识别特性(Auto Probe)可以让i.MXRT1060无需FDCB也能从NOR Flash启动》

  为了让大家对 i.MXRTxxx 系列串行 NOR Flash 启动初始化流程有明确概念,痞子衡重画了相应启动流程图,从流程上来看,其和 i.MXRT1060 最主要的差异就是三处步骤Y,这是最核心的改进点,也是本文主题。除此以外,还有一些微小差异(步骤7的位置调整)。

1.2 Flash SW Reset相关代码设计

  BootROM 中 Flash SW Reset 功能是通过 flexspi_nor_restore_spi_protocol() 函数实现的(关于它的原型可以在 i.MXRT1170 SDK\middleware\mcu-boot\src\drivers\flexspi_nor\flexspi_nor_flash.c 文件里找到),这个函数一共被调用两次,一次是在 Auto Probe 流程里(见 flexspi_nor_flash.c 文件里的 flexspi_nor_get_config() 函数实现,这个过程用户无需参与);另一次是在主流程里(见如下代码),主流程里的调用才是用户可以参与控制的:

// Flash 状态模式
enum
{kFlashInstMode_ExtendedSpi = 0x00,kFlashInstMode_0_4_4_SDR   = 0x01,kFlashInstMode_0_4_4_DDR   = 0x02,kFlashInstMode_QPI_SDR     = 0x41,kFlashInstMode_QPI_DDR     = 0x42,kFlashInstMode_OPI_SDR     = 0x81,kFlashInstMode_OPI_DDR     = 0x82,
};// 主要支持的三种软复位命令序列
enum
{kRestoreSequence_Send_66_99     = 6, // 适用大部分 QSPI Flash(如 IS25WP064A,GD25Q64,W25Q64)以及 Micron 的 OctalFlashkRestoreSequence_Send_6699_9966 = 7, // 适用 MXIC 的 OctalFlash,如 MX25UM51345kRestoreSequence_Send_06_FF     = 8, // 专用 Adesto EcoXIP
};typedef union {struct{uint8_t por_mode;             // 默认上电 Flash 状态模式uint8_t current_mode;         // 当前 Flash 状态模式uint8_t exit_no_cmd_sequence;uint8_t restore_sequence;     // 指定软复位命令序列} B;uint32_t U;
} flash_run_context_t;// 从指定的非易失性区域获取用户设置
flash_run_context_t flashRunCtx;
(void)flexspi_nor_read_persistent(&flashRunCtx.U);// 根据用户设置来做相应 Flash 软复位操作
(void)flexspi_nor_restore_spi_protocol(flexspiInstance, &flexspiNorConfig, &flashRunCtx);

  其中 flashRunCtx.B.restore_sequence 取值跟 Flash 型号有关, kRestoreSequence_Send_66_99 适用 QSPI NOR,比如华邦的 W25Q64(下图里 SW Reset 命令有 SPI 模式和 QPI 模式两种,但 BootROM 只用 QPI SDR 这种):

  kRestoreSequence_Send_66_99 也适用 Micron 的 OctalFlash,如 MT35X 系列(下图里 SW Reset 命令有 SPI 模式和 OPI 模式两种,但 BootROM 只用 OPI SDR 这种):

  kRestoreSequence_Send_6699_9966 适用旺宏的 Octal Flash,比如 MX25UM51345(下图里 SW Reset 命令有 SPI 模式和 OPI 模式两类,但 BootROM 只用 OPI 这类,不过 SDR/DTR 都支持):

1.3 存储SW Reset指示的非易失性通用寄存器

  上一节代码中的 flash_run_context_t 结构体变量 flashRunCtx 是用户程序跟 BootROM 沟通的关键,这个变量需要存在一个芯片系统软复位不清除的区域,BootROM 代码里选择了如下非易失性通用寄存器:

// i.MXRT500/600 里实现
status_t flexspi_nor_read_persistent(uint32_t *data)
{*data = *(volatile uint32_t *)(SYSCTL0_BASE + 0x380);return kStatus_Success;
}// i.MXRT1160/1170 里实现
status_t flexspi_nor_read_persistent(uint32_t *data)
{*data = SRC->GPR[2];return kStatus_Success;
}

1.4 将SW Reset请求传递给 BootROM 的两种方式

  用户有两种方式将 flashRunCtx 值传递给 BootROM,一是在应用程序代码里加入如下代码,主动将值写进指定的通用寄存器,这种方式比较灵活,flashRunCtx 设置可根据实际应用情况任意调整。

flash_run_context_t flashRunCtx = {.U = 0};
flashRunCtx.B.por_mode = kFlashInstMode_ExtendedSpi;
flashRunCtx.B.current_mode = kFlashInstMode_QPI_SDR;
flashRunCtx.B.restore_sequence = kRestoreSequence_Send_66_99;
// 针对 i.MXRT1160/1170
SRC->GPR[2] = flashRunCtx.U;
// 针对 i.MXRT500/600
*(volatile uint32_t *)(SYSCTL0_BASE + 0x380) = flashRunCtx.U;

  第二种方式是利用启动头 FDCB,在 flexspi_nor_config_t.flashStateCtx 里保存的就是 flashRunCtx,每一次 BootROM 启动都会将 FDCB 里的 flashStateCtx 写入指定的通用寄存器,这种方式相对来说不够灵活,适用明确的场景。

#if defined(BOOT_HEADER_ENABLE) && (BOOT_HEADER_ENABLE == 1)
#if defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".flash_conf"), used))
#elif defined(__ICCARM__)
#pragma location = ".flash_conf"
#endifconst flexspi_nor_config_t flash_config = {.memConfig ={.tag                 = FLEXSPI_CFG_BLK_TAG,// 其他省去不表},.pageSize      = 256u,.sectorSize    = 4u * 1024u,.blockSize     = 64u * 1024u,// 设置 flashRunCtx.flashStateCtx = 0x06004100u,  /*!< [0x1d4-0x1d7] */
};#endif /* BOOT_HEADER_ENABLE */

二、BootROM中Flash SW Reset功能应用

2.1 Flash进入QPI/OPI模式后系统复位

  Flash 的 SPI 模式和 QPI/OPI 模式常常是互斥的,同一时间仅能一种模式工作。Flash 上电默认是 SPI 模式,需要发送特殊的 QPIEN 命令或者配置一些内部寄存器才能进入 QPI 或者 OPI模式,一旦进了 QPI/OPI 模式,需要被复位回 SPI 模式才能被 BootROM 正常启动。

  比如在 MIMXRT595-EVK 板卡上,SDK 里 FDCB 启动头使能了默认板载 Octal Flash - MX25UM51435 的 OPI DDR 模式,所以我们需要在应用程序系统初始化里插入如下代码:

void SystemInit_flash(void)
{flash_run_context_t flashRunCtx = {.U = 0};flashRunCtx.B.por_mode = kFlashInstMode_ExtendedSpi;flashRunCtx.B.current_mode = kFlashInstMode_OPI_DDR;run_cflashRunCtxtx.B.restore_sequence = kRestoreSequence_Send_6699_9966;*(volatile uint32_t *)(SYSCTL0_BASE + 0x380) = flashRunCtx.U;
}/*
// 或 FDCB 增加如下设置
const flexspi_nor_config_t flash_config = {.flashStateCtx = 0x07008200u,  //!< [0x1d4-0x1d7] //
};
*/

2.2 Flash进入Continuous read模式后系统复位

  《串行NOR Flash的Continuous read模式下软复位后i.MXRT无法启动问题解决方案之SW Reset》 一文里的问题,可通过如下新方案实现(基于 MIMXRT1170-EVK 板卡):

void reset_flash_to_normal(void)
{__disable_irq();flash_run_context_t flashRunCtx = {.U = 0};flashRunCtx.B.por_mode = kFlashInstMode_ExtendedSpi;flashRunCtx.B.current_mode = kFlashInstMode_0_4_4_SDR;flashRunCtx.B.restore_sequence = kRestoreSequence_Send_66_99;SRC->GPR[2] = flashRunCtx.U;NVIC_SystemReset();
}/*
// 或 FDCB 增加如下设置
const flexspi_nor_config_t flash_config = {.flashStateCtx = 0x06000100u,  //!< [0x1d4-0x1d7] //
};
*/

2.3 Flash进入Deep Power Down模式后系统复位

  大部分 Flash 都支持进入 Deep Power Down 模式(通过 B9H 命令进入),这种模式适合一些对功耗要求敏感的设备,比如智能手表。在 Deep Power Down 模式下,Flash 不再响应读写擦命令,需要接受 Release Deep Power Down 命令(同时也是 Read Device ID命令)才能被再次唤醒正常工作,某些 QSPI NOR 以及 OctalFlash 下也支持 SW Reset 命令来唤醒退出低功耗模式,这时候也可以根据实际情况利用 BootROM 里集成的 SW Reset 功能。

  至此,i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。

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

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

  1. 痞子衡嵌入式:简析i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道. ECC 是 "Error Correc ...

  2. 痞子衡嵌入式:揭秘i.MXRTxxx系列上串行NOR Flash双程序可交替启动设计

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT500/600上串行NOR Flash双程序可交替启动设计. 在上一篇文章 <i.MXRT1170上串行NOR Fla ...

  3. 痞子衡嵌入式:利用i.MXRT1xxx系列ROM提供的FlexSPI driver API可轻松IAP

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT系列ROM中的FlexSPI驱动API实现IAP. 痞子衡的技术交流群里经常有群友提问: i.MXRT中的FlexSPI驱动 ...

  4. 痞子衡嵌入式:RT-MFB - 一种灵活的i.MXRT下多串行NOR Flash型号选择的量产方案

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是一种灵活的i.MXRT下多串行NOR Flash型号选择的量产方案. 对于以 i.MXRT 这类没有内部 NVM (Non-Volati ...

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

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

  6. 痞子衡嵌入式:对比恩智浦全系列MCU(包含Kinetis/LPC/i.MXRT/MCX)的GPIO电平中断设计差异...

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦全系列MCU(包含Kinetis, LPC, i.MXRT, MCX)的GPIO电平中断设计差异. 在痞子衡旧文 <以i.M ...

  7. 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(4) - 轮询Flash配置参数

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(4)之轮询Flash配置参数. 文接上篇 <超级下载算法(RT-UFL)开发笔记(3) - 统一FlexSP ...

  8. 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(1)- KBOOT架构

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT架构. Bootloader是嵌入式MCU开发里很常见的一种专用的应用程序,在一个没有Boo ...

  9. 痞子衡嵌入式:i.MXRT连接特殊Octal Flash时(OPI DTR模式下反转字节序)下载与启动注意事项(以MX25UM51245为例)...

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是OPI DTR模式下反转字节序的Octal Flash在i.MXRT下载与启动注意事项. 在恩智浦官方参考设计板 MIMXRT595-E ...

最新文章

  1. 2021年春季学期-信号与系统-第十三次作业参考答案-第二小题
  2. OpenSUSE 13.1 和 OpenSUSE 12.3 用户如何安装 Cinnamon 2.2 桌面
  3. 《敏捷迭代开发:管理者指南》—第2章2.14节推荐读物
  4. Java虚拟机知识汇总,有这些还怕面试被问到?
  5. mysql没加引号导致全表扫描_mysql隐蔽的索引规则导致数据全表扫描
  6. 你应该知道的Redis过期键和过期策略
  7. VS 自带DLL注册工具注册Dll
  8. DOS+DNS放大攻击工具编写
  9. 学习路之Linux--获取root权限
  10. 【设计模式】:单例设计模式深究
  11. Javaweb安全——JSP Webshell
  12. 家谱宗族网站源码_家谱管理系统(源代码)
  13. android棉花糖,清甜棉花糖:安卓M/Android 6.0上手体验评测
  14. linux cadaver 命令,备份Linux系统的数据到坚果云
  15. PHP快速入门(一)
  16. 代餐行业鱼龙混杂暴利驱动微商形成产业链
  17. 给大家推荐ScratchJr 少儿编程课程,感觉讲的还可以,内容比较清晰,而且前面还有幼儿音乐也比较好听
  18. Dockerfile最佳实践【原创、很多实践经验】
  19. 一文详解CAD与图新地球软件中提取高程点的方法图新地球
  20. Flutter项目快速搭建指南

热门文章

  1. php红包退回通知,PHP红包算法类(已运用实际项目)
  2. 学习 Java 的历程和体会『写给新手看,欢迎老司机批评和建议』
  3. Mysql中,order by + limt的大坑
  4. 刚刚!核电老将俞培根晋升东方电气集团董事长
  5. 机器学习笔记六——特征工程之数据预处理
  6. 正方体最快最简单画_正方体的画法步骤_正方体怎么画
  7. 外部数据的合规引入助力银行用户营销系统冷启动
  8. while(true) Thread.Sleep(XX)我通常是用这种写法,有没有更好的写法或者改进
  9. 人的判断力受制于他的知识和经验:明月当空叫,黄犬卧花心
  10. android版本低无法安装微信,解决低版本安卓4.4.4无法安装微信的问题