文件头区:区内 Sector 起始地址放一个 Magic 值(4 字节),用于标识文件头。然后开始按序记录一份份文件数据在文件数据区里的位置信息(默认用 2byte 去记录一份文件数据的位置)。如果当前 Header Sector 存储满了,便换到下一个 Header Sector 继续记录。

2.3 API 主参数

kFlashFile 设计上使用 kflash_file_t 型作为 API 主参数,这个参数原型定义如下:

managedStart:表示文件存储区映射首地址,即 kflash_file_init() 调用时的 memStart 值加上 Flash 在内存里映射首地址,managedStart 需要以 Flash Sector 大小对齐。

managedSize:表示文件存储区总大小,即 kflash_file_init() 调用时的 memSize 值,需要是 Flash Sector 大小的整数倍。

activedStart:表示当前有效文件数据存储的映射首地址,需要以 Flash Page 大小对齐。

activedSize:表示当前有效文件数据长度,需要是 Flash Page 大小的整数倍。

recordedIdx:表示当前有效文件头所在的 Header Sector 索引。

recordedPos:表示 Header Sector 中用于存储当前有效文件数据位置信息的区域偏移。

buffer[]:当前有效的文件数据暂存区。

三、实现

3.1 Driver 层

在 i.MXRT 系列上,kFlashFile 的 Driver 层即 FlexSPI NOR 驱动,这个驱动既可以采用 MCU SDK 版本,也可以采用 BootROM 版本。

此处推荐 BootROM 版本的 FlexSPI NOR 驱动,因为这个驱动历经多个 MCU ROM 的洗礼,已经相当成熟稳定。这里简单讲下其中 Flash 操作的函数:

因为 flexspi_nor_flash_page_program() 每次都要固定编程整个 Page 数据,不够灵活,因此我新写了一个 flexspi_nor_flash_program() 函数,这个函数支持编程用户自定义长度的数据,并且支持跨物理 Page 去写:

需要特别注意,对于 SDR 模式的 Flash,最小编程长度可以是 1Byte;而 DDR 模式的 Flash,最小编程长度应是 2Bytes(如果这 2Bytes 地址上有一个 Byte 内容是 0xFF,该 Byte 依旧可以被再次编程)。

此外 flexspi_nor_flash_program() 函数有一个限制,即传入的 src 源数据首地址必须 4 字节对齐,哪怕你只想写入 2 个字节,这是 FlexSPI 模块底层对驱动的要求。