大家好, 我是痞子衡, 是正经搞技术的痞子. 今天痞子衡给大家介绍的是恩智浦 i.MX RT1015/1020/1050 三款 MCU 的 FlexSPI NOR 启动的连接方式.
由于 i.MXRT 内部没有非易失性存储器, 因此在系统设计时为 i.MXRT 搭配一块存放应用程序代码的存储器是头等大事. i.MXRT 支持启动的外部存储器类型众多, 其中通过 FlexSPI 接口连接串行 NOR Flash 是首选.
就 i.MXRT 芯片引脚本身来说, 其 FlexSPI 模块支持的 Pinmux 选择较多, 这在芯片参考手册 Chip IO 一章可以找到具体信息. 但是并不是所有 FlexSPI Pinmux 组合都能被用来连接串行 NOR Flash 去启动.
i.MXRT1050/1020/1015 是 i.MXRT 系列 MCU 家族比较早亮相的型号, 也是客户当前使用较多的 i.MXRT 芯片. 它们三兄弟内部均只有一个双通道 8bit 的 FlexSPI 模块, 在 FlexSPI NOR 启动连接方式支持上是相似的. 今天痞子衡就来跟大家好好聊一聊到底哪些 FlexSPI NOR 连接方式是可以用作启动的.
一, 涉及 FlexSPI 引脚
提及启动, 就不得不提 i.MXRT 芯片内部 BootROM,BootROM 是固化在芯片内部 ROM 空间的一段代码, 芯片上电永远是 BootROM 先运行, 由 BootROM 从外部存储器去加载应用程序执行. 因此 FlexSPI NOR 连接方式其实是由 BootROM 决定的, 更直白点说, 其实 FlexSPI NOR 连接方式是写死在 BootROM 代码里.
我们可以在芯片参考手册 System Boot 这一章节找到 BootROM 指定的 FlexSPI NOR 引脚, 痞子衡整理如下:
下表适用于 i.MXRT105x:
下表适用于 i.MXRT102x 和 i.MXRT1015:
上面的表格基本上已经给我们指明了方向, 目前我们知道了哪些 Pin 可以用作 FlexSPI NOR 启动连接, 但是似乎还是有一些不清楚的地方:
疑问 1:1st Option 里一共有 4 根片选信号 (SSx) 和 2 根 DQS 信号, 而 Flash 只需要一个片选和一个 DQS, 是不是所有片选 + DQS 组合都可以?
疑问 2:1st Option 里一共 8 根数据线, 除了连接八线 Octal/Hyper Flash 之外, 是否可以单连四线 QSPI Flash?PortA 和 PortB 是不是都可以连 QSPI Flash?
疑问 3: 是否可以从 1st 和 2nd Option 里分别挑选信号线和数据线来连接 Flash? 比如 1st Option 里的 PortA_DATA[1:0]和 2nd Option 里的 PORTA_DATA[3:2]组成四线.
疑问 4: 那根 FlexSPI Reset 信号对于 1st 和 2nd Option 是不是都适用?
疑问 5: 是否可以挂两片 QSPI Flash 启动? 具体怎么挂? 两片 Flash 能否实现在一片 Flash 中执行代码去擦写另一片 Flash?
疑问 6:2nd Option 里只有 PortA 和一根片选, 但 RT1050 Pinmux 表里其也支持 PortB 和其他三根片选, 那些信号线后续是否可以利用?
在下面文章的内容里, 痞子衡会逐一为大家解析这些疑问:
二, 单 Flash 连接方式(3 种)
在系统设计时使用一片 Flash 是最常用的情况, 这片 Flash 负责存放应用程序代码(即所谓的 Code Flash),i.MXRT 既可以在 Flash 中原地执行, 也可以将应用程序拷贝到内部 RAM 中执行.
相信大家做板级设计一定会参考官方 EVK, 在 RT1050-EVKB 中, 官方给出了如下两种单 Flash 的连接方式, 这也是最推荐的两种方式:
第一种 Flash 连接方式就是利用 FlexSPI 1st Option 里的 6 根 PORTA 信号线连接四线 QSPI Flash, 此处需要注意的是片选信号仅能选 PORTA_SS0, 你可能会疑问 PORTA_SS1 明明也在 BootROM 支持列表里, 为何不能用? 关于这一点痞子衡会在后面双 Flash 连接里为大家解释.
第二种 Flash 连接方式就是利用 FlexSPI 1st Option 里的 7 根 PORTA 信号线和 5 根 PORTB 信号线连接八线 Octal/Hyper Flash, 此处仍需注意的是片选和 DQS 信号仅能选 PORTA_SS0,PORTA_DQS. 此种 Flash 接法还利用了 FlexSPI Reset 信号.
第三种 Flash 连接方式就是利用 FlexSPI 2nd Option 里的 6 根 PORTA 信号线连接四线 QSPI Flash, 具体接法跟第一种方式很像, 但是此处没有关于片选的疑虑, 因为 2nd Option 只有一个片选.
介绍完三种单 Flash 连接方案, 现在来解答一些前面列出的疑问.
解答 1:1st Option 里一共 4 根片选信号 (SSx) 和 2 根 DQS 信号并不是随意组合都可以, 无论是四线还是八线单 Flash 连接方案, 均只有 PORTA_SS0,PORTA_DQS 这一种组合可用. 其他组合主要用在双 Flash 连接方案中.
解答 2:1st Option 中仅 PORTA 可以单独接四线 QSPI Flash, 不支持 PORTB 单独接四线 QSPI Flash.
解答 3: 不支持从 1st 和 2nd Option 里分别挑选信号线和数据线来连接 Flash. 不过就 FlexSPI 模块本身而言, 理论上是支持的, 但这么用的话需要解决信号线等长问题, 因为这两个 Option 的走线长度在芯片内部不一样. 总之不推荐这么用.
解答 4:FlexSPI Reset 信号是与 1st,2nd Option 无关的, 所以两个 Option 下均可以用, 不过 Reset 信号常用于八线 Flash.
三, 双 Flash 连接方式(14 种)
很多实际系统设计中, 常常有既在 Flash 中存放用户应用程序, 也在 Flash 中存放用户数据的场景, 当然我们可以将一片 Flash 分成 Code 区和 Data 区来实现, 但更好的方案是选用两片 Flash(一片 Code Flash, 一片 Data Flash)同时挂在 FlexSPI 上, 这样可以避免数据误操作, 而且最重要的是在擦除或者编程 Data Flash 的等待期间(这个时间可不短),CPU 可以继续从 Code Flash 取代码执行或响应中断. 此处我们暂不讨论支持 RWW 特性的 Flash.
i.MXRT 支持挂两片 Flash 去启动, 此处仅以两片四线 QSPI Flash 为例. 下图给出了多片 Flash 的连接方式, 理论上一个 FlexSPI 最多可以挂四片 Flash, 因为最大有 4 个片选. 但仅考虑接两片 Flash 的话, 1st Option 以及 2nd Option 里一共 8 个片选, 按排列组合来说应该有 C(8,2) = 28 种组合方式, 但要考虑如下异常:
异常 1:1st A_SS0-2nd A_SS0,1st A_SS1-2nd A_SS1,1st B_SS0-2nd B_SS0,1st B_SS1-2nd B_SS1 互联这 4 种情况需排除
异常 2:1st A_SS0-2nd A_SS1,1st A_SS1-2nd A_SS0,1st B_SS0-2nd B_SS1,1st B_SS1-2nd B_SS0 连接这四种情况, DATA 线有两种选择, 所以要增加 4 种组合
考虑进上述异常情况后, 还是存在 28 种连接组合, 那么这 28 种组合是不是都可行呢? 当然不是! 要在这 28 种组合中剔除掉不包含 1st A_SS0 或者 2nd A_SS0 的组合. 即下图中标浅绿色的 Flash A0 在双 Flash 组合中是一定要存在的, 因为 BootROM 上电永远是从 Flash A0 中获取 FDCB 以及启动代码头(IVT, BootData), 所以 Flash A0 就是 Code Flash.
分析到了这里, 我们就知道如下符合条件的 14 种包含 Flash A0 的组合方式, 其中标记 Code 的片选信号应该连接存放应用程序代码的 Code Flash, 标记 Data 的片选信号则连接存放用户数据的 Data Flash:
Note: 有一个地方要注意, 如果两个 Flash 挂在同一类型 PORT 上(都是 PORTA 或都是 PORTB), 即下面的第 1,4,5,8,9,12 种组合时, 这两片 Flash 最好是同一个型号, 这样电气特性容易保持一致.
Num | FlexSPI 1st Option | FlexSPI 2nd Option | Comments | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
A_SS0 | A_SS1 | A_DATA[3:0] A_SCLK | B_SS0 | B_SS1 | B_DATA[3:0] B_SCLK | A_SS0 | A_SS1 | A_DATA[3:0] A_SCLK | B_SS0 | B_SS1 | B_DATA[3:0] B_SCLK | ||
1 | ✔ Code | ✔ Data | ✔ | BootROM 直接支持 < br ztid="134" ow="0" oh="0"> Data Flash 的配置 | |||||||||
2 | ✔ Code | ✔ | ✔ Data | ✔ | |||||||||
3 | ✔ Code | ✔ | ✔ Data | ✔ | |||||||||
4 | ✔ Data | ✔ Code | ✔ | ||||||||||
5 | ✔ Data | ✔ | ✔ Code | ✔ | |||||||||
6 | ✔ Data | ✔ | ✔ Code | ✔ | |||||||||
7 | ✔ Data | ✔ | ✔ Code | ✔ | |||||||||
8 | ✔ Code | ✔ | ✔ Data | 仅适用 RT1050 用户实现 Data Flash 配置 | |||||||||
9 | ✔ Code | ✔ | ✔ Data | ✔ | |||||||||
10 | ✔ Code | ✔ | ✔ Data | ✔ | |||||||||
11 | ✔ Code | ✔ | ✔ Data | ✔ | |||||||||
12 | ✔ Code | ✔ Data | ✔ | ||||||||||
13 | ✔ Code | ✔ | ✔ Data | ✔ | |||||||||
14 | ✔ Code | ✔ | ✔ Data | ✔ |
介绍完 14 种双 Flash 连接方案, 现在来解答一些前面列出的疑问.
解答 5: 可以挂两片 QSPI Flash 启动, 一共有 14 种连接方式. 两片 Flash 的方案还是不可以实现在 Code Flash 里原地执行代码去擦写 Data Flash 这种用法, 但可以实现 RWW 的核心意义, 下一节会单独展开讲这个.
解答 6: 不在 BootROM 指定的 2nd Option PortB 信号可以用于连接 Data Flash, 但是 Data Flash 的配置需要由 Code Flash 里的用户应用程序代码来完成, BootROM 无法直接配置 Data Flash.
四, 关于 RWW 的注意事项
现在市面上大部分 Flash(尤其是普通四线 QSPI)是不支持 RWW(Read-While-Write)特性的, 就是在单片 Flash 上无法实现同时读写. 但如果我们在 i.MXRT1015/1020/1050 系统设计中采用一片支持 RWW 特性的 Flash 或者直接使用两片 Flash, 是否可以实现在 Code Flash(或 RWW Flash 中的 Code 分区)中原地执行代码去擦写 Data Flash(或 RWW Flash 中的 Data 分区)这种需求. 答案其实还是不可以, 这是由 FlexSPI 模块本身特性限制的, 这个特性就是同一个 FlexSPI 模块下的 AHB command 和 IP command 是互斥的.
4.1 FlexSPI 异类命令互斥特性
下图是 FlexSPI 模块框图, 可以这么简单理解, CPU 去 Code Flash 取程序代码指令走的是 64bit AHB Bus(即 AHB command),Code Flash 里的程序代码里调用 FlexSPI 驱动去擦除或编程 Data Flash 走的是 32bit IPS Bus(即 IP command), 这两种不同类型的 command 会经过 ARB_CTL 模块去仲裁, 同一时间只有一种 command 胜出成为 ARB command 去实际操作 Flash.
那 FlexSPI 模块这个限制到底怎么破? 有以下三种方式可以来帮忙:
方法 1: 在 MPU 里设置 Code Flash 对应的映射地址区域, 使能 Cache, 并且保证应用程序代码里调用 FlexSPI 驱动去擦写 Data Flash 的关键部分 (触发 IP CMD 执行) 始终缓存在 Cache 里.
方法 2: 将应用程序代码里调用 FlexSPI 驱动去擦写 Data Flash 的关键部分搬运到 RAM 空间去运行, 可以直接借助 IDE 特性去完成(比如 IAR, 可以用__ramfunc 去修饰关键函数).
方法 3: 应用程序代码里的 FlexSPI 驱动直接使用 BootROM API(代码是在 ROM 空间运行的).
这三种方法里首推方法 3, 既能实现需求, 又能省 Code Flash 空间(FlexSPI 驱动代码说小不小). 方法 1 其实是不推荐的, 毕竟 Cache 是种玄学, 岂是你想控制就控制的.
4.2 RWW 的核心意义
最后再说一下, 挂两片 Flash(或一片 RWW Flash)到底相比挂一片非 RWW Flash 有什么好处? 这就涉及到 RWW 的核心意义了, 其实痞子衡前面已经讲过了, 虽然不能实现在 Code Flash 中原地执行擦写操作相关代码, 但是在 Data Flash 擦写等待期间, CPU 可以继续从 Code Flash 取代码执行, 这意味着此时不需要刻意关闭系统全局中断, 因此不影响系统响应的实时性.
至此, 恩智浦 i.MX RT1015/1020/1050 三款 MCU 的 FlexSPI NOR 启动的连接方式痞子衡便介绍完毕了, 掌声在哪里~~~
来源: https://www.cnblogs.com/henjay724/p/12375942.html