NRF51822基于蓝牙协议栈SDK+FDS-Flash data storage 的使用及应用例程

操作系统:win10 64位

开发IDE:Keil MDK V5.26

SDK蓝牙协议栈:nRF5 SDK v12.3.0

使用NRF51822的FDS(Flash data storage)进行Flash的操作,用于存储一些掉电后需要保存的数据。如何使用呢?

(1)使用FDS,最好把SDK升级到较新的版本,如nRF5 SDK v12.3.0

(2)在sdk_config.h中,配置使能FDS,即把FDS_ENABLED 改为 1

//  FDS_ENABLED - fds - Flash data storage module
//==========================================================
#ifndef FDS_ENABLED
#define FDS_ENABLED 1
#endif

(3)添加基于SDK的FDS相关的驱动文件。把 fds.c fstorage.c加入到工程中,并配置好头文件的路径。

NRF51822基于蓝牙协议栈SDK+FDS-Flash data storage 的使用及应用例程_第1张图片

 

相关驱动代码:

#include "fstorage.h"
#include "fds.h"

#define	MAX_DVR_SN_LEN        16
#define NET_PARAM_ID    1  //这个ID不重复即可
#define DVR_SN_KEY     1 //KEY,也能不重复,一个ID可以有多个KEY,1,2,3...

uint8_t g_dvr_sn[MAX_DVR_SN_LEN];

//删除
bool del_dvr_sn(void)
{
	static ret_code_t ret = 0;
	fds_record_desc_t dvr_sn_desc = {0};
	fds_find_token_t tok = {0};
	ret = fds_record_find(NET_PARAM_ID, DVR_SN_KEY, &dvr_sn_desc, &tok);
	if(ret == FDS_ERR_NOT_FOUND)
	{
		return false;
	}
	else
	{
		fds_record_delete(&dvr_sn_desc);
	}
	return true;
}

//设置保存
void set_dvr_sn(void)
{
	static uint32_t sn_data[MAX_DVR_SN_LEN/4] = {0};
	static uint8_t i = 0;
	uint8_t * ptr_sn_data = NULL;
	fds_record_desc_t dvr_sn_desc={0};

	fds_record_chunk_t chunk;
	fds_record_t record;

	record.file_id = NET_PARAM_ID;
	record.key = DVR_SN_KEY;
	ptr_sn_data = (uint8_t *)sn_data;

	for(i = 0; i < MAX_DVR_SN_LEN; i++)
	{
		ptr_sn_data[i] = g_dvr_sn[i];
	}

	chunk.p_data = sn_data;
	chunk.length_words = sizeof(sn_data)/sizeof(uint32_t);

	record.data.p_chunks = &chunk;
	record.data.num_chunks = 1;

	fds_record_write(&dvr_sn_desc, &record);
}

//读取
bool get_dvr_sn(void)
{
	fds_find_token_t tok = {0};
	fds_record_desc_t dvr_sn_desc = {0};
	memset(g_dvr_sn, 0, sizeof(g_dvr_sn));
	if(fds_record_find(NET_PARAM_ID, DVR_SN_KEY, &dvr_sn_desc, &tok) == FDS_SUCCESS)
	{
		uint8_t i = 0;
		fds_flash_record_t record = {0};
		fds_record_open(&dvr_sn_desc, &record);
		uint8_t *p = (uint8_t*)record.p_data;
		for(i = 0; i < MAX_DVR_SN_LEN; i++)
		{
			*(g_dvr_sn+i) = *(p+i);
		}
		fds_record_close(&dvr_sn_desc);
		return true;
	}
	return false;
}

 

注意事项:

(1)FDS的使用时,需要设置一个ID与一个KEY,一个ID下面可以多个KEY,一个KEY可以对应一个值。一个ID下面多个不同的值,可以用多个KEY标记。

(2)FDS的写操作是异步的。也就是函数执行完,可能数据还没有及时的写入。因此,这里代入的值需要为全局变量地址或是static静态的。

(3)FDS最小的操作单位为4个字节,因此如果不足四个字节,需要补成4字节对齐。

(4)FDS理论上存一些较小的参数,长度最好不要太长。否则需要在sdk_config.h中设置FDS的大小与分区。

//  FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. 
//  One of the virtual pages is reserved by the system for garbage collection.
//  Therefore, the minimum is two virtual pages: one page to store data and
//  one page to be used by the system for garbage collection. The total amount
//  of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES
//  @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes.

#ifndef FDS_VIRTUAL_PAGES
#define FDS_VIRTUAL_PAGES 3
#endif

//  FDS_VIRTUAL_PAGE_SIZE  - The size of a virtual page of flash memory, expressed in number of 4-byte words.
 

//  By default, a virtual page is the same size as a physical page.
//  The size of a virtual page must be a multiple of the size of a physical page.
// <256=> 256 
// <512=> 512 
// <1024=> 1024 

#ifndef FDS_VIRTUAL_PAGE_SIZE
#define FDS_VIRTUAL_PAGE_SIZE 256
#endif

(5)FDS操作可以通过fds_event_handler 回调函数,获取一些状态。

(6)如果数据较长,可能FDS写会失败,可以在前面调用 fds_gc() 进入垃圾回收后再写操作。

 

 

你可能感兴趣的:(嵌入式软件)