This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52832 Flash as EEPROM with ESB.

KeyWords: nRF52832  ESB  Flash as EEPROM  SDK:17.0.0

Hello, I an using nRF52832 developing ESB communicution with other nordic product.

I need to save some infomation, so used flash as eeprom, used the last page of flash: page_127 :


#define USER_CFG_ADDR_ST (127 * 4 * 1024)
#define USER_CFG_ADDR_SP (128 * 4 * 1024)

I used the following functions:

nrf_fstorage_init(&my_fs, p_fs_api, NULL);
    nrf_fstorage_erase(&my_fs, USER_CFG_ADDR_ST, 1, NULL);
            erase(nrf_fstorage_t const * p_fs, uint32_t page_addr, uint32_t len, void * p_param)
                queue_start();
                    queue_start();
                        queue_process();
                            rc = erase_execute(m_p_cur_op);

when the code run here (i debuged with log msg),can't continue run any more.

I don't know what's wrong, can any one tell me what should i do.

my email: [email protected]

Parents
  • Hi

    Have you gotten any error messages when trying to debug this issue? What IDE are you using for development and debugging? Have you made sure to add DEBUG to your preprocessor definitions in order to get all debugging messages?

    Best regards,

    Simon

  • Thanks for your replay!
    What IDE are you using for development and debugging?
    MDK5
    Have you made sure to add DEBUG to your preprocessor definitions in order to get all debugging messages?
    Yes.
    I have added macro "DEBUG" in "Preprocesson Symbols".
    I have set the debug level to "Debug" by nRF_Log module in file "sdk_config.h".
    Have you gotten any error messages when trying to debug this issue?
    In order to tracking where the error happend, i defined some macros for debugging:
    #define log_msg(x, ...)             LOG(x, ##__VA_ARGS__)
    #define log_error(x, ...)           LOG(x, ##__VA_ARGS__)
    this is what i got:
    next, please let me describe how i got that by the code flow:
    in main, initialized the fstorage, and read some user defined infomation.
    int main(void)
    {
        uint32_t err_code;
        
        err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        
        log_msg("\r\n\r\n");
        log_msg("\r\n    log is ready!\r\n");
        
        gpio_init();
        
        lfclk_config();
        rtc_config();
        clocks_start();
        
        user_cfg_fs_init();         // set nrf_fstorage_sd for api
        read_user_cfg_in_flash();
        
        ms_timer_init();
        //user_adc_init(0xFF, 1000);
        //user_iic_init(NRF_DRV_TWI_FREQ_100K, ARDUINO_SCL_PIN, ARDUINO_SDA_PIN);
        //user_spi_init();
        
        dev_init_common();
        dev_init();
        
        err_code = esb_init();
        APP_ERROR_CHECK(err_code);
        
        NRF_LOG_DEBUG("\r\n\r\nEnhanced ShockBurst Receiver Example started.");
        log_msg("record_cnt = %d(%08X)\r\n", Dev.user_flash.Pkg.record_cnt, Dev.user_flash.Pkg.record_cnt);
        
        err_code = nrf_esb_start_rx();
        APP_ERROR_CHECK(err_code);
        
        while(true)
        {
            update_status_by_rx_payload();
            
            dev_service_main();
            
            user_cfg_write_service();
            
            if(NRF_LOG_PROCESS() == false)
                __WFE();
        }
    }
    use nrf_fstorage_sd for fstorage api.
    void user_cfg_fs_init(void)
    {
        ret_code_t rc;
        
        nrf_fstorage_api_t *p_fs_api;
        p_fs_api = &nrf_fstorage_sd;
        
        //初始化FS
        rc = nrf_fstorage_init(&my_fs, p_fs_api, NULL);
        APP_ERROR_CHECK(rc);
    }
    read user infomation and check it, when first time read, the last page was erased to "FF", so when api check the read out value, will found the value is wrong. so need to save infomations to flash use "default" value.
    void read_user_cfg_in_flash(void)
    {
        static bool Flash_Cfg_Need_Save = false;
        
        uint32_t i;
        
        log_msg("\r\nread_user_cfg_in_flash:enter\r\n");
        log_msg("\r\nfrom 0x%08X read %d Byte to 0x%08X\r\n", USER_CFG_ADDR_ST, sizeof(UserFlashCfg_t), Dev.user_flash.Buf_U8);
        
        // 读取 Flash 内容
        nrf_fstorage_read(&my_fs, USER_CFG_ADDR_ST, (void *)Dev.user_flash.Buf_U8, sizeof(UserFlashCfg_t));
        
        log_msg("the_val_is:\r\n");
        for(i=0; i<sizeof(UserFlashCfg_t); i++)
        {
            log_msg("%02X ", Dev.user_flash.Buf_U8[i]);
        }
        
        log_msg("\r\n");
        log_msg("record_cnt = %08X(%d)\r\n", Dev.user_flash.Pkg.record_cnt, Dev.user_flash.Pkg.record_cnt);
        log_msg("dev_id = %02X(%d)\r\n", Dev.user_flash.Pkg.dev_id, Dev.user_flash.Pkg.dev_id);
        log_msg("report_freq = %02X(%d)(%d)\r\n", Dev.user_flash.Pkg.report_freq, Dev.user_flash.Pkg.report_freq, (1 << (4 + Dev.user_flash.Pkg.report_freq)));
        log_msg("rf_ch = %02X(%d)(2.4%dGHz)\r\n", Dev.user_flash.Pkg.rf_ch, Dev.user_flash.Pkg.rf_ch, (Dev.user_flash.Pkg.rf_ch / 10));
        log_msg("name_id = %02X(%d)\r\n", Dev.user_flash.Pkg.name_id, Dev.user_flash.Pkg.name_id);
        log_msg("amplify = %02X(%d)(%d)\r\n", Dev.user_flash.Pkg.amplify, Dev.user_flash.Pkg.amplify, (Dev.user_flash.Pkg.amplify * 500));
        log_msg("CompassCali_t = xyz=(%02X %02X %02X)(%d %d %d)\r\n",
                Dev.user_flash.Pkg.compass_cali.x,
                Dev.user_flash.Pkg.compass_cali.y,
                Dev.user_flash.Pkg.compass_cali.z,
                
                Dev.user_flash.Pkg.compass_cali.x,
                Dev.user_flash.Pkg.compass_cali.y,
                Dev.user_flash.Pkg.compass_cali.z);
        
        log_msg("\r\n");
        
        // 检查 dev_id
        if(! Check_DevID(Dev.user_flash.Pkg.dev_id))
        {
            Dev.user_flash.Pkg.dev_id = 0;
            Flash_Cfg_Need_Save = true;
        }
        
        // ...
        
        
        // 按需保存设备信息
        if(Flash_Cfg_Need_Save)
        {
            log_msg("save_cfg\r\n");
            
            Dev.user_flash.Pkg.record_cnt += 1;
            log_msg("record_cnt = %08X(%d)\r\n", Dev.user_flash.Pkg.record_cnt, Dev.user_flash.Pkg.record_cnt);
            
            user_cfg_write();
        }
    }
    then called function "user_cfg_write()"
    void user_cfg_write(void)
    {
        ret_code_t rc;
        
        log_msg("\r\nuser_cfg_write:enter\r\n");
        
        // erase page
        if(!my_fs_info.busy)
        {
            rc = 0;
            
            my_fs_info.busy = true;
            
            log_msg("user_cfg_write:nrf_fstorage_erase\r\n");
            
            // nrf_fstorage_erase(nrf_fstorage_t const *p_fs, uint32_t page_addr, uint32_t len, void *p_context)
            rc = nrf_fstorage_erase(&my_fs, USER_CFG_ADDR_ST, 1, NULL);
            APP_ERROR_CHECK(rc);
            //nrf_nvmc_page_erase(USER_CFG_ADDR_ST);
            
            //wait_for_flash_ready(&my_fs);
            //while(nrf_fstorage_is_busy(&my_fs))
            //    ;
            
            log_cfg("\r\nerase_cfg\r\n");
        }
        
        else
            log_cfg("\r\nerase_busy\r\n");
        
        log_msg("set_need_write_flag\r\n");
        
        // fill write parameter
        my_fs_info.need_write = true;
    }
    in order to save user config infomation to flash, first, I need to erase the user flash area (i used the last page of flash)
    // nRF52832 Flash 4 kByte per page
    #define USER_CFG_ADDR_ST       (127 * 4 * 1024) // user config infomation in flash Start Address
    #define USER_CFG_ADDR_SP       (128 * 4 * 1024) // user config infomation in flash End Address
    nrf_fstorage_erase
    ret_code_t nrf_fstorage_erase(nrf_fstorage_t const * p_fs,
                                  uint32_t               page_addr,
                                  uint32_t               len,
                                  void                 * p_context)
    {
        NRF_FSTORAGE_PARAM_CHECK(p_fs,        NRF_ERROR_NULL);
        NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
        NRF_FSTORAGE_PARAM_CHECK(len,         NRF_ERROR_INVALID_LENGTH);
    
        /* Address must be aligned to a page boundary. */
        NRF_FSTORAGE_PARAM_CHECK(addr_is_page_aligned(p_fs, page_addr), NRF_ERROR_INVALID_ADDR);
    
        NRF_FSTORAGE_PARAM_CHECK(
            addr_is_within_bounds(p_fs, page_addr, (len * p_fs->p_flash_info->erase_unit)),
            NRF_ERROR_INVALID_ADDR
        );
        
        log_msg("\r\nnrf_fstorage_erase:enter\r\n");
        log_msg("(p_fs->p_api)->erase\r\n");
        return (p_fs->p_api)->erase(p_fs, page_addr, len, p_context);
    }
    nrf_fstorage_sd.erase
    static ret_code_t erase(nrf_fstorage_t const * p_fs,
                            uint32_t               page_addr,
                            uint32_t               len,
                            void                 * p_param)
    {
        nrf_fstorage_sd_op_t  * p_op;
        nrf_atfifo_item_put_t   iput_ctx;
    
        log_msg("\r\nerase:enter\r\n");
        
        /* Get a free queue element. */
        p_op = nrf_atfifo_item_alloc(m_fifo, &iput_ctx);
    
        if (p_op == NULL)
        {
            log_error("erase:NRF_ERROR_NO_MEM\r\n");
            return NRF_ERROR_NO_MEM;
        }
    
        /* Initialize the operation. */
        memset(p_op, 0x00, sizeof(nrf_fstorage_sd_op_t));
    
        p_op->op_code              = NRF_FSTORAGE_OP_ERASE;
        p_op->p_fs                 = p_fs;
        p_op->p_param              = p_param;
        p_op->erase.page           = (page_addr / m_flash_info.erase_unit);
        p_op->erase.pages_to_erase = len;
        
        log_msg("erase:");
        log_msg("\r\n p_op->op_code = %d",              p_op->op_code);
        log_msg("\r\n p_op->p_fs = %08X(%d)",           (uint32_t)(p_op->p_fs), (uint32_t)(p_op->p_fs));
        log_msg("\r\n p_op->p_param = %08X(%d)",        (uint32_t)(p_op->p_param), (uint32_t)(p_op->p_param));
        log_msg("\r\n p_op->erase.page = %08X(%d)",     p_op->erase.page, p_op->erase.page);
        log_msg("\r\n p_op->pages_to_erase = %08X(%d)", p_op->erase.pages_to_erase, p_op->erase.pages_to_erase);
        log_msg("\r\n");
    
        /* Put the operation on the queue. */
        (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);
        
        log_msg("erase:queue_start\r\n");
        queue_start();
        
        log_msg("erase:NRF_SUCCESS\r\n");
        return NRF_SUCCESS;
    }
    queue_start
    /* Start processing the queue if it is not running and fstorage is not paused. */
    static void queue_start(void)
    {
        log_msg("\r\nqueue_start:enter\r\n");
        
        if (   (!nrf_atomic_flag_set_fetch(&m_flags.queue_running))
            && (!m_flags.paused))
        {
            queue_process();
        }
        else
            log_error("queue_start:not_enter_queue_process\r\n");
    }
    queue_process
    in this function, maybe some error happend here: rc = erase_execute(m_p_cur_op);
    when the code enter here, there is no log_msg any more, and code can't run any more.
    if i don't save infomation to my user flash area, i can see the code run correctly by a led blink and other log message. so, error happend here. but the source code of "erase_execute" is unviewable.
    /* Execute an operation in the queue. */
    static void queue_process(void)
    {
        uint32_t rc;
        
        log_msg("\r\nqueue_process:enter\r\n");
        
        if (m_flags.state == NRF_FSTORAGE_STATE_IDLE)
        {
            log_msg("queue_process:queue_load_next\r\n");
            
            if (!queue_load_next())
            {
                /* No more operations, nothing to do. */
                m_flags.queue_running = false;
                log_error("queue_process:queue_running_false\r\n");
                return;
            }
        }
        
        log_msg("queue_process:update_m_flags.state\r\n");
        m_flags.state = NRF_FSTORAGE_STATE_OP_EXECUTING;
    
        log_msg("queue_process:1 rc=%02X(%d)\r\n", rc, rc);
        
        log_msg("queue_process:switch (m_p_cur_op->op_code = %02X(%d))\r\n", m_p_cur_op->op_code, m_p_cur_op->op_code);
        switch (m_p_cur_op->op_code)
        {
            case NRF_FSTORAGE_OP_WRITE:
                log_msg("queue_process:NRF_FSTORAGE_OP_WRITE\r\n");
                rc = write_execute(m_p_cur_op);
                break;
    
            case NRF_FSTORAGE_OP_ERASE:
                log_msg("queue_process:NRF_FSTORAGE_OP_ERASE\r\n");
                log_msg("queue_process:page=%08X(%d) progress=%08X(%d)\r\n", m_p_cur_op->erase.page, m_p_cur_op->erase.page, m_p_cur_op->erase.progress, m_p_cur_op->erase.progress);
                rc = erase_execute(m_p_cur_op);
                break;
    
             default:
                log_msg("queue_process:rc = NRF_ERROR_INTERNAL\r\n");
                rc = NRF_ERROR_INTERNAL;
                break;
        }
        
        log_msg("queue_process:2 rc=%02X(%d)\r\n", rc, rc);
        
        log_msg("queue_process:switch (rc)\r\n");
        switch (rc)
        {
            case NRF_SUCCESS:
            {
                /* The operation was accepted by the SoftDevice.
                 * If the SoftDevice is enabled, wait for a system event. Otherwise,
                 * the SoftDevice call is synchronous and will not send an event so we simulate it. */
                if (!m_flags.sd_enabled)
                {
                    nrf_fstorage_sys_evt_handler(NRF_EVT_FLASH_OPERATION_SUCCESS, NULL);
                }
            } break;
    
            case NRF_ERROR_BUSY:
            {
                /* The SoftDevice is executing a flash operation that was not requested by fstorage.
                 * Stop processing the queue until a system event is received. */
                m_flags.state = NRF_FSTORAGE_STATE_OP_PENDING;
            } break;
    
            default:
            {
                /* An error has occurred. We cannot proceed further with this operation. */
                event_send(m_p_cur_op, NRF_ERROR_INTERNAL);
                /* Reset the internal state so we can accept other operations. */
                m_flags.state         = NRF_FSTORAGE_STATE_IDLE;
                m_flags.queue_running = false;
                /* Free the current queue element. */
                queue_free();
            } break;
        }
    }
    I don't know why some error happend.
    my project is based on "nRF5_SDK_17.0.0_9d13099\examples\proprietary_rf\esb_prx\pca10040\blank\arm5_no_packs"
    I changed the file sdk_config.h
    the whole sdk_config.h is here:
    if you can't visit it, please give me an email to  [email protected]
    Looking forward to your replay!

Reply
  • Thanks for your replay!
    What IDE are you using for development and debugging?
    MDK5
    Have you made sure to add DEBUG to your preprocessor definitions in order to get all debugging messages?
    Yes.
    I have added macro "DEBUG" in "Preprocesson Symbols".
    I have set the debug level to "Debug" by nRF_Log module in file "sdk_config.h".
    Have you gotten any error messages when trying to debug this issue?
    In order to tracking where the error happend, i defined some macros for debugging:
    #define log_msg(x, ...)             LOG(x, ##__VA_ARGS__)
    #define log_error(x, ...)           LOG(x, ##__VA_ARGS__)
    this is what i got:
    next, please let me describe how i got that by the code flow:
    in main, initialized the fstorage, and read some user defined infomation.
    int main(void)
    {
        uint32_t err_code;
        
        err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        
        log_msg("\r\n\r\n");
        log_msg("\r\n    log is ready!\r\n");
        
        gpio_init();
        
        lfclk_config();
        rtc_config();
        clocks_start();
        
        user_cfg_fs_init();         // set nrf_fstorage_sd for api
        read_user_cfg_in_flash();
        
        ms_timer_init();
        //user_adc_init(0xFF, 1000);
        //user_iic_init(NRF_DRV_TWI_FREQ_100K, ARDUINO_SCL_PIN, ARDUINO_SDA_PIN);
        //user_spi_init();
        
        dev_init_common();
        dev_init();
        
        err_code = esb_init();
        APP_ERROR_CHECK(err_code);
        
        NRF_LOG_DEBUG("\r\n\r\nEnhanced ShockBurst Receiver Example started.");
        log_msg("record_cnt = %d(%08X)\r\n", Dev.user_flash.Pkg.record_cnt, Dev.user_flash.Pkg.record_cnt);
        
        err_code = nrf_esb_start_rx();
        APP_ERROR_CHECK(err_code);
        
        while(true)
        {
            update_status_by_rx_payload();
            
            dev_service_main();
            
            user_cfg_write_service();
            
            if(NRF_LOG_PROCESS() == false)
                __WFE();
        }
    }
    use nrf_fstorage_sd for fstorage api.
    void user_cfg_fs_init(void)
    {
        ret_code_t rc;
        
        nrf_fstorage_api_t *p_fs_api;
        p_fs_api = &nrf_fstorage_sd;
        
        //初始化FS
        rc = nrf_fstorage_init(&my_fs, p_fs_api, NULL);
        APP_ERROR_CHECK(rc);
    }
    read user infomation and check it, when first time read, the last page was erased to "FF", so when api check the read out value, will found the value is wrong. so need to save infomations to flash use "default" value.
    void read_user_cfg_in_flash(void)
    {
        static bool Flash_Cfg_Need_Save = false;
        
        uint32_t i;
        
        log_msg("\r\nread_user_cfg_in_flash:enter\r\n");
        log_msg("\r\nfrom 0x%08X read %d Byte to 0x%08X\r\n", USER_CFG_ADDR_ST, sizeof(UserFlashCfg_t), Dev.user_flash.Buf_U8);
        
        // 读取 Flash 内容
        nrf_fstorage_read(&my_fs, USER_CFG_ADDR_ST, (void *)Dev.user_flash.Buf_U8, sizeof(UserFlashCfg_t));
        
        log_msg("the_val_is:\r\n");
        for(i=0; i<sizeof(UserFlashCfg_t); i++)
        {
            log_msg("%02X ", Dev.user_flash.Buf_U8[i]);
        }
        
        log_msg("\r\n");
        log_msg("record_cnt = %08X(%d)\r\n", Dev.user_flash.Pkg.record_cnt, Dev.user_flash.Pkg.record_cnt);
        log_msg("dev_id = %02X(%d)\r\n", Dev.user_flash.Pkg.dev_id, Dev.user_flash.Pkg.dev_id);
        log_msg("report_freq = %02X(%d)(%d)\r\n", Dev.user_flash.Pkg.report_freq, Dev.user_flash.Pkg.report_freq, (1 << (4 + Dev.user_flash.Pkg.report_freq)));
        log_msg("rf_ch = %02X(%d)(2.4%dGHz)\r\n", Dev.user_flash.Pkg.rf_ch, Dev.user_flash.Pkg.rf_ch, (Dev.user_flash.Pkg.rf_ch / 10));
        log_msg("name_id = %02X(%d)\r\n", Dev.user_flash.Pkg.name_id, Dev.user_flash.Pkg.name_id);
        log_msg("amplify = %02X(%d)(%d)\r\n", Dev.user_flash.Pkg.amplify, Dev.user_flash.Pkg.amplify, (Dev.user_flash.Pkg.amplify * 500));
        log_msg("CompassCali_t = xyz=(%02X %02X %02X)(%d %d %d)\r\n",
                Dev.user_flash.Pkg.compass_cali.x,
                Dev.user_flash.Pkg.compass_cali.y,
                Dev.user_flash.Pkg.compass_cali.z,
                
                Dev.user_flash.Pkg.compass_cali.x,
                Dev.user_flash.Pkg.compass_cali.y,
                Dev.user_flash.Pkg.compass_cali.z);
        
        log_msg("\r\n");
        
        // 检查 dev_id
        if(! Check_DevID(Dev.user_flash.Pkg.dev_id))
        {
            Dev.user_flash.Pkg.dev_id = 0;
            Flash_Cfg_Need_Save = true;
        }
        
        // ...
        
        
        // 按需保存设备信息
        if(Flash_Cfg_Need_Save)
        {
            log_msg("save_cfg\r\n");
            
            Dev.user_flash.Pkg.record_cnt += 1;
            log_msg("record_cnt = %08X(%d)\r\n", Dev.user_flash.Pkg.record_cnt, Dev.user_flash.Pkg.record_cnt);
            
            user_cfg_write();
        }
    }
    then called function "user_cfg_write()"
    void user_cfg_write(void)
    {
        ret_code_t rc;
        
        log_msg("\r\nuser_cfg_write:enter\r\n");
        
        // erase page
        if(!my_fs_info.busy)
        {
            rc = 0;
            
            my_fs_info.busy = true;
            
            log_msg("user_cfg_write:nrf_fstorage_erase\r\n");
            
            // nrf_fstorage_erase(nrf_fstorage_t const *p_fs, uint32_t page_addr, uint32_t len, void *p_context)
            rc = nrf_fstorage_erase(&my_fs, USER_CFG_ADDR_ST, 1, NULL);
            APP_ERROR_CHECK(rc);
            //nrf_nvmc_page_erase(USER_CFG_ADDR_ST);
            
            //wait_for_flash_ready(&my_fs);
            //while(nrf_fstorage_is_busy(&my_fs))
            //    ;
            
            log_cfg("\r\nerase_cfg\r\n");
        }
        
        else
            log_cfg("\r\nerase_busy\r\n");
        
        log_msg("set_need_write_flag\r\n");
        
        // fill write parameter
        my_fs_info.need_write = true;
    }
    in order to save user config infomation to flash, first, I need to erase the user flash area (i used the last page of flash)
    // nRF52832 Flash 4 kByte per page
    #define USER_CFG_ADDR_ST       (127 * 4 * 1024) // user config infomation in flash Start Address
    #define USER_CFG_ADDR_SP       (128 * 4 * 1024) // user config infomation in flash End Address
    nrf_fstorage_erase
    ret_code_t nrf_fstorage_erase(nrf_fstorage_t const * p_fs,
                                  uint32_t               page_addr,
                                  uint32_t               len,
                                  void                 * p_context)
    {
        NRF_FSTORAGE_PARAM_CHECK(p_fs,        NRF_ERROR_NULL);
        NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
        NRF_FSTORAGE_PARAM_CHECK(len,         NRF_ERROR_INVALID_LENGTH);
    
        /* Address must be aligned to a page boundary. */
        NRF_FSTORAGE_PARAM_CHECK(addr_is_page_aligned(p_fs, page_addr), NRF_ERROR_INVALID_ADDR);
    
        NRF_FSTORAGE_PARAM_CHECK(
            addr_is_within_bounds(p_fs, page_addr, (len * p_fs->p_flash_info->erase_unit)),
            NRF_ERROR_INVALID_ADDR
        );
        
        log_msg("\r\nnrf_fstorage_erase:enter\r\n");
        log_msg("(p_fs->p_api)->erase\r\n");
        return (p_fs->p_api)->erase(p_fs, page_addr, len, p_context);
    }
    nrf_fstorage_sd.erase
    static ret_code_t erase(nrf_fstorage_t const * p_fs,
                            uint32_t               page_addr,
                            uint32_t               len,
                            void                 * p_param)
    {
        nrf_fstorage_sd_op_t  * p_op;
        nrf_atfifo_item_put_t   iput_ctx;
    
        log_msg("\r\nerase:enter\r\n");
        
        /* Get a free queue element. */
        p_op = nrf_atfifo_item_alloc(m_fifo, &iput_ctx);
    
        if (p_op == NULL)
        {
            log_error("erase:NRF_ERROR_NO_MEM\r\n");
            return NRF_ERROR_NO_MEM;
        }
    
        /* Initialize the operation. */
        memset(p_op, 0x00, sizeof(nrf_fstorage_sd_op_t));
    
        p_op->op_code              = NRF_FSTORAGE_OP_ERASE;
        p_op->p_fs                 = p_fs;
        p_op->p_param              = p_param;
        p_op->erase.page           = (page_addr / m_flash_info.erase_unit);
        p_op->erase.pages_to_erase = len;
        
        log_msg("erase:");
        log_msg("\r\n p_op->op_code = %d",              p_op->op_code);
        log_msg("\r\n p_op->p_fs = %08X(%d)",           (uint32_t)(p_op->p_fs), (uint32_t)(p_op->p_fs));
        log_msg("\r\n p_op->p_param = %08X(%d)",        (uint32_t)(p_op->p_param), (uint32_t)(p_op->p_param));
        log_msg("\r\n p_op->erase.page = %08X(%d)",     p_op->erase.page, p_op->erase.page);
        log_msg("\r\n p_op->pages_to_erase = %08X(%d)", p_op->erase.pages_to_erase, p_op->erase.pages_to_erase);
        log_msg("\r\n");
    
        /* Put the operation on the queue. */
        (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);
        
        log_msg("erase:queue_start\r\n");
        queue_start();
        
        log_msg("erase:NRF_SUCCESS\r\n");
        return NRF_SUCCESS;
    }
    queue_start
    /* Start processing the queue if it is not running and fstorage is not paused. */
    static void queue_start(void)
    {
        log_msg("\r\nqueue_start:enter\r\n");
        
        if (   (!nrf_atomic_flag_set_fetch(&m_flags.queue_running))
            && (!m_flags.paused))
        {
            queue_process();
        }
        else
            log_error("queue_start:not_enter_queue_process\r\n");
    }
    queue_process
    in this function, maybe some error happend here: rc = erase_execute(m_p_cur_op);
    when the code enter here, there is no log_msg any more, and code can't run any more.
    if i don't save infomation to my user flash area, i can see the code run correctly by a led blink and other log message. so, error happend here. but the source code of "erase_execute" is unviewable.
    /* Execute an operation in the queue. */
    static void queue_process(void)
    {
        uint32_t rc;
        
        log_msg("\r\nqueue_process:enter\r\n");
        
        if (m_flags.state == NRF_FSTORAGE_STATE_IDLE)
        {
            log_msg("queue_process:queue_load_next\r\n");
            
            if (!queue_load_next())
            {
                /* No more operations, nothing to do. */
                m_flags.queue_running = false;
                log_error("queue_process:queue_running_false\r\n");
                return;
            }
        }
        
        log_msg("queue_process:update_m_flags.state\r\n");
        m_flags.state = NRF_FSTORAGE_STATE_OP_EXECUTING;
    
        log_msg("queue_process:1 rc=%02X(%d)\r\n", rc, rc);
        
        log_msg("queue_process:switch (m_p_cur_op->op_code = %02X(%d))\r\n", m_p_cur_op->op_code, m_p_cur_op->op_code);
        switch (m_p_cur_op->op_code)
        {
            case NRF_FSTORAGE_OP_WRITE:
                log_msg("queue_process:NRF_FSTORAGE_OP_WRITE\r\n");
                rc = write_execute(m_p_cur_op);
                break;
    
            case NRF_FSTORAGE_OP_ERASE:
                log_msg("queue_process:NRF_FSTORAGE_OP_ERASE\r\n");
                log_msg("queue_process:page=%08X(%d) progress=%08X(%d)\r\n", m_p_cur_op->erase.page, m_p_cur_op->erase.page, m_p_cur_op->erase.progress, m_p_cur_op->erase.progress);
                rc = erase_execute(m_p_cur_op);
                break;
    
             default:
                log_msg("queue_process:rc = NRF_ERROR_INTERNAL\r\n");
                rc = NRF_ERROR_INTERNAL;
                break;
        }
        
        log_msg("queue_process:2 rc=%02X(%d)\r\n", rc, rc);
        
        log_msg("queue_process:switch (rc)\r\n");
        switch (rc)
        {
            case NRF_SUCCESS:
            {
                /* The operation was accepted by the SoftDevice.
                 * If the SoftDevice is enabled, wait for a system event. Otherwise,
                 * the SoftDevice call is synchronous and will not send an event so we simulate it. */
                if (!m_flags.sd_enabled)
                {
                    nrf_fstorage_sys_evt_handler(NRF_EVT_FLASH_OPERATION_SUCCESS, NULL);
                }
            } break;
    
            case NRF_ERROR_BUSY:
            {
                /* The SoftDevice is executing a flash operation that was not requested by fstorage.
                 * Stop processing the queue until a system event is received. */
                m_flags.state = NRF_FSTORAGE_STATE_OP_PENDING;
            } break;
    
            default:
            {
                /* An error has occurred. We cannot proceed further with this operation. */
                event_send(m_p_cur_op, NRF_ERROR_INTERNAL);
                /* Reset the internal state so we can accept other operations. */
                m_flags.state         = NRF_FSTORAGE_STATE_IDLE;
                m_flags.queue_running = false;
                /* Free the current queue element. */
                queue_free();
            } break;
        }
    }
    I don't know why some error happend.
    my project is based on "nRF5_SDK_17.0.0_9d13099\examples\proprietary_rf\esb_prx\pca10040\blank\arm5_no_packs"
    I changed the file sdk_config.h
    the whole sdk_config.h is here:
    if you can't visit it, please give me an email to  [email protected]
    Looking forward to your replay!

Children
No Data
Related