打印
[开发工具]

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

[复制链接]
592|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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介绍

结构体功能:在TinyFlashDB中,API的操作都需要指定的参数index,该index结构体中存储了flash的地址,flash的大小,存储的变量的长度,结束标志位。在读取flash扇区时会去校验此信息。

函数功能:从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成功,其他失败。

函数功能:在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字节。

数据存储时,会根据flash支持的字节操作进行对齐,所以函数中rwbuffer指向的数据第二要求至少为下面函数中计算得出的alignedvalue_size个字节:
每次写入后都会再读取出来进行校验,如果校验不通过,就会继续在下一个地址继续尝试写入。直到达到最大写入次数(TFDBWRITEMAX_RETRY)或者头部校验错误。
读取数据时也会计算和校验,不通过的话继续读取,直到返回校验通过的最新数据,或者读取失败。
TinyFlashDB移植和配置
移植使用只需要在tfdb_port.c中,编写完成三个接口函数,也要在tfdb_port.h中添加相应的头文件和根据不同芯片修改宏定义

需要注意头文件问题

所有的配置项都在tfdb_port.h中
RD8T36P的flash擦除后的值为0x00,与一般的单片机不同

TFDB.h内可以配置存储器地址和通过宏进行存储器选择

接口函数文件内会根据存储器宏进行选择操作函数

RD8T36P使用RD LINK PRO仿真时,步骤是1编译-》2下载-》3进仿真(编译完不下载直接进仿真,仿真执行不正确)

点击下载时会有IAP操作提醒,这在调试时的option状态能有提示作用(IAP操作范围非常重要,不然操作会失败)
调试模式时IAP的使能状态如下


测试程序在TFDB.c内,调试操作过程如下:

更改程序运行函数变量

读取数据前情况缓存区

读取成功后,内存缓存区重新被赋值

经过上述操作,读写都是正确的,整个移植过程就介绍完了。希望对大家有所帮助。
TFDB项目地址:https://github.com/smartmx/TFDB/tree/main
测试工程源码: NBK-RD8x3x Demo Code(TFDB).zip (8.17 MB)

使用特权

评论回复
沙发
RDS小定| | 2022-11-30 20:07 | 只看该作者
终于看到对IAP的测评了

使用特权

评论回复
评论
6552918 2022-11-30 20:20 回复TA
没应用笔记,坑很多,说多了都是泪。。。 
板凳
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寿命.

使用特权

评论回复
5
caizhiwei| | 2024-3-4 13:38 | 只看该作者
要移植的话,很奇怪,port.c port.h中都没有看到底层读写flash的接口啊!

使用特权

评论回复
6
caizhiwei| | 2024-3-4 13:40 | 只看该作者
找到了,不好意思
TFDB_Err_Code tfdb_port_write(tfdb_addr_t addr, const uint8_t *buf, size_t size)
{
    TFDB_Err_Code result = TFDB_NO_ERR;
    /* You can add your code under here. */

    return result;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

100

主题

1184

帖子

5

粉丝