the pstorage function(persistent storage) of nRF5X has been changed as fstorage in SDK12.
the APIs have been changed. So I write the example for demonstrating how to adopt those .
Board :nRF52832/SDK12/s132
STEP 0.
I create the project file "ble_app_fstoarge_test_file" in example\ble_peripheral
And the example is coopied from nRF5_SDK_12.2.0_f012efa\examples\ble_peripheral\ble_app_template
project config:
please include all the files in this folder
nRF5_SDK_12.2.0_f012efa\components\libraries\fds
include
"fds.h"
"fds.c"
"fstorage.h"
"fds.c"
and do not forget to paste the path to project option
STEP 1.
the line begins about 3124 in "sdk_config.h" should be modified as following for fds purpose.
("sdk_config.h" is located in nRF5_SDK_12.2.0_f012efa\examples\ble_peripheral\ble_app_fstorage_test_file\pca10040\s132\config)
add these codes to test fstorage
// <e> FDS_ENABLED - fds - Flash data storage module //========================================================== #ifndef FDS_ENABLED #define FDS_ENABLED 1 #endif #if FDS_ENABLED // <o> FDS_OP_QUEUE_SIZE - Size of the internal queue. #ifndef FDS_OP_QUEUE_SIZE #define FDS_OP_QUEUE_SIZE 4 #endif // <o> FDS_CHUNK_QUEUE_SIZE - Determines how many @ref fds_record_chunk_t structures can be buffered at any time. #ifndef FDS_CHUNK_QUEUE_SIZE #define FDS_CHUNK_QUEUE_SIZE 8 #endif // <o> FDS_MAX_USERS - Maximum number of callbacks that can be registered. #ifndef FDS_MAX_USERS #define FDS_MAX_USERS 8 #endif // <o> FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. // <i> One of the virtual pages is reserved by the system for garbage collection. // <i> Therefore, the minimum is two virtual pages: one page to store data and // <i> one page to be used by the system for garbage collection. The total amount // <i> of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES // <i> @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes. #ifndef FDS_VIRTUAL_PAGES #define FDS_VIRTUAL_PAGES 3 #endif // <o> FDS_VIRTUAL_PAGE_SIZE - The size of a virtual page of flash memory, expressed in number of 4-byte words. // <i> By default, a virtual page is the same size as a physical page. // <i> The size of a virtual page must be a multiple of the size of a physical page. // <1024=> 1024 // <2048=> 2048 #ifndef FDS_VIRTUAL_PAGE_SIZE #define FDS_VIRTUAL_PAGE_SIZE 1024 #endif #endif //FDS_ENABLED // </e> // <e> FSTORAGE_ENABLED - fstorage - Flash storage module //========================================================== #ifndef FSTORAGE_ENABLED #define FSTORAGE_ENABLED 1 #endif #if FSTORAGE_ENABLED // <o> FS_QUEUE_SIZE - Configures the size of the internal queue. // <i> Increase this if there are many users, or if it is likely that many // <i> operation will be queued at once without waiting for the previous operations // <i> to complete. In general, increase the queue size if you frequently receive // <i> @ref FS_ERR_QUEUE_FULL errors when calling @ref fs_store or @ref fs_erase. #ifndef FS_QUEUE_SIZE #define FS_QUEUE_SIZE 4 #endif // <o> FS_OP_MAX_RETRIES - Number attempts to execute an operation if the SoftDevice fails. // <i> Increase this value if events return the @ref FS_ERR_OPERATION_TIMEOUT // <i> error often. The SoftDevice may fail to schedule flash access due to high BLE activity. #ifndef FS_OP_MAX_RETRIES #define FS_OP_MAX_RETRIES 3 #endif // <o> FS_MAX_WRITE_SIZE_WORDS - Maximum number of words to be written to flash in a single operation. // <i> Tweaking this value can increase the chances of the SoftDevice being // <i> able to fit flash operations in between radio activity. This value is bound by the // <i> maximum number of words which the SoftDevice can write to flash in a single call to // <i> @ref sd_flash_write, which is 256 words for nRF51 ICs and 1024 words for nRF52 ICs. #ifndef FS_MAX_WRITE_SIZE_WORDS #define FS_MAX_WRITE_SIZE_WORDS 1024 #endif #endif //FSTORAGE_ENABLED // </e>
the "sdk_config.h" is first time added in SDK12, almost every function must config in this file.
STEP 2.
example code:
add these functions to test fstorage
about line 706
/*the definition for fstorage*/
static volatile uint8_t write_flag=0;
static uint8_t fs_callback_flag;
#define NUM_PAGES 4
#define PAGE_SIZE_WORDS 256
static uint32_t data;
static uint32_t flash_data[4];
/**@brief Function for the Power manager. */ static void power_manage(void) { uint32_t err_code = sd_app_evt_wait(); APP_ERROR_CHECK(err_code); } static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result) { if (result != FS_SUCCESS) { bsp_indication_set(BSP_INDICATE_FATAL_ERROR); } else { NRF_LOG_INFO("fstorage command successfully completed\n\r"); fs_callback_flag = 0; } } static void fstorage_test(void) { PRINTF("fstorage_test\r\n"); FS_REGISTER_CFG(fs_config_t fs_config) = { .callback = fs_evt_handler, // Function for event callbacks. .num_pages = NUM_PAGES, // Number of physical flash pages required. .priority = 0xFE // Priority for flash usage. }; fs_ret_t ret = fs_init(); if (ret != FS_SUCCESS) { bsp_indication_set(BSP_INDICATE_FATAL_ERROR); } // Erase one page (256*4). NRF_LOG_INFO("Erasing a flash page at address 0x%X\r\n", (uint32_t)fs_config.p_start_addr); fs_callback_flag = 1; ret = fs_erase(&fs_config, fs_config.p_start_addr, 1, NULL); if (ret != FS_SUCCESS) { bsp_indication_set(BSP_INDICATE_FATAL_ERROR); } while(fs_callback_flag == 1) { power_manage(); } //Read the first 4 words of the page NRF_LOG_INFO("Data read from flash address 0x%X: \r\n", (uint32_t)fs_config.p_start_addr); for(int i=0; i<4; i++) { flash_data[i] = *(fs_config.p_start_addr + i); NRF_LOG_INFO("%X \r\n", flash_data[i]); } /*agatha*/ NRF_LOG_INFO("from agatha\r\n"); data = 0x19950225; NRF_LOG_INFO("Writing data 0x%X to address 0x%X\r\n", data, (uint32_t)fs_config.p_start_addr ); fs_callback_flag = 1; ret = fs_store(&fs_config, fs_config.p_start_addr, &data, 1, NULL); if (ret != FS_SUCCESS) { bsp_indication_set(BSP_INDICATE_FATAL_ERROR); } while(fs_callback_flag == 1) { power_manage(); } //Read the first 4 words of the page NRF_LOG_INFO("Data read from flash address 0x%X: \r\n", (uint32_t)fs_config.p_start_addr); flash_data[2] = *(fs_config.p_start_addr); NRF_LOG_INFO("%X ", flash_data[2]); } /**@brief Function for application main entry. */ int main(void) { PRINTF("DEVICE START \r\n"); uint32_t err_code; bool erase_bonds; // Initialize. err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); ble_stack_init(); peer_manager_init(erase_bonds); if (erase_bonds == true) { NRF_LOG_INFO("Bonds erased!\r\n"); } gap_params_init(); advertising_init(); services_init(); conn_params_init(); // Start execution. NRF_LOG_INFO("Proximity Start!\r\n"); advertising_start(); /*the example function of fstorage*/ PRINTF("start fstorage test\r\n"); fstorage_test(); // Enter main loop. for (;;) { if (NRF_LOG_PROCESS() == false) { power_manage(); } } }
these code demo how to :
initialize fstorage ->clear the code page -> write at specific address (0x79000) ->read the address
and I define
the number of code pages and page_size should be a multiple of 4.
/*the definition for fstorage*/ static volatile uint8_t write_flag=0; static uint8_t fs_callback_flag; #define NUM_PAGES 4 #define PAGE_SIZE_WORDS 256 static uint32_t data; static uint32_t flash_data[4];
and the result print in segger_RTT will be like this :
NOTES:
1.this article only shows the most basic way to use fstorage, and how to prevent the conflict of
power_manage and fstorage.
2.I register the space and clear/ write at the same time, so the space for data to store is limited .
3.I did not define the start code page , so the fstorage will start at 0x79000 (in default)
but the start point is able to be assigned by yourself.
try to assign start point in
fs_config.p_start_addr
your could change the address 0x79000 as 0x78000 to observe the storaging address be entailed changed.
4.KNOWN insuffience :I have not implement how to use fstorage in interrupt (press button, UART...etc). Maybe I should write an example relate to fstorage and interrupt ?
Hello ! Can you tell me how to create a new project for nrf52. I use nrf52840 PDK. I always have trouble with the example in thier SDK. and I want to know how to create a new project.
回覆刪除try to change "ble_template" to suit your usage, but not to try to create a new project...
刪除it is really difficult to open a new project in Keil c