IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 痞子衡嵌入式:深扒i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合... -> 正文阅读

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


  大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是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 的 OctalFlash
    kRestoreSequence_Send_6699_9966 = 7, // 适用 MXIC 的 OctalFlash,如 MX25UM51345
    kRestoreSequence_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"
#endif

const 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主页知乎主页微信公众号 平台上。

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

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 10:57:40  更:2021-08-02 10:59:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:58:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码