大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是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 型号在这个方面特性只会微调和增强。
为了让大家对 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主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。
痞子衡嵌入式:深扒i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合的更多相关文章
-
痞子衡嵌入式:了解i.MXRTxxx系列ROM中灵活的串行NOR Flash启动硬复位引脚选择
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRTxxx系列ROM中灵活的串行NOR Flash启动硬复位引脚选择. 关于 i.MXRT 系列 BootROM 中串行 NOR ...
-
痞子衡嵌入式:深入i.MXRT1050系列ROM中串行NOR Flash启动初始化流程
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是深入i.MXRT1050系列ROM中串行NOR Flash启动初始化流程. 从外部串行NOR Flash启动问题是i.MXRT系列开发最 ...
-
痞子衡嵌入式:了解i.MXRT1060系列ROM中串行NOR Flash启动初始化流程优化点
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1060系列ROM中串行NOR Flash启动初始化流程优化点. 前段时间痞子衡写了一篇 <深入i.MXRT1050系 ...
-
痞子衡嵌入式:了解i.MXRTxxx系列ROM API及其与i.MXRT1xxx系列的差异
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRTxxx系列ROM API设计细节. 痞子衡之前写过两篇文章 <利用i.MXRT1xxx系列ROM提供的FlexSPI ...
-
痞子衡嵌入式:简析i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道. ECC 是 "Error Correc ...
-
痞子衡嵌入式:利用i.MXRT1xxx系列ROM提供的FlexSPI driver API可轻松IAP
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT系列ROM中的FlexSPI驱动API实现IAP. 痞子衡的技术交流群里经常有群友提问: i.MXRT中的FlexSPI驱动 ...
-
痞子衡嵌入式:串行NOR Flash的DQS信号功能简介
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是串行NOR Flash的DQS信号功能. 串行NOR Flash在嵌入式里的应用相当广泛,既可用作数据存储也可以用作代码(XiP)存储, ...
-
痞子衡嵌入式:原来i.MXRT1xxx系列里也暗藏了Product ID寄存器
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1xxx系列里暗藏的Product ID寄存器. MCU 厂商在定义一个产品系列时,通常是会预先规划产品发展路线的(即会有一 ...
-
痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(1)- KBOOT架构
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT架构. Bootloader是嵌入式MCU开发里很常见的一种专用的应用程序,在一个没有Boo ...
随机推荐
-
Linux 操作mysql数据库 创建库 导入、删除表
确保线上的运行数据库是不可避免的本人小白,因公司上线没有办法自己去整服务器,深刻体会到服务器大神的霸气,所以为了增加记忆,服务广大员友记录一下 linux mysql 忘记root的密码无法登陆进my ...
-
C#_技巧:真伪随机数
使用 Random 产生随机数.(这是一种伪随机数,需要seed,同一个seed后,采用某种算法产生的数字序列都是一样的) 两种写法 错误 for(int i=0;i<100;i++) { ...
-
4.羽翼sqlmap学习笔记之Post登录框注入
4.Sqlmap系列教程——post登录框注入注入点: http://xxx.xxx.com/Login.asp 注入方式一: 1.对着注入点使用burp抓包,保存txt格式文件. 2.输入命令: . ...
-
GC 基础
= GC 基础 ===================== JAVA堆的描述如下: 内存由 Perm 和 Heap 组成. 其中 Heap = {Old + NEW = { Eden , from, ...
-
Skia
1 What is SKIA. Skia is an open source 2D graphics library which provides common APIs that work acro ...
-
HtmlAgilityPack --解析Html源码
最近项目需要从网络上抓取一下数据解析Html源码,奈何正则表达式难写,于是网上搜索找到了“ HtmlAgilityPack”类库,敏捷开发,果然效率非同寻常. 在此做笔记,写下心得,顺便给自己总结一下 ...
-
UVA - 10057 A mid-summer night&;#39;s dream.
偶数时,中位数之间的数都是能够的(包含中位数) 奇数时,一定是中位数 推导请找初中老师 #include<iostream> #include<cstdio> #include ...
-
阿里云有对手了!CDN横评:腾讯云优势明显
如今,云计算产品越来越多,像国内的BAT三大巨头都提供了云主机(腾讯云CVM.阿里云ECS.百度云BCC),另外还有存储.数据库.安全等相关云服务.在这其中,CDN也是一项重要的云服务,CDN指的是内 ...
-
less用法小结
1,采用koala进行编译,可以实时地在vscode这样的工具中看到less到css的转换: 2,均支持/**/以及//两种形式的注释,由于后期维护是维护less,因此推荐使用后者,因为后者不会被编译 ...
-
python之旅七【第七篇】面向对象之类成员
面向对象的类成员 相关知识点 一 字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Provinc ...