[开发工具] 新定义MCU开发板测评 移植Flash存储方案(TinyFlashDB)及IAP调试注意事项

[复制链接]
 楼主| 6552918 发表于 2022-11-30 15:35 | 显示全部楼层 |阅读模式
<
本帖最后由 6552918 于 2022-11-30 15:38 编辑

TFDB
Tiny Flash Database for MCU.
TinyFlashDB设计前言
在单片机日常开发中,总会需要存储一些信息,这时就需要使用单片机FLASH存储的方案,目前单片机存储的方案有很多,比如:EASYFLASH、FLASHDB、OSAL_NV等等方案,他们程序都非常大,在存储不多的变量时不值得。而且很少有考虑到flash写入出错的情况。在实际产品中,嵌入式产品flash写入可能会受各种因素影响(电池供电、意外断电、气温等)从而并不是很稳定,一旦出现错误,会导致产品一系列问题。
TinyFlashDB设计理念
不同于其他很多的KV型数据库,TinyFlashDB每一个需要存储的变量都会分配一个单独的单片机flash扇区,变量长度不可变。所以TinyFlashDB仅适用于存储几个关键性变量(例如:IAP跳转标志、系统断电时间等等),不适合大规模数据存储(大规模数据存储可使用EASYFLASH等)。TinyFlashDB在设计时就考虑了写入错误的影响,追求力所能及的安全保障、资源占用方面尽可能的缩小(不到1kb代码占用)、尽可能的通用性(可以移植到51等8位机,无法逆序写入的stm32L4系列,某些flash加密的单片机和其他普通32位机上)。
TinyFlashDB API介绍
698523fc8316211a36280453256b208b
结构体功能:在TinyFlashDB中,API的操作都需要指定的参数index,该index结构体中存储了flash的地址,flash的大小,存储的变量的长度,结束标志位。在读取flash扇区时会去校验此信息。
7b1b4bf19c9d341190781906383c315c
函数功能:从index指向的扇区中获取一个index中指定变量长度的变量,flash头部数据校验出错不会重新初始化flash。
参数 index:tfdb操作的index指针。
参数rwbuffer:写入和读取的缓存,所有flash的操作最后都会将整理后的数据拷贝到该buffer中,再调用tfdbport_write或者tfdbportread进行写入。当芯片对于写入的数据区缓存有特殊要求(例如4字节对齐,256字节对齐等),可以通过该参数将符合要求的变量指针传递给函数使用。至少为4字节长度。
参数addrcache:可以是NULL,或者是地址缓存变量的指针,当addrcache不为NULL,并且也不为0时,则认为addrcache已经初始化成功,不再校验flash头部,直接从该addrcache的地址读取数据。
参数value_to:要存储数据内容的地址。
返回值:TFDBNOERR成功,其他失败。
bf730d47f7230253348a4f575532455b
函数功能:在index指向的扇区中写入一个index中指定变量长度的变量,flash头部数据校验出错重新初始化flash。
参数 index:tfdb操作的index指针。
参数rwbuffer:写入和读取的缓存,所有flash的操作最后都会将整理后的数据拷贝到该buffer中,再调用tfdbport_write或者tfdbportread进行写入。当芯片对于写入的数据区缓存有特殊要求(例如4字节对齐,256字节对齐等),可以通过该参数将符合要求的变量指针传递给函数使用。至少为4字节长度。
参数addrcache:可以是NULL,或者是地址缓存变量的指针,当addrcache不为NULL,并且也不为0时,则认为addrcache已经初始化成功,不再校验flash头部,直接从该addrcache的地址读取数据。
参数value_from:要存储的数据内容。
返回值:TFDBNOERR成功,其他失败。
TinyFlashDB设计原理
观察上方代码,可以发现TinyFlashDB的操作都需要tfdbindext定义的index参数。Flash初始化后头部信息为4字节,所以只支持1、2、4、8字节操作的flash:头部初始化时会读取头部,所以函数中rw_buffer指向的数据第一要求至少为4字节,如果最小写入单位是8字节,则为第一要求最少为8字节。
fbceff1b549b454cb96dc00430714c1b
数据存储时,会根据flash支持的字节操作进行对齐,所以函数中rwbuffer指向的数据第二要求至少为下面函数中计算得出的alignedvalue_size个字节:
13d340c41a3e8e894b1bc98f2f902385 0da03d765b4d45c0c80e8b9504eb1f7a 每次写入后都会再读取出来进行校验,如果校验不通过,就会继续在下一个地址继续尝试写入。直到达到最大写入次数(TFDBWRITEMAX_RETRY)或者头部校验错误。
读取数据时也会计算和校验,不通过的话继续读取,直到返回校验通过的最新数据,或者读取失败。
TinyFlashDB移植和配置
移植使用只需要在tfdb_port.c中,编写完成三个接口函数,也要在tfdb_port.h中添加相应的头文件和根据不同芯片修改宏定义
17d7bb8840823a26a9260081f0dfcf0d
需要注意头文件问题
9d7930494621ea3770177a458f20fbdf
所有的配置项都在tfdb_port.h中
RD8T36P的flash擦除后的值为0x00,与一般的单片机不同
073846dcb2080e7eda69c6e18ed0c60a
TFDB.h内可以配置存储器地址和通过宏进行存储器选择
3678cd7b57964f1eb05f2d9d5f15e691
接口函数文件内会根据存储器宏进行选择操作函数
26a1249025ae326a7c660de1b444b4ee
RD8T36P使用RD LINK PRO仿真时,步骤是1编译-》2下载-》3进仿真(编译完不下载直接进仿真,仿真执行不正确)
8de12c06b1c77f03d9588fd7b311d2b6
点击下载时会有IAP操作提醒,这在调试时的option状态能有提示作用(IAP操作范围非常重要,不然操作会失败)
调试模式时IAP的使能状态如下
7d168857912c76805ee287546f553f10
410ccec4ca41cf66e72b86800ee36139
测试程序在TFDB.c内,调试操作过程如下:
57b2fddab17dd0fe2d1360e816aa5aa7
更改程序运行函数变量
90d8dbc6984ddc44a2d5d9f9ffbe30ab
读取数据前情况缓存区
13e7a0b716996d628bdeab6e9a2e8287
读取成功后,内存缓存区重新被赋值
da13d23fe6501b87ad088616f8f0bff6
经过上述操作,读写都是正确的,整个移植过程就介绍完了。希望对大家有所帮助。
TFDB项目地址:https://github.com/smartmx/TFDB/tree/main
测试工程源码: NBK-RD8x3x Demo Code(TFDB).zip (8.17 MB, 下载次数: 11)

RDS小定 发表于 2022-11-30 20:07 | 显示全部楼层
终于看到对IAP的测评了

评论

没应用笔记,坑很多,说多了都是泪。。。  发表于 2022-11-30 20:20
wangqy_ic 发表于 2022-12-1 08:46 | 显示全部楼层
"TinyFlashDB每一个需要存储的变量都会分配一个单独的单片机flash扇区" 这个开销是不是多了些。一个实际的应用中有几个参数应该是个普遍现象吧,这要是就占了几个扇区……有点得不偿失的感觉~
 楼主| 6552918 发表于 2022-12-1 09:11 | 显示全部楼层
wangqy_ic 发表于 2022-12-1 08:46
"TinyFlashDB每一个需要存储的变量都会分配一个单独的单片机flash扇区" 这个开销是不是多了些。一个实际的 ...

每个扇区能保存很多数据,不是只保存一个数据,而是一组数据,我例程中也是保存的一个数组,实际使用中可以 通过结构体进行再分组。TinyFlashDB支持简单的均衡写保护,延长flash寿命.
caizhiwei 发表于 2024-3-4 13:38 | 显示全部楼层
要移植的话,很奇怪,port.c port.h中都没有看到底层读写flash的接口啊!
caizhiwei 发表于 2024-3-4 13:40 | 显示全部楼层
找到了,不好意思
  1. TFDB_Err_Code tfdb_port_write(tfdb_addr_t addr, const uint8_t *buf, size_t size)
  2. {
  3.     TFDB_Err_Code result = TFDB_NO_ERR;
  4.     /* You can add your code under here. */

  5.     return result;
  6. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:北京汇冠触摸技术有限公司/电子工程师
简介:电子工程师,嵌入式应用爱好者。

102

主题

1290

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部