2020
07/01
12:01
你的位置:msn.com > 操作眉目 > 痞子衡嵌入式是哪门子:kFlashFile v1.0

痞子衡嵌入式是哪门子:kFlashFile v1.0

发布时间:2020-07-01 12:01:11

原文章标题大全:痞子衡嵌入式是哪门子:kFlashFile v1.0

痞子衡最近在参与一度依据 i.MXRT1170 的项目。项目有个需求,要求在 Flash 里实时保存一些关键数据(初步设 512 bytes),掉电能恢复。该署数据在作客方式上要友好,最好是很简单的 API 短信服务平台接口,上层无需操心关键该署数据在 Flash 里是如何存储以及具体存储在哪门子位置,只需在意关键数据保存和读取的操作即可(就像在 RAM 里动态存取那样)。

是规范搞技术的痞子。今天给大家带到的是痞子衡的个人小项目 - kFlashFile。

痞子衡最近在参与一度依据 i.MXRT1170 的项目,项目有个需求。要求在 Flash 里实时保存一些关键数据(初步设 512 bytes),掉电能恢复。该署数据在作客方式上要友好,最好是很简单的 API 短信服务平台接口,上层无需操心关键该署数据在 Flash 里是如何存储以及具体存储在哪门子位置,只需在意关键数据保存和读取的操作即可(就像在 RAM 里动态存取那样)。

根据如上需求,痞子衡做了一度参照设计,命名为 kFlashFile。当前是 v1.0 版本。痞子衡写了相形之下细大不捐的设计文档,专门分享给大家,如果大家有更好的今日白银操作建议和想法,欢迎在励志文章手底下留言。

项目地址大全:https://github.com/JayHeng/kFlashFile

kFlashFile

一,简介

kFlashFile 是一度依据 NOR Flash 的最轻量级广州钢制文件柜数据存储方案,用于要求断流数据保存的项目。

kFlashFile 重点为 i.MXRT 系列设计。但其分层框架设计使其也可轻松医道到其它 MCU 平台。

kFlashFile 学装修设计从何学起上分为三层:

  • 最底下是Driver层:即Low-level使得,这层是MCU呼吸相通的。对于i.MXRT以来,就是FlexSPI模块的使得。
  • 里边是Adapter层:重点用于适配底层Driver,莫衷一是MCU其Driver短信服务平台接口函数可能性莫衷一是,因此会在这一层做到短信服务平台接口汇合。
  • 最高层是API层:纯太平洋下载眉目设计来实现广州钢制文件柜数据存储,提供了四个非常简易小魔术的API。

images/loading.gif' data-original="http://henjay724.com/image/github/kFlashFile_Framework.PNG" loading="lazy">

二,设计

2.1 API定义

kFlashFile 是一度广州钢制文件柜数据存储的设计,file_read(),file_save()是两个必备的 API,另外也提供业界可用 API 短信服务平台接口file_init(),file_deinit()。

  • kflash_file_init(): 用于初次分派Flash空间来存储广州钢制文件柜数据,并且指名广州钢制文件柜长度。如果当前指名的Flash空间里留存有效广州钢制文件柜数据,那么延续复用。
  • kflash_file_read(): 用于得到当前有效存储的广州钢制文件柜数据,广州钢制文件柜数据可以部分读取。
  • kflash_file_save(): 用于实时写入最新的广州钢制文件柜数据,广州钢制文件柜数据可以部分更新。
  • kflash_file_deinit(): 用于清除当前分派的Flash空间里的广州钢制文件柜数据。以便下次再次分派。
status_t kflash_file_init(kflash_file_t *flashFile, uint32_t memStart, uint32_t memSize, uint32_t fileSize);status_t kflash_file_read(kflash_file_t *flashFile, uint32_t offset, uint8_t *data, uint32_t size);status_t kflash_file_save(kflash_file_t *flashFile, uint32_t offset, uint8_t *data, uint32_t size);status_t kflash_file_deinit(kflash_file_t *flashFile);

2.2 空间分派

kFlashFile 将分派的 Flash 空间分成两个部分,之前是广州钢制文件柜数据区(Data Sectors),后面是广州钢制文件柜头区(Header Sectors)。

广州钢制文件柜数据区:从区内起始地址大全开始按序存放一份份广州钢制文件柜数据,只要广州钢制文件柜数据出现无法覆盖的更新(即 Flash 无法反手的特性),便会不才一度新地址大全再次存储。如果数据区满了。便擦除区内起始地址大全处的历史广州钢制文件柜数据。延续循环存储。

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

2.3 API主参数

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

typedef struct { uint32_t managedStart; uint32_t managedSize; uint32_t activedStart; uint32_t activedSize; uint32_t recordedIdx; uint32_t recordedPos; uint8_t buffer[KFLASH_MAX_FILE_SIZE];} kflash_file_t;
  • managedStart: 表示广州钢制文件柜存储区辉映首地址大全,即 kflash_file_init() 调用时的 memStart 值加上 Flash 在内存里辉映首地址大全。managedStart 要求以 Flash Sector a4纸大小对齐。
  • managedSize: 表示广州钢制文件柜存储区总a4纸大小,即 kflash_file_init() 调用时的 memSize 值,要求是 Flash Sector a4纸大小的整数包括分数吗倍。
  • activedStart: 表示当前有效广州钢制文件柜数据存储的辉映首地址大全,要求以 Flash Page a4纸大小对齐。
  • activedSize: 表示当前有效广州钢制文件柜数据长度,要求是 Flash Page a4纸大小的整数包括分数吗倍。
  • 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_erase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length):这个函数实现Flash擦除。虽然数组作为形参里是任意设定的start, address,但实际擦除还无乃Sector对齐的,函数内中会对start和address做自行对齐。
  • flexspi_nor_flash_page_program(uint32_t instance, flexspi_nor_config_t *config, uint32_t dstAddr, const uint32_t *src):这个函数实现Flash编程。一次固定写一整个Pagea4纸大小的数据,即使dstAddr不无乃Page对齐,实际写入的Page数据也决不会跨情理Page(会自行跳回同一度情理Page首地址大全,这是Flash自身特性)。

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

  • flexspi_nor_flash_program(uint32_t instance, flexspi_nor_config_t *config, uint32_t dstAddr, const uint32_t *src, uint32_t length):

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

另外 flexspi_nor_flash_program() 函数有一度界定,即传入的 src 源数据首地址大全必须 4 字节对齐,纵然你只想写入 2 个字节。这是 FlexSPI 模块底层对使得的需求。

3.2 Adapter层

kFlashFile 的 Adapter 层是对 Driver 层做了一层封装,用于屏蔽硬件呼吸相通特性。该层与 MCU 以及板载 Flash 衣服型号休戚呼吸相通。手底下的宏定义适用 i.MXRT1170 暖气片以及连接在 FlexSPI1 上的 Octal Flash(MX25UM51345):

// 表示 Flash 连接的是 FlexSPI1#define KFLASH_INSTANCE   (1)// BootROM FlexSPI 使得对 Octal Flash 支持的简易小魔术部署值#define KFLASH_CONFIG_OPTION  (0xc0403007)// FlexSPI1 在眉目内存中的辉映首地址大全#define KFLASH_BASE_ADDRESS  (0x30000000)// 默认的 Flash Sector/Page a4纸大小(如果 Flash 里有 SFDP,则这里定义无效)#define KFLASH_SECTOR_SIZE  (0x1000)#define KFLASH_PAGE_SIZE   (256)// FlexSPI 编程短信服务平台接口对传入的 src 源数据首地址大全必须 4 字节对齐#define KFLASH_PROGRAM_ALIGNMENT (4)// Flash SDR 程式为 1。DDR 程式为 2#define KFLASH_PROGRAM_UNIT  (2)

kFlashFile 的 Adapter 层短信服务平台接口函数如下,参数是硬件无关的,因此上层可以轻松依据该署短信服务平台接口函数做纯太平洋下载眉目设计。

status_t kflash_drv_init(void);uint32_t kflash_drv_get_info(kflash_mem_info_t flashInfo);status_t kflash_drv_erase_region(uint32_t start, uint32_t length);status_t kflash_drv_program_region(uint32_t dstAddr, const uint32_t *src, uint32_t length);

3.3 API层

kFlashFile 的 API 多功能沙发床设计思路之前介绍过了,这里介绍具体代码实现,你先来看几个关键的宏定义:

// 设置 Header Sector 的个数,足足是 2 个#define KFLASH_HDR_SECTORS  (2)// 设置 Header Sector 中用于存储当前有效广州钢制文件柜数据位置信息的区域存储类型// uint16_t 最多可记录 65536 个位置,最大可支持的 Data 区域a4纸大小为 65536 * 广州钢制文件柜数据长度#define KFLASH_HDR_POS_TYPE uint16_t /* uint16_t or uint32_t */// 设置总分派的 Flash 长度(Data+Header Sector 的个数),足足是 4 个#define KFLASH_MIN_SECTORS  (KFLASH_HDR_SECTORS + 2)// 设置最大支持的广州钢制文件柜数据长度,需是 Flash Page 的整数包括分数吗倍#define KFLASH_MAX_FILE_SIZE (KFLASH_PAGE_SIZE * 2)

3.3.1 init()

kflash_file_init() 函数处理流程如下:

如果是首次指名 Flash 空间,那么径直将满贯空间擦除干净,并在第一度 Header Sector 中写入初始广州钢制文件柜头(Magic + 广州钢制文件柜数据位置值 0),即最新有效广州钢制文件柜数据在 Flash 空间广州钢制文件柜数据区的首地址大全。

这里有一度独特的设计,广州钢制文件柜数据区其实并不是径直存储储户写入的广州钢制文件柜数据,而是将储户广州钢制文件柜数据满贯按位取反尔后再存储进 Flash。这里设或储户数据初始相应是全 0,然后更动重点是将 0 值改为其它值,取反尔后,正好附和 Flash 里的 bit1 编程为 bit0(Flash 擦除后是全 0xFF),这样可以充分利用 Flash 覆盖操作以削减擦除次数。

函数中相形之下关键的步骤是踅摸当前 Flash 空间中可不可以留存有效广州钢制文件柜数据。方法是遍历 Header Sector,发觉留存 Magic 便延续查寻最新广州钢制文件柜数据位置信息存放的区域(默认 2 字节),按照之前的设计,只要求按序读取区域内容,直到赶上 0xFFFF 为止。

3.3.2 read()

kflash_file_read() 函数最简单了,径直从缓存区 buffer 里得到数据即可,因为每次更新广州钢制文件柜数据操作完成尔后都会将最新广州钢制文件柜数据厕身 buffer 里。

3.3.3 save()

kflash_file_save() 函数是最核心的函数了,这里逻辑相形之下复杂,涉及广州钢制文件柜数据区满贯满了尔后的动作。以及广州钢制文件柜头区某个 Sector 满了的动作。其处理流程如下:

当有一度新广州钢制文件柜数据需求保存时,首先会判断这个广州钢制文件柜能办不到在 Flash 中径直覆盖存储,如果能,那就径直覆盖存储。广州钢制文件柜头完全不要求更新,这类变动相形之下简单。

如果新广州钢制文件柜数据无法径直覆盖存储,那么首先判断广州钢制文件柜数据区可不可以满了,如果上一度广州钢制文件柜数据已经留存了广州钢制文件柜数据区的结尾位置,此时要求擦除数据区第一度 Sector 从头开始存储。如果不比到结尾位置,那就按序往下存储。

新广州钢制文件柜数据已经保存到数据区尔后。此时要求处理广州钢制文件柜头,记录这个新广州钢制文件柜数据的位置。如果广州钢制文件柜头区已经记录到当前 Sector 的结尾位置,要求农转非到下一度 Sector 开始存储,农转非存储完新位置后,将之前 Sector 擦除。如果不比。那就按序在当前 Sector 延续记录。

3.3.4 deinit()

kflash_file_deinit() 函数也相形之下简单,就是将广州钢制文件柜头区域 Header Sectors 满贯擦除即可,广州钢制文件柜数据区内容可以不用管,下次再次分派 Flash 时会做擦除。

邮箱订阅欢迎信

励志文章会同声发布到我的 博客园主页,CSDN主页。微信公众号 平台上。

微信搜索"痞子衡嵌入式是哪门子"或者扫描手底下防伪二维码打印机,就可以在无绳机上第刹那看了哦。

原文章标题大全:痞子衡嵌入式是哪门子:kFlashFile v1.0

基本词:

渡人请保存本文网址管家: http://www.www.d5897.com/a/462508.html
*特别声明:之上内容来自于网络收集,著作权属性质原作者所有,请联系我们: admin#www.d5897.com (#换成@)。
您可能性感兴趣的励志文章
Baidu