大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦i.MXRT官方SDK里关于串行Flash相关的驱动与例程资源。
经常有同事以及 i.MXRT 客户咨询痞子衡,咱们恩智浦官方 SDK 里有哪些串行 Flash 相关的示例,每一次痞子衡都是按照询问需求将 SDK 里相应资源路径发给对方。看来那句俗话说得也不尽然对,酒香也怕巷子深,今天痞子衡就给大家全面梳理一下 SDK 里和串行 Flash 相关的全部资源。
- Note 1: 本文内容主要以 SDK_2_15_100_EVKB-IMXRT1050 软件包里的资源为例
- Note 2: 本文共分为上下两篇,本篇是上篇,主要介绍 drivers 和 components
一、Flash相关驱动概览
首先直接开门见山,痞子衡把 SDK 里和 Flash 有关系的驱动全部罗列如下,分布在 device driver、components、middleware、azure-rtos 里。 这四个目录下的驱动关系简单概括如下:
二、Flash驱动解释及例程
2.1 drivers
2.1.1 flexspi
fsl_flexspi 驱动是芯片外设 FlexSPI 的 HAL 级驱动,其是操作 FlexSPI 寄存器以实现 1-8bit SPI 类主设备方式数据收发,其 API 本身和 Flash 芯片操作并没有直接的联系,这从如下主要 API 原型可以看出来:
如下配套例程调用 fsl_flexspi 驱动里 API 实现了官方 RT1050-EVKB 板卡上的 hyperflash (S26KS512S) 和四线 nor flash (IS25WP064A) 的读写功能验证。
从 API 命名来看其实现了面向 Flash 的读写擦功能,但是 API 里的代码实现比较简洁,没有过度设计,对于不同厂商/类型的 Flash 支持,主要依赖用户定义的 LUT 表里的命令序列。
2.1.2 lpspi
fsl_lpspi 驱动是芯片外设 LPSPI 的 HAL 级驱动,其是操作 LPSPI 寄存器以实现 1bit(4bit) SPI 主/从设备方式数据收发,API 本身和 Flash 芯片也没有直接的联系。
该驱动的配套例程是单纯的 SPI 总线传输,并没有针对 Flash,这里就不展开了,但是它会在 components/flash 里被用到,后文会提及。
2.1.3 romapi
fsl_romapi 驱动是芯片固化 BootROM 所导出的通用 Flash API,在 BootROM 里集成了基于 FlexSPI 外设驱动而写成的通用 Flash 驱动,这个 Flash 驱动设计差不多是 components 级别,具体源代码原则上不可见,但其实我们可以在 middleware/mcu_bootloader 里大概知道。
既有面向 Flash 的写擦功能,也有偏 FlexSPI 外设 HAL 级别的接口。前者相比 flexspi 驱动配套的例程里对于 Flash 的支持就强大多了,用户完全可以仅靠 API 定义的简化参数来支持不同厂商/类型的 Flash;而后者存在的意义是为了让用户能够进一步设计面向 Flash 的功能函数。
总结一下,使用 fsl_romapi 例程相比 fsl_flexspi 例程去操作 Flash,好处是省代码空间且不需要考虑 Read-While-Write 限制(仅对驱动本身执行而言,无需代码重定向,但是全局中断问题仍要考虑),坏处是源代码是个黑盒子,出问题不容易定位。
2.2 components
2.2.1 mx25r_flash
mx25r_flash 组件其实是为 LPC54114 板卡上的旺宏宽电压四线 NOR Flash MX25R 系列而设计的,其在 \SDK_2_xxx_LPCXpresso54114\boards\lpcxpresso54114\driver_examples\spi\polling_flash 例程里有被调用,而在 i.MXRT 系列 SDK 里并没有相关例程使用它(不要疑问为啥会出现在软件包里,多就是好)。这个组件设计得挺有意思,其代码实现完全与芯片具体外设隔离,外设接口传输函数是通过 callback 形式传入的,充满了代码抽象(面向对象)的味道,有兴趣可以查看源码。
2.2.2 internal_flash
internal_flash 组件从名字上看像是为片内 Flash 而设计的,但是 i.MXRT 系列并无片内 Flash(RT1024/1064 只是 SIP 了串行 NOR Flash,本质上还是片外)。大家不要被这个名字骗了,这个组件最早确实是用于恩智浦 Kinetis/LPC 系列片内 Flash 的,但是在 i.MX RT 上因为配套 EVK 上有支持 XIP 的外置 NOR Flash,所以这个组件也沿用给这些外置 NOR Flash 了,因此其是基于 flexspi 驱动的组件。
在 \components\internal_flash\fsl_adapter_flash.h 文件里一共定义了 10 个 API 接口,其中如下 4 个是必须要实现的,其余 6 个可以不用实现(跟 Kinetis/LPC 片内 Flash 特性紧相关)。因为 RT1050-EVKB 默认连接的 hyperflash,所以该组件也仅为其做了相应实现 \components\internal_flash\hyper_flash。这个组件代码实现跟 flexspi 驱动配套例程里对于 Flash 的支持差不多。
internal_flash 组件设计的意义在于 SDK 其它例程中如果有 IAP 操作或者存储运行参数需求,均可以调用这个统一接口来实现,当然客户应用有相应需求,也一样可以使用。
2.2.3 flash
flash 组件里一共有三个: nor、nand、mflash,咱们一个个来说:
2.2.3.1 nor
先来介绍 nor 组件,从 \components\flash\nor\fsl_nor_flash 文件里的 API 命名来看,肯定是面向 NOR Flash 的读写擦功能,接口设计上对于底层外设采用了轻度抽象的方法,形参不涉及具体外设,但是函数实现里不同外设需要不同的实现,这也是为什么我们能看到 \nor\flexspi 和 \nor\lpspi 两个文件夹里的源代码。虽然底层外设不同,但是它们要操作的均是相同的串行 NOR Flash。
\nor\flexspi 里的代码实现跟 romapi 驱动实现方式有点像,其会从 Flash 里读取 SFDP 表进行解析从而自动获取所需操作命令,不依赖用户填充 LUT 命令。
\nor\lpspi 里的代码实现则比较简单,因为 LPSPI 外设本身主要支持 1bit SPI 传输,所以其也仅实现了一线方式对 Flash 进行读写擦,这部分命令是通用的,也无需用户填充 LUT。
2.2.3.2 nand
再来介绍 nand 组件,从 \components\flash\nand\fsl_nand_flash.h 文件里的 API 命名来看,肯定是面向 NAND Flash 的读写擦功能,接口设计上对于底层外设同样采用了轻度抽象的方法,形参不涉及具体外设,但是函数实现里不同外设需要不同的实现,这也是为什么我们能看到 \nand\flexspi 和 \nor\semc 两个文件夹里的源代码。不过 flexspi 外设和 semc 外设所支持的 NAND 不是一个产品,前者是串行 NAND,后者是并行 NAND,完全是两类不同的存储器标准。
\nand\flexspi 里的代码实现则比较简洁,因为串行 NAND 发展不如串行 NOR 那样丰富多样,所以其使用了固定 LUT 里的预设命令序列,基本能够支持华邦等主流四线串行 NAND 产品。
2.2.3.3 mflash
最后要重点介绍 mflash 组件,其分为 drv 层和 file 层两种不同类型的 API,drv 层提供基于芯片外设的底层 Flash 操作(详见 \mflash\mimxrt1052 文件夹下代码),file 层则是基于 drv 层里的 API 而设计的轻量级静态文件系统,简单理解就是将 Flash 虚拟成一个由具有固定最大长度的预定义命名文件集组成的存储空间,我们可以将小数据以文件名索引的方式写入 Flash,适用于需要存储运行参数或者设备配置数据的场合。
mflash 组件会在 middleware 以及 rtos 里被广泛使用,这个痞子衡将会在下篇里再具体介绍。
至此,恩智浦i.MXRT官方SDK里关于串行Flash相关的驱动与例程资源痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。