reading incorrect data from fstorage after using J-Link script to upgrade firmware

Before using J-Link script to upgrade firmware,  offsetStart (0x0) and offsetEnd (0x32E06) are correct. But after using J-Link script to upgrade firmware, offsetStart (0xADDEFE01) and offsetEnd (0x1EF1FFFF) are not correct.

log messages of before using J-Link script to upgrade firmware.

 0> <debug> app: endAddr=0x7FFFF
 0> <debug> app: startAddr=0x7F000
 0> <debug> app: nrf_fstorage_read() e
 0>
 0> <debug> app: nrf_fstorage_read() x
 0>
 0> <debug> app: record
 0>
 0> <debug> app: offsetStart=0x0
 0>
 0> <debug> app: offsetEnd=0x32E06

log messages of after using J-Link script to upgrade firmware.

0> <debug> app: endAddr=0x7FFFF
 0> <debug> app: startAddr=0x7F000
 0> <debug> app: nrf_fstorage_read() e
 0>
 0> <debug> app: nrf_fstorage_read() x
 0>
 0> <debug> app: record
 0>
 0> <debug> app: offsetStart=0xADDEFE01
 0>
 0> <debug> app: offsetEnd=0x1EF1FFFF

Parents
  • Which memory address are you trying to read? where does the offsetSTart and offsetEND reside in the flash? How should I test this before and after? I only see softdevice and app hex file, so which version do i compare the results with? 

    Also which logs are you using? I do not see anything on RTT or serial (CDC) after flashing the softdevice and application hex file you gave.

  • I read memory address from 0x7F000. I am using rtt. I will provide Python3 program fo you to reproduce this issue.

  • Step to reproduce this issue.

    1. Unzip PyQt6.rar

    2. Open command prompt

    3. python3 main.py

    4. Press scan button

    5. Chose "ANCS2" and then press connect button

    6. Press measure button and wait 5 seconds

    7. Press read button

    8. Running J-Link script to upgrade firmware

    9. Repeat step 4, 5, 7

  • 3782.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    1
    #define FSTORAGE_WAIT_CNT    1000
    
    static bool _gFstorageInitialized = false;
    static bool _gFstorageEraseDone   = true;
    static bool _gFstorageWriteDone   = true;
    static bool _gFstoragePageDirty   = true;
    static fstorage_state_t _gFstorageState = FSTORAGE_STATE_UNKNOWN;
    static uint8_t _gData[RECORD_LEN] = {0};
    
    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 _fstorageGetEndAddr() can be used to retrieve the last address on the
         * last page of flash available to write data. */
        .start_addr = 0x7F000,
        .end_addr   = 0x7FFFF,
    };
    
    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;
                _gFstorageState     = FSTORAGE_STATE_WRITTEN;
                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;
                _gFstorageState     = FSTORAGE_STATE_ERASED;
                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)-1);
    }
    
    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))
        while (!_gFstorageEraseDone || !_gFstorageWriteDone) {
            NRF_LOG_DEBUG("pm e\n");
            power_manage();
            NRF_LOG_DEBUG("pm x\n");
        }
    #endif
    		return 0;
        
    }
    
    int _fstorageRead(const uint32_t addr, const uint32_t len, uint8_t* data) {
        if (!_gFstorageInitialized) {
            return ERROR_FSTORAGE_UNINITIALIZED;
        }   
    
        NRF_LOG_DEBUG("nrf_fstorage_read() e\n");
        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;
        }
        NRF_LOG_DEBUG("nrf_fstorage_read() x\n");
    
        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;
        _gFstorageState     = FSTORAGE_STATE_WRITING;
        const uint32_t wlen = _fstorageRoundUpU32(len);
    
        NRF_LOG_DEBUG("nrf_fstorage_write() e\n");
        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;
        }
        NRF_LOG_DEBUG("nrf_fstorage_write() x\n");
       
        _fstorageWait(FSTORAGE_WAIT_CNT);
    
        return 0;
    }
    
    
    static void _fstoragePrintInfo(void) {
        NRF_LOG_INFO("========| flash info |========");
        NRF_LOG_INFO("erase unit:   %d bytes", _gFstorage.p_flash_info->erase_unit);
        NRF_LOG_INFO("program unit: %d bytes", _gFstorage.p_flash_info->program_unit);
        NRF_LOG_INFO("end address: 0x%x",      _fstorageGetEndAddr());
        NRF_LOG_INFO("==============================");
    }
    
    int fstorageInit(void) {
        // initializing variables
        _gFstorageInitialized = false;
        _gFstorageEraseDone   = true;
        _gFstorageWriteDone   = true;
        _gFstoragePageDirty   = true;
        _gFstorageState = FSTORAGE_STATE_UNKNOWN;
    
        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;
        }
    
        _fstoragePrintInfo();
        _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;
        _gFstorageState     = FSTORAGE_STATE_ERASING;
    
        NRF_LOG_WARNING("nrf_fstorage_erase() e\n");
        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;
        }
        NRF_LOG_WARNING("nrf_fstorage_erase() x\n");
    
        _fstorageWait(FSTORAGE_WAIT_CNT);
        
        return 0;
    }
    
    int fstorageReadRecord(const uint32_t addr, record_t* pRecord) {
        if (_fstorageRead(addr, RECORD_LEN, _gData) != 0) {
            return ERROR_FDS_READ_FAIL;
        }
    
        data2Record(_gData, 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, addr=0x%x\n", type, addr);
        const fstorage_state_t state = fstorageGetState();
        NRF_LOG_DEBUG("state=%d\n", state);
        switch (type) {
            case RECORD_DATA_TYPE_START:
            {  
                NRF_LOG_DEBUG("START E\n");
                if ((state == FSTORAGE_STATE_UNKNOWN)) {
                    fstorageErase(addr, 1);    
                } else if (state == FSTORAGE_STATE_ERASED) {    
                    record_t record;
                    record.offsetStart = norFlashGetStartOffset();
                    record.offsetEnd   = norFlashGetStartOffset();
                    nrf_cal_get_datetime(&record.timeStart);
                    nrf_cal_get_datetime(&record.timeEnd);
                    recordPrintRecord("record", &record);
                    fstorageWriteRecord(addr, &record);
                }    
                NRF_LOG_DEBUG("START x\n");
            }    
            break;
    
            case RECORD_DATA_TYPE_END:
            {
                NRF_LOG_DEBUG("END E\n");
                static record_t record;
    
                if ((state == FSTORAGE_STATE_UNKNOWN) || (state == FSTORAGE_STATE_WRITTEN)) {
                    if (fstorageReadRecord(addr, &record) != 0) {
                        NRF_LOG_WARNING("fstorageReadRecord(0x%x) failed\n", addr);
                        return ERROR_FSTORAGE_READ_FAIL;
                    }
                    recordPrintRecord("record r", &record);
                    fstorageErase(addr, 1);
                } else if (state == FSTORAGE_STATE_ERASED) {
                    record.offsetEnd = pRecord->offsetEnd;
                    record.timeEnd   = pRecord->timeEnd;
                    recordPrintRecord("record w", &record);
                    fstorageWriteRecord(addr, &record);
                }    
                NRF_LOG_DEBUG("END X");
            }   
            break;    
        }    
    
        return 0;
    }
    
    int fstorageWaitUpdateRecordFinish(void) {
        record_t record;
        record.offsetEnd   = norFlashGetWrittenOffset();
        nrf_cal_get_datetime(&record.timeEnd);
        if (fstorageUpdateRecord(RECORD_DATA_TYPE_END, &record) != 0) {
            NRF_LOG_WARNING("fstorageUpdateRecord(%d) failed\n", RECORD_DATA_TYPE_END);
            return ERROR_FSTORAGE_WRITE_FAIL;
        }    
        return 0;
    }
    
    
    int fstorageWriteRecord(const uint32_t addr, record_t* pRecord) {
        record2Data(pRecord, _gData);
        if (_fstorageWrite(addr, RECORD_LEN, _gData) != 0) {
            return ERROR_FSTORAGE_WRITE_FAIL;
        }
    
        return 0;
    }
    
    bool fstorageGetInitialized(void) {
        return _gFstorageInitialized;
    }
    
    bool fstorageGetEraseDone(void) {
        return _gFstorageEraseDone;
    }
    
    bool fstorageGetWriteDone(void) {
        return _gFstorageWriteDone;
    }
    
    bool fstorageGetPageDirty(void) {
        return _gFstoragePageDirty;
    }
    
    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 - FSTORAGE_PAGE_NUM * eraseUnit + 1; 
        } else {
            startAddr = bootloaderAddr - FSTORAGE_PAGE_NUM * eraseUnit + 1;
        }
    
        NRF_LOG_DEBUG("endAddr=0x%x", endAddr);
        NRF_LOG_DEBUG("startAddr=0x%x", startAddr);
        return startAddr;
    }
    
    fstorage_state_t fstorageGetState(void) {
        return _gFstorageState;
    }
    
    
    
    
    

Reply
  • 3782.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    1
    #define FSTORAGE_WAIT_CNT    1000
    
    static bool _gFstorageInitialized = false;
    static bool _gFstorageEraseDone   = true;
    static bool _gFstorageWriteDone   = true;
    static bool _gFstoragePageDirty   = true;
    static fstorage_state_t _gFstorageState = FSTORAGE_STATE_UNKNOWN;
    static uint8_t _gData[RECORD_LEN] = {0};
    
    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 _fstorageGetEndAddr() can be used to retrieve the last address on the
         * last page of flash available to write data. */
        .start_addr = 0x7F000,
        .end_addr   = 0x7FFFF,
    };
    
    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;
                _gFstorageState     = FSTORAGE_STATE_WRITTEN;
                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;
                _gFstorageState     = FSTORAGE_STATE_ERASED;
                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)-1);
    }
    
    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))
        while (!_gFstorageEraseDone || !_gFstorageWriteDone) {
            NRF_LOG_DEBUG("pm e\n");
            power_manage();
            NRF_LOG_DEBUG("pm x\n");
        }
    #endif
    		return 0;
        
    }
    
    int _fstorageRead(const uint32_t addr, const uint32_t len, uint8_t* data) {
        if (!_gFstorageInitialized) {
            return ERROR_FSTORAGE_UNINITIALIZED;
        }   
    
        NRF_LOG_DEBUG("nrf_fstorage_read() e\n");
        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;
        }
        NRF_LOG_DEBUG("nrf_fstorage_read() x\n");
    
        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;
        _gFstorageState     = FSTORAGE_STATE_WRITING;
        const uint32_t wlen = _fstorageRoundUpU32(len);
    
        NRF_LOG_DEBUG("nrf_fstorage_write() e\n");
        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;
        }
        NRF_LOG_DEBUG("nrf_fstorage_write() x\n");
       
        _fstorageWait(FSTORAGE_WAIT_CNT);
    
        return 0;
    }
    
    
    static void _fstoragePrintInfo(void) {
        NRF_LOG_INFO("========| flash info |========");
        NRF_LOG_INFO("erase unit:   %d bytes", _gFstorage.p_flash_info->erase_unit);
        NRF_LOG_INFO("program unit: %d bytes", _gFstorage.p_flash_info->program_unit);
        NRF_LOG_INFO("end address: 0x%x",      _fstorageGetEndAddr());
        NRF_LOG_INFO("==============================");
    }
    
    int fstorageInit(void) {
        // initializing variables
        _gFstorageInitialized = false;
        _gFstorageEraseDone   = true;
        _gFstorageWriteDone   = true;
        _gFstoragePageDirty   = true;
        _gFstorageState = FSTORAGE_STATE_UNKNOWN;
    
        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;
        }
    
        _fstoragePrintInfo();
        _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;
        _gFstorageState     = FSTORAGE_STATE_ERASING;
    
        NRF_LOG_WARNING("nrf_fstorage_erase() e\n");
        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;
        }
        NRF_LOG_WARNING("nrf_fstorage_erase() x\n");
    
        _fstorageWait(FSTORAGE_WAIT_CNT);
        
        return 0;
    }
    
    int fstorageReadRecord(const uint32_t addr, record_t* pRecord) {
        if (_fstorageRead(addr, RECORD_LEN, _gData) != 0) {
            return ERROR_FDS_READ_FAIL;
        }
    
        data2Record(_gData, 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, addr=0x%x\n", type, addr);
        const fstorage_state_t state = fstorageGetState();
        NRF_LOG_DEBUG("state=%d\n", state);
        switch (type) {
            case RECORD_DATA_TYPE_START:
            {  
                NRF_LOG_DEBUG("START E\n");
                if ((state == FSTORAGE_STATE_UNKNOWN)) {
                    fstorageErase(addr, 1);    
                } else if (state == FSTORAGE_STATE_ERASED) {    
                    record_t record;
                    record.offsetStart = norFlashGetStartOffset();
                    record.offsetEnd   = norFlashGetStartOffset();
                    nrf_cal_get_datetime(&record.timeStart);
                    nrf_cal_get_datetime(&record.timeEnd);
                    recordPrintRecord("record", &record);
                    fstorageWriteRecord(addr, &record);
                }    
                NRF_LOG_DEBUG("START x\n");
            }    
            break;
    
            case RECORD_DATA_TYPE_END:
            {
                NRF_LOG_DEBUG("END E\n");
                static record_t record;
    
                if ((state == FSTORAGE_STATE_UNKNOWN) || (state == FSTORAGE_STATE_WRITTEN)) {
                    if (fstorageReadRecord(addr, &record) != 0) {
                        NRF_LOG_WARNING("fstorageReadRecord(0x%x) failed\n", addr);
                        return ERROR_FSTORAGE_READ_FAIL;
                    }
                    recordPrintRecord("record r", &record);
                    fstorageErase(addr, 1);
                } else if (state == FSTORAGE_STATE_ERASED) {
                    record.offsetEnd = pRecord->offsetEnd;
                    record.timeEnd   = pRecord->timeEnd;
                    recordPrintRecord("record w", &record);
                    fstorageWriteRecord(addr, &record);
                }    
                NRF_LOG_DEBUG("END X");
            }   
            break;    
        }    
    
        return 0;
    }
    
    int fstorageWaitUpdateRecordFinish(void) {
        record_t record;
        record.offsetEnd   = norFlashGetWrittenOffset();
        nrf_cal_get_datetime(&record.timeEnd);
        if (fstorageUpdateRecord(RECORD_DATA_TYPE_END, &record) != 0) {
            NRF_LOG_WARNING("fstorageUpdateRecord(%d) failed\n", RECORD_DATA_TYPE_END);
            return ERROR_FSTORAGE_WRITE_FAIL;
        }    
        return 0;
    }
    
    
    int fstorageWriteRecord(const uint32_t addr, record_t* pRecord) {
        record2Data(pRecord, _gData);
        if (_fstorageWrite(addr, RECORD_LEN, _gData) != 0) {
            return ERROR_FSTORAGE_WRITE_FAIL;
        }
    
        return 0;
    }
    
    bool fstorageGetInitialized(void) {
        return _gFstorageInitialized;
    }
    
    bool fstorageGetEraseDone(void) {
        return _gFstorageEraseDone;
    }
    
    bool fstorageGetWriteDone(void) {
        return _gFstorageWriteDone;
    }
    
    bool fstorageGetPageDirty(void) {
        return _gFstoragePageDirty;
    }
    
    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 - FSTORAGE_PAGE_NUM * eraseUnit + 1; 
        } else {
            startAddr = bootloaderAddr - FSTORAGE_PAGE_NUM * eraseUnit + 1;
        }
    
        NRF_LOG_DEBUG("endAddr=0x%x", endAddr);
        NRF_LOG_DEBUG("startAddr=0x%x", startAddr);
        return startAddr;
    }
    
    fstorage_state_t fstorageGetState(void) {
        return _gFstorageState;
    }
    
    
    
    
    

Children
No Data
Related