51822 SDK12.3 fstorage的使用

对于32位单片机来说,所有的数据在默认情况下是采用字节对齐的,至于什么是字节对齐,请自行百度,所以我们在进行存储时,由于字节对齐的原因,我们的数据编辑存储需要自行进行调整尽量避免字节对齐造成的不必要的错误。你参照官方例程时,会发现官方的例程采用的是32位的变量,就算是有缓存数组,也是采用32位的数据类型的。很多时候我们会采用结构体作为模块数据结构变量,此时存储该数据结构要非常注意字节对齐。对于结构体中的元素,我们可能用到8位,16位,32位的变量,如果不强行字节对齐,一定要有组织的给自己的元素进行排序。强行字节对齐方式以 #pragma pack(对齐长度) 开始,#program pack()结束,之间的数据结构为对其长度的对齐方式,比如对其长度为1,则该数据结构的对齐方式是单字节对齐,最终整个数据结构的长度为4的整数倍,不足的补充预留变量在数据结构中。举例如下:

(1)非字节对齐

typedef struct

{

uint8_t  a;

uint16_t b;

uint16_t c;

uint32_t d;

}_A;

typedef struct

{

uint16_t b;

uint16_t c;

uint8_t a;

uint32_t d;

}_B;

众所周知,我们的结构体是支持指针的,所以可以确定他所占用的RAM空间在地址上是连续的,在32位的单片机中,数据结构_A,a和b一共占用了4字节,c和d一共占用了8字节,整个数据结构一共占用了12字节,这就是字节对齐造成的,而数据结构_B,b和c一共占用了4字节,而a占用了4字节,d占用了4字节,共12字节,这也是字节对齐造成的。

强制字节对齐

#pragram pack(1)

typedef struct

{

uint8_t  a;

uint16_t b;

uint16_t c;

uint32_t d;

}_A;

#pragram pack()

此时上述所占用RAM大小为9字节,因为现在是强制单字节对齐,强制字节对齐,节省了RAM,应该增加程序的运行时间,此消彼长。对于存储而言,官方要求是4字节对齐的,此时如果直接对_A进行操作时是不满足要求的,需要修改如下

#pragram pack(1)

typedef struct

{

uint8_t  a;

uint16_t b;

uint16_t c;

uint32_t d;

uint8_t reverse[3];         //预留3字节保证字节对齐

}_A;

#pragram pack()

上面的描述是些基础知识,下面步入正题。

FS_REGISTER_CFG(fs_config_t fs_config1) =
{
.callback  = fs_evt_handler, // Function for event callbacks.
.num_pages = TEST_PAGE_NUM,       // Number of physical flash pages required.
.priority  = USER_SNV_TEST1             // Priority for flash usage.
};

先定义一个存储配置变量,为需要的存储操作合理的分配资源,USER_SNV_TEST1取值范围1到254,255留给配对绑定使用,TEST_PAGE_NUM为你认为需要存储的空间大小。fs_evt_handler为存储触发的事件回调函数。fstroage的读取操作是同步的,而写入操作是异步的,也就是说你发起写入操作之后,不确定在什么时候才开始真正的进行写操作。另外即便发起了写操作,也有写入失败的可能,这个问题的完美解释在nordic的一份资料里面有提及。上代码:

回调函数

static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result)
{
    if (result != FS_SUCCESS)
    {
        // An error occurred.
    }
else
{
switch(evt->id)
{
case FS_EVT_STORE:  
if(result == FS_SUCCESS)
{
memset((uint8_t *)&MySnvStorage,0,sizeof(_MY_SNV_STORAGE));
MSG_ParaOperationSNV(MySnvPara.PercentSelectF,SNV_OPERATION_READ);
__nop();
}

else
{
MSG_ParaOperationSNV(MySnvPara.PercentSelectF,SNV_OPERATION_WRITE);
}
break;

case FS_EVT_ERASE:

if(result == FS_SUCCESS)
{
if(MySnvPara.OperationF != SNV_OPERATION_ERASE)
{
MSG_ParaOperationSNV(MySnvPara.PercentSelectF,SNV_OPERATION_WRITE);
}
}

else
{
MSG_ParaOperationSNV(MySnvPara.PercentSelectF,SNV_OPERATION_ERASE);
}
break;

default : break;
}
}
}

进行存储操作的函数

void MSG_ParaOperationSNV(_USER_SNV_ENUM _snvaddr,_USER_SNV_OPERATION _operation)
{
fs_ret_t ret = FS_SUCCESS;
    switch(_snvaddr)
    {
case USER_SNV_TEST1:

if(_operation == SNV_OPERATION_WRITE)
{
ret = fs_store(&fs_config1, fs_config1.p_start_addr, SaveUserBuff,sizeof(_MY_SNV_STORAGE)/sizeof(uint32_t),NULL);
MySnvPara.OperationF = SNV_OPERATION_WRITE;
}
//
else if(_operation == SNV_OPERATION_READ)
{
//
for(uint16_t i=0; i<sizeof(_MY_SNV_STORAGE)/sizeof(uint32_t); i++)
SaveUserBuff[i] = *(fs_config1.p_start_addr + i);
MySNV_CpyData((uint8_t *)&MySnvStorage,(uint8_t *)SaveUserBuff,sizeof(_MY_SNV_STORAGE));
MySnvPara.OperationF = SNV_OPERATION_READ;
}
//
else if(_operation == SNV_OPERATION_UPDATE)
{
ret = fs_erase(&fs_config1, fs_config1.p_start_addr, TEST_PAGE_NUM,NULL);
if (ret != FS_SUCCESS)
{}
//
MySNV_CpyData((uint8_t *)SaveUserBuff,(uint8_t *)&MySnvStorage,sizeof(_MY_SNV_STORAGE));
MySnvPara.OperationF = SNV_OPERATION_UPDATE;
}
//
else if(_operation == SNV_OPERATION_ERASE)
{
ret = fs_erase(&fs_config1, fs_config1.p_start_addr, TEST_PAGE_NUM,NULL);
MySnvPara.OperationF = SNV_OPERATION_ERASE;
}
MySnvPara.PercentSelectF = USER_SNV_TEST1;
break;

}

}

如果采用上述函数(作者自定义的),写入数据时建议进行update操作,对于所有的存储操作之前,要确保该FLASH区域是没有被写操作过的,当你修改某一个区域的某一个数据时,先要执行擦除操作,然后才能重新写入。读数据时则不需要,希望各位仔细研究一下。当你配置了该存储结构,你也就选择了数据在FLASH中的唯一的存储地址,这个存储地址应该是和USER_SNV_TEST1有关系,仔细翻阅官方资料,会了解更多。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值