ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

闪存中的键值对:无文件系统 minINI

2022-04-19 13:02:10  阅读:153  来源: 互联网

标签:闪存 minINI 文件系统 键值 ini file define


  许多嵌入式系统应用需要以持久的方式存储某种数据:校准值、设置或日志信息。对于较少的数据量,使用外部存储器或文件系统是一种过度大材小用。在许多系统中,我使用minINI以“ini-file”的方式存储键值解析,但它需要使用某种文件系统。minINI很棒,效率很高,使获取和存储数据变得非常容易。但对于简单的情况,单个闪存页面或扇区正是我所需要的。相反,直接管理该页面,为什么不在没有文件系统的情况下使用minINI?

  例如,我使用上面的电路板驱动多达4个不同的步进电机和霍尔传感器。我需要存储校准偏移量和电机信息,并且每个电路板的信息可能不同。这些板通过RS-485总线连接,因此每个板都有一个唯一的地址。对于此应用程序,我需要存储键值对(例如,address=0x10)。为此,我使用minINI将数据存储在内部闪存的一页中,因此不需要文件系统。

1、概述

  因为 minINI 处理文件,所以它需要某种文件系统。对于较小的系统或较小的数据量,随着代码大小和数据需求的增加,这增加了复杂性。在本文中,我将介绍一种对 minINI 库进行无文件和无文件系统适配的方法,该方法只需要一个小型且可配置的 RAM 缓冲区以及单个 FLASH 页面或扇区。这样,一个非常通用和用户友好的键值存储可用于小型嵌入式系统,而无需文件系统。
  该实现可在 GitHub 上找到。

2、.ini文件

  .ini文件允许我将数据分组为“部分”和“键值”对。下面是一个示例:

[motor0]
name=split-flap 0
offset=30
x=0
 
[motor1]
offset=32

  使用minINI,我可以读/写这样的值。它具有“只读”模式,在这种模式下,我只能读取数据。

3、minINI接口

  minINI 架构包括一个“粘合”接口。这样,它可以很容易地适应不同的文件系统。以下是 FatFS 的“粘合”实现:

#define INI_FILETYPE    FIL
#define ini_openread(filename,file)   (f_open((file), (filename), FA_READ+FA_OPEN_EXISTING) == FR_OK)
#define ini_openwrite(filename,file)  (f_open((file), (filename), FA_WRITE+FA_CREATE_ALWAYS) == FR_OK)
#define ini_close(file)               (f_close(file) == FR_OK)
#define ini_read(buffer,size,file)    f_gets((buffer), (size),(file))
#define ini_write(buffer,file)        f_puts((buffer), (file))
#define ini_remove(filename)          (f_unlink(filename) == FR_OK)
 
#define INI_FILEPOS                   unsigned long//DWORD
#define ini_tell(file,pos)            (*(pos) = f_tell((file)))
#define ini_seek(file,pos)            (f_lseek((file), *(pos)) == FR_OK)

4、FLASH接口

  我们的想法是添加一个新的“粘合”,它不需要文件系统。相反,它直接读取和写入闪存,并模仿文件系统。
  这有一个限制:仅支持单个“ini文件”。该限制可以很容易地扩展到支持多个“文件”,但我真的没有看到这种需求,至少在我的应用程序中没有。

5、配置

  配置是使用配置宏(请参见软件配置的不同方式)。下面是一个示例配置:

  这样就可以配置闪存。数据大小宏用于限制数据大小,以减少用于写入闪存的内存缓冲区的数量。
需要从可用于链接器的闪存数量中减少/排除已使用的闪存,否则应用程序也可能使用它。以下是如何使用恩智浦MCUXpresso IDE从内存映射中减少内存:

6、命令行

  该实现包括一个命令行/shell 接口。
  低于只读配置的状态:

  “McuMinINI”显示minINI的“核心”信息,而“ini”组用于闪存实现它。
  使用命令行界面,可以检查或修改数据:

7、用法

  将键值对与 minINI 结合使用非常简单:我可以查询整数、布尔值、浮点值或字符串值。下面是获取设备存储地址的示例:

#define NVMC_MININI_FILE_NAME         "settings.ini" /* 'file' name used */
 
/* RS-485 bus settings */
#define NVMC_MININI_SECTION_RS485     "rs485"
#define NVMC_MININI_KEY_RS485_ADDR    "addr" /* long value: RS-485 address */
...
*addr = McuMinINI_ini_getl(NVMC_MININI_SECTION_RS485, NVMC_MININI_KEY_RS485_ADDR, 0x1, NVMC_MININI_FILE_NAME);

  我真正喜欢minINI的是我可以提供默认值(在上面的示例中0x1):如果部分/键不存在,它将返回我指定的默认值:这样默认值就不需要配置区域中的任何空间。
存储值类似于下面的示例:

McuMinINI_ini_putl(NVMC_MININI_SECTION_RS485, NVMC_MININI_KEY_RS485_ADDR, addr, NVMC_MININI_FILE_NAME);

8、内存要求

  当然,每个功能都会带来一些成本。但在这种情况下,我认为它真的是最小的。
  为了在闪存中存储数据,它至少需要一个扇区或闪存页。其大小取决于所使用的系统,例如1 kByte(LPC845)或2 KByte(Kinetis K22),具体取决于微控制器。大小配置为McuMinINI_CONFIG_FLASH_NVM_BLOCK_SIZE。
  对于写入访问,它需要一个RAM缓冲区来备份和存储来自FLASH的数据。该金额McuMinINI_CONFIG_FLASH_NVM_MAX_DATA_SIZE配置。最小值为 64 个字节。根据要存储的数据量,128 或 256 可能更合理。对于只读访问,缓冲区量为零。根据所使用的微控制器和SDK,需要闪存驱动程序的设备句柄:例如,在Kinetis上,这需要额外的100字节。对于像LP845这样的其他产品,不需要手柄,因为ROM例程用于闪存编程。
  在 Kinetis 上,只读配置会增加大约 6 KB 的代码大小(-O0,无优化),而使其读写会增加额外的 3 KB (-O0)。添加shell支持会增加额外的1 KB:因此这意味着最多需要10 KB的闪存,在启用优化后降至约6 KB。到目前为止,还不到完整的文件系统支持,很容易是30-50 KB的闪存。

9、总结

  有了这个用于minINI的附加粘合端口,可以在没有文件系统的情况下使用它。这使得它适用于较小的嵌入式系统。它支持只读和读写数据存储。它使用直接闪存读/写,只有在读写配置中,它才需要一个可配置的RAM缓冲区来写入或扩展数据。这样,就可以轻松地将“键值”对存储添加到任何嵌入式系统,而闪存的成本不到10 KB。
  您可以在GitHub上的McuLib中找到该实现。

链接

英文原文​:Key-Value pairs in FLASH Memory: file-system-less minINI | MCU on Eclipse

欢迎关注:

标签:闪存,minINI,文件系统,键值,ini,file,define
来源: https://www.cnblogs.com/foxclever/p/16164571.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有