Hi,
I'm using S112 v6.0 with SDK 15.0 on nRF52810. It's based on app_ble_uart example. I have some data to save in flash. I define the address as follow:
#define PAGRE_TO_ERASE 1
#define FLASH_START_ADDR 0x27000
#define FLASH_STOP_ADDR 0x28000
#define FLASH_START_WRITE_ADDR FLASH_START_ADDR
I could write data to flash when powered up after nrf_fstorage_init and I could read them out. But when I wirte the data received from UART, I found that it have not write them into the flash. When I receive the data from uart, I would call read_clear_data() then delay 300ms, then I write them. When I read them out, I found that it's the data I write when powered up.
Attachment is my test code. Could anyone give me some advice? Thanks
#include "app_util.h" #include "stdio.h" #include "string.h" #include "user_config.h" #include "nrf_fstorage.h" #include "nrf_fstorage_sd.h" #include "nrf_delay.h" #include "app_timer.h" #include "nrf_nvic.h" #include "Flash_Handler.h" #define PAGRE_TO_ERASE 1 #define FLASH_START_ADDR 0x27000 #define FLASH_STOP_ADDR 0x28000 #define FLASH_START_WRITE_ADDR FLASH_START_ADDR uint8_t fs_event_num = 0; at_com_data_t at_com_data; //static bool reset_write_para = false; void idle_state_handle(void); void fs_evt_handler(nrf_fstorage_evt_t * evt); void fs_evt_handler(nrf_fstorage_evt_t * p_evt) { if (p_evt->result != NRF_SUCCESS) { return; } switch (p_evt->id) { case NRF_FSTORAGE_EVT_WRITE_RESULT: { // printf("wrote %d bytes at address 0x%x.\r\n", // p_evt->len, p_evt->addr); //uint32_t err_code = sd_nvic_SystemReset(); } break; case NRF_FSTORAGE_EVT_ERASE_RESULT: { // printf("erased %d page from address 0x%x.\r\n", // p_evt->len, p_evt->addr); } break; default: break; } } NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) = { .evt_handler = fs_evt_handler, .start_addr = FLASH_START_ADDR, .end_addr = FLASH_STOP_ADDR, }; void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage) { /* While fstorage is busy, sleep and wait for an event. */ while (nrf_fstorage_is_busy(p_fstorage)) { idle_state_handle(); } } void wait_flash_complete(void) { wait_for_flash_ready(&fstorage); } void flash_clear(void) { ret_code_t rc = nrf_fstorage_erase( &fstorage, /* The instance to use. */ FLASH_START_WRITE_ADDR, /* The address of the flash pages to erase. */ PAGRE_TO_ERASE, /* The number of pages to erase. */ NULL /* Optional parameter, backend-dependent. */ ); // printf("clear rc=0x%02x \r\n",rc); if (rc == NRF_SUCCESS) { // printf("Clear OK\r\n"); /* The operation was accepted. Upon completion, the NRF_FSTORAGE_ERASE_RESULT event is sent to the callback function registered by the instance. */ } } void flash_write(uint8_t *dat,uint16_t len) { ret_code_t rc = nrf_fstorage_write( &fstorage, /* The instance to use. */ FLASH_START_WRITE_ADDR, /* The address in flash where to store the data. */ dat, /* A pointer to the data. */ len, /* Lenght of the data, in bytes. */ NULL /* Optional parameter, backend-dependent. */ ); // printf("write rc=0x%02x\r\n",rc); if (rc == NRF_SUCCESS) { // printf("Write OK\r\n"); /* The operation was accepted. Upon completion, the NRF_FSTORAGE_WRITE_RESULT event is sent to the callback function registered by the instance. */ } } void flash_read(uint8_t *dat,uint16_t len) { ret_code_t rc = nrf_fstorage_read( &fstorage, /* The instance to use. */ FLASH_START_WRITE_ADDR, /* The address in flash where to read data from. */ dat, /* A buffer to copy the data into. */ len /* Lenght of the data, in bytes. */ ); // printf("read rc=0x%02x\r\n",rc); if (rc == NRF_SUCCESS) { // printf("Read OK\r\n"); /* The operation was accepted. Upon completion, the NRF_FSTORAGE_READ_RESULT event is sent to the callback function registered by the instance. Once the event is received, it is possible to read the contents of 'number'. */ } } void read_clear_data(void) { flash_read((uint8_t *)&at_com_data,sizeof(at_com_data)); flash_clear(); } void flash_init(void) { uint8_t name[] = "Test-string"; nrf_fstorage_init( &fstorage, /* You fstorage instance, previously defined. */ &nrf_fstorage_sd, /* Name of the backend. */ NULL /* Optional parameter, backend-dependant. */ ); read_clear_data(); memset(&at_com_data,0,sizeof(at_com_data)); printf("power=%d\r\n",at_com_data.tx_power); at_com_data.tx_power = -8; memcpy(&at_com_data.device_name[1],name,strlen((char *)name)); at_com_data.device_name[0] = strlen((char *)name); flash_write((uint8_t *)&at_com_data,sizeof(at_com_data)); memset(&at_com_data,0,sizeof(at_com_data)); flash_read((uint8_t *)&at_com_data,sizeof(at_com_data)); printf("aa_power=%d\r\n",at_com_data.tx_power); printf("%s\r\n",(char *)&at_com_data.device_name[1]); } void flash_operate(uint8_t event) { if(fs_event_num == FS_ERASE_EVT) { fs_event_num = FS_IDLE; // at_com_data.tx_power = 0x33; // printf("power=%x\r\n",at_com_data.tx_power); // printf("name=%s\r\n",&at_com_data.device_name[1]); // printf("con_interval=%x\r\n",at_com_data.con_interval.conInterval); // printf("adv_interval=%x\r\n",at_com_data.adver_interval); // printf("uart_cfg=%x\r\n",at_com_data.uart_cfg.br); read_clear_data(); nrf_delay_ms(100); flash_write((uint8_t *)&at_com_data,sizeof(at_com_data)); wait_flash_complete(); // printf("init power=%x\r\n",at_com_data.tx_power); // flash_read((uint8_t *)&at_com_data,sizeof(at_com_data)); } } //static void PowerUp_write_timeout_handler(void * p_context) //{ // //// printf("name=%s len=%d\r\n",&at_com_data.device_name[1],at_com_data.device_name[0]); //// printf("con_interval=%x\r\n",at_com_data.con_interval.conInterval); //// printf("adv_interval=%x\r\n",at_com_data.adver_interval); // if((reset_write_para)&&(PowerUp_uart_rec)) // { //// printf("Timeout write\r\n"); // fs_event_num = FS_ERASE_EVT; // } // //} //void PowerUp_write_timer_init(void) //{ // app_timer_create(&m_PowerUp_write_id, // APP_TIMER_MODE_SINGLE_SHOT, // PowerUp_write_timeout_handler); // // app_timer_start(m_PowerUp_write_id,POWER_UP_WRITE_TIMEOUT_INTERVAL,NULL); // reset_write_para = true; //}