I try to using nrf_fstorage_write() to write data to fstorage and then waiting writting finish. But it hang at sd_app_evt_wait().fstorage.h
#include "app_timer.h"
#include "error.h"
#include "fds_flash.h"
#include "fstorage.h"
#include "nrf_delay.h"
#include "nrf_fstorage.h"
#include "nrf_fstorage_sd.h"
#include "nrf_fstorage_nvmc.h"
#include "nrf_log.h"
#include "nrf_soc.h"
#include "spi_flash.h"
#define FSTORAGE_PAGE_NUM 3
#define FSTORAGE_WAIT_CNT 1000
static bool _gFstorageInitialized = false;
static bool _gFstorageEraseDone = true;
static bool _gFstorageWriteDone = true;
static bool _gFstoragePageDirty = true;
static void _fstorageEvtHandler(nrf_fstorage_evt_t * p_evt);
NRF_FSTORAGE_DEF(nrf_fstorage_t _gFstorage) =
{
/* Set a handler for fstorage events. */
.evt_handler = _fstorageEvtHandler,
/* These below are the boundaries of the flash space assigned to this instance of fstorage.
* You must set these manually, even at runtime, before nrf_fstorage_init() is called.
* The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
* last page of flash available to write data. */
.start_addr = 0x7D000,
.end_addr = 0x80000,
};
static void _fstorageEvtHandler(nrf_fstorage_evt_t * pEvt) {
NRF_LOG_DEBUG("Evt e\n");
switch (pEvt->id) {
case NRF_FSTORAGE_EVT_WRITE_RESULT:
{
NRF_LOG_DEBUG("Evt w\n");
_gFstorageWriteDone = true;
if (pEvt->result != NRF_SUCCESS) {
NRF_LOG_WARNING("fstorage writing failed %d bytes at address 0x%x.",
pEvt->len, pEvt->addr);
} else {
NRF_LOG_DEBUG("NRF_FSTORAGE_EVT_WRITE_RESULT ok");
_gFstoragePageDirty = true;
}
} break;
case NRF_FSTORAGE_EVT_ERASE_RESULT:
{
NRF_LOG_DEBUG("Evt er\n");
_gFstorageEraseDone = true;
if (pEvt->result != NRF_SUCCESS) {
NRF_LOG_WARNING("fstorage erased failed %d page from address 0x%x.",
pEvt->len, pEvt->addr);
} else {
NRF_LOG_DEBUG("NRF_FSTORAGE_EVT_ERASE_RESULT ok");
_gFstoragePageDirty = false;
}
} break;
default:
break;
}
NRF_LOG_DEBUG("Evt x\n");
}
static uint32_t _fstorageGetEndAddr(void) {
const uint32_t bootloaderAddr = BOOTLOADER_ADDRESS;
const uint32_t pageSz = NRF_FICR->CODEPAGESIZE;
const uint32_t codeSz = NRF_FICR->CODESIZE;
return (bootloaderAddr != 0xFFFFFFFF ?
bootloaderAddr : (codeSz * pageSz));
}
static uint32_t _fstorageGetStartAddr(void) {
const uint32_t eraseUnit = _gFstorage.p_flash_info->erase_unit;
const uint32_t endAddr = _fstorageGetEndAddr();
const uint32_t bootloaderAddr = BOOTLOADER_ADDRESS;
uint32_t startAddr;
if (bootloaderAddr == 0xFFFFFFFF) {
startAddr = endAddr - FDS_VIRTUAL_PAGES * eraseUnit;
} else {
startAddr = bootloaderAddr - FSTORAGE_PAGE_NUM * eraseUnit;
}
NRF_LOG_DEBUG("endAddr=0x%x", endAddr);
NRF_LOG_DEBUG("startAddr=0x%x", startAddr);
return startAddr;
}
static bool _fstorageIsEraseNeeded(void) {
return _gFstoragePageDirty;
}
static uint32_t _fstorageRoundUpU32(const uint32_t len) {
if (len % sizeof(uint32_t)) {
return (len + sizeof(uint32_t) - (len % sizeof(uint32_t)));
}
return len;
}
static void power_manage(void)
{
#ifdef SOFTDEVICE_PRESENT
(void) sd_app_evt_wait();
#else
__WFE();
#endif
}
int _fstorageWait(const uint32_t timeOutCnt) {
#if 0
NRF_LOG_DEBUG("timeOutCnt=%u\n", timeOutCnt);
const uint32_t startCnt = app_timer_cnt_get();
NRF_LOG_DEBUG("startCnt=%u\n", startCnt);
uint32_t endCnt;
uint32_t diffCnt;
do {
endCnt = app_timer_cnt_get();
diffCnt = app_timer_cnt_diff_compute(endCnt, startCnt);
if (diffCnt >= timeOutCnt) {
NRF_LOG_WARNING("_fstorage wait timeout\n");
return ERROR_FSTORAGE_WAIT_TIMEOUT;
}
if (_gFstorageEraseDone && _gFstorageWriteDone) {
break;
}
} while (true);
NRF_LOG_DEBUG("endCnt=%u\n", endCnt);
#else
while (nrf_fstorage_is_busy(&_gFstorage))
{
power_manage();
}
#endif
return 0;
}
int _fstorageRead(const uint32_t addr, const uint32_t len, uint8_t* data) {
if (!_gFstorageInitialized) {
return ERROR_FSTORAGE_UNINITIALIZED;
}
const ret_code_t errCode = nrf_fstorage_read(&_gFstorage, addr, data, len);
if (errCode != NRF_SUCCESS) {
NRF_LOG_WARNING("nrf_fstorage_read() failed 0x%x\n", errCode);
return ERROR_FSTORAGE_READ_FAIL;
}
return 0;
}
int _fstorageWrite(const uint32_t addr, const uint32_t len, void const* pData) {
if (!_gFstorageInitialized) {
return ERROR_FSTORAGE_UNINITIALIZED;
}
if (!_gFstorageEraseDone) {
return ERROR_FSTORAGE_ERASE_ON_GOING;
}
if (!_gFstorageWriteDone) {
return ERROR_FSTORAGE_WRITE_ON_GOING;
}
_gFstorageWriteDone = false;
const uint32_t wlen = _fstorageRoundUpU32(len);
const ret_code_t retCode = nrf_fstorage_write(&_gFstorage, addr, pData, wlen, NULL);
if (retCode != NRF_SUCCESS) {
NRF_LOG_WARNING("nrf_fstorage_write() failed 0x%x", retCode);
return ERROR_FSTORAGE_WRITE_FAIL;
}
_fstorageWait(FSTORAGE_WAIT_CNT);
return 0;
}
int fstorageInit(void) {
_gFstorageInitialized = false;
const ret_code_t errCode = nrf_fstorage_init(&_gFstorage, &nrf_fstorage_sd, NULL);
if (errCode != NRF_SUCCESS) {
NRF_LOG_WARNING("nrf_fstorage_init() failed 0x%x", errCode);
return ERROR_FSTORAGE_INITIALIZE_FAIL;
}
_gFstorageInitialized = true;
return 0;
}
int fstorageErase(const uint32_t addr, const uint32_t pagesCnt) {
if (!_gFstorageInitialized) {
return ERROR_FSTORAGE_UNINITIALIZED;
}
if (!_gFstorageEraseDone) {
return ERROR_FSTORAGE_ERASE_ON_GOING;
}
if (!_gFstorageWriteDone) {
return ERROR_FSTORAGE_WRITE_ON_GOING;
}
_gFstorageEraseDone = false;
const ret_code_t errCode = nrf_fstorage_erase(&_gFstorage, addr, pagesCnt, NULL);
if (errCode != NRF_SUCCESS) {
NRF_LOG_WARNING("nrf_fstorage_erase() failed 0x%x", errCode);
return ERROR_FSTORAGE_ERASE_FAIL;
}
_fstorageWait(FSTORAGE_WAIT_CNT);
return 0;
}
/*
int fstorageEraseFDS(void) {
const uint32_t eraseUnit = _gFstorage.p_flash_info->erase_unit;
const uint32_t endAddr = _fstorageGetEndAddr();
const uint32_t bootloaderAddr = BOOTLOADER_ADDRESS;
uint32_t addr;
if (bootloaderAddr == 0xFFFFFFFF) {
addr = endAddr - FDS_VIRTUAL_PAGES * eraseUnit;
} else {
addr = bootloaderAddr - FDS_VIRTUAL_PAGES * eraseUnit;
}
const uint32_t pagesCnt = FDS_VIRTUAL_PAGES;
const ret_code_t errCode = nrf_fstorage_erase(&_gFstorage, addr, pagesCnt, NULL);
if (errCode != NRF_SUCCESS) {
NRF_LOG_WARNING("nrf_fstorage_erase() failed 0x%x\n", errCode);
return ERROR_FSTORAGE_ERASE_FAIL;
}
return 0;
}
*/
int fstorageReadRecord(const uint32_t addr, record_t* pRecord) {
uint8_t data[RECORD_LEN] = {0};
if (_fstorageRead(addr, RECORD_LEN, data) != 0) {
return ERROR_FDS_READ_FAIL;
}
data2Record(data, pRecord);
return 0;
}
int fstorageUpdateRecord(const record_data_type_t type, const record_t* pRecord) {
const uint32_t addr = _fstorageGetStartAddr();
NRF_LOG_DEBUG("type=%d, add=0x%x\n", type, addr);
switch (type) {
case RECORD_DATA_TYPE_START:
{
NRF_LOG_DEBUG("RECORD_DATA_TYPE_START E\n");
if (_fstorageIsEraseNeeded()) {
NRF_LOG_DEBUG("fstorageErase() E\n");
fstorageErase(addr, 1);
}
NRF_LOG_DEBUG("fstorageWriteRecord() E\n");
record_t record;
record.offsetStart = 0;
record.offsetEnd = 0;
fstorageWriteRecord(addr, &record);
NRF_LOG_DEBUG("RECORD_DATA_TYPE_START x\n");
}
break;
case RECORD_DATA_TYPE_END:
{
NRF_LOG_DEBUG("RECORD_DATA_TYPE_END E\n");
record_t record;
NRF_LOG_DEBUG("fstorageReadRecord() E\n");
if (fstorageReadRecord(addr, &record) != 0) {
return ERROR_FSTORAGE_READ_FAIL;
}
NRF_LOG_DEBUG("fstorageReadRecord() x\n");
NRF_LOG_DEBUG("record.offsetStart=0x%x", record.offsetStart);
NRF_LOG_DEBUG("record.offsetEnd=0x%x", record.offsetEnd);
if (_fstorageIsEraseNeeded()) {
NRF_LOG_DEBUG("fstorageErase() E\n");
fstorageErase(addr, 1);
}
record.offsetEnd = pRecord->offsetEnd;
NRF_LOG_DEBUG("record.offsetEnd=0x%x", record.offsetEnd);
NRF_LOG_DEBUG("fstorageWriteRecord() E\n");
fstorageWriteRecord(addr, &record);
NRF_LOG_DEBUG("RECORD_DATA_TYPE_END X");
}
break;
}
return 0;
}
int fstorageWriteRecord(const uint32_t addr, record_t* pRecord) {
uint8_t data[RECORD_LEN] = {0};
record2Data(pRecord, data);
if (_fstorageWrite(addr, RECORD_LEN, data) != 0) {
return ERROR_FSTORAGE_WRITE_FAIL;
}
return 0;
}
int _fstorageWrite(const uint32_t addr, const uint32_t len, void const* pData) {
if (!_gFstorageInitialized) {
return ERROR_FSTORAGE_UNINITIALIZED;
}
if (!_gFstorageEraseDone) {
return ERROR_FSTORAGE_ERASE_ON_GOING;
}
if (!_gFstorageWriteDone) {
return ERROR_FSTORAGE_WRITE_ON_GOING;
}
_gFstorageWriteDone = false;
const uint32_t wlen = _fstorageRoundUpU32(len);
const ret_code_t retCode = nrf_fstorage_write(&_gFstorage, addr, pData, wlen, NULL);
if (retCode != NRF_SUCCESS) {
NRF_LOG_WARNING("nrf_fstorage_write() failed 0x%x", retCode);
return ERROR_FSTORAGE_WRITE_FAIL;
}
_fstorageWait(FSTORAGE_WAIT_CNT);
return 0;
}