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

Hardfault triggered after p nrf_fstorage_erase

Hi!

Writing to flash memory.

After calling nrf_fstorage_erase (...) a hardfault happens. It only NOT happens if JLink is enabled (using dbg or rtt logs).
So I can not debug it deeply. I did simple de-bug procedure, with LED flashing the number of cfsr_msgs[]. This number is 10,
meaning [10] = "Data bus error (return address in the stack frame is not related to the instruction that caused the error)".

Looks like the flash area is not erased as the result.

Looks like it happens not every time. I load the program into debugger (it works good), then I go out of the debugger session.
The program continues to run, and after 2 or 3 erase/write cycles it fails and calls for hardfault.

This piece of the program is taken from a working program, so looks like the problem depends on the code size, or RAM map, or
FLASH map. Can not understand.

I know this situation happens with NRF52832 not in first time, as there are some answers in this community already. But it does not help.

Anybody could help me?

Alex. 

Parents
  • Thank you for help.

    In sdk_config.h there are the following lines:

    // <i> NRF_FSTORAGE_SD uses the nrf_fstorage_sd backend implementation using the SoftDevice API. Use this if you have a SoftDevice present.
    // <i> NRF_FSTORAGE_NVMC uses the nrf_fstorage_nvmc implementation. Use this setting if you don't use the SoftDevice.
    // <1=> NRF_FSTORAGE_NVMC
    // <2=> NRF_FSTORAGE_SD

    #ifndef FDS_BACKEND
    #define FDS_BACKEND 2
    #endif

    So, I guess, I use NRF_FSTORAGE_SD

    Also, I write:
    #include "nrf_fstorage_sd.h"


    and here too:

    void fstorage_options_init(void)
    {
        uint32_t addr;
        nrf_fstorage_api_t * p_fs_api;
        ret_code_t ret_code;


        p_fs_api = &nrf_fstorage_sd;
        ret_code = nrf_fstorage_init(&fstorage_options, p_fs_api, NULL);
        APP_ERROR_CHECK(ret_code);

        print_flash_info(&fstorage_options);

    /* It is possible to set the start and end addresses of an fstorage instance at runtime.
    * They can be set multiple times, should it be needed. The helper function below can
    * be used to determine the last address on the last page of flash memory available to
    * store data. */
        addr = nrf5_flash_end_addr_get();
        NRF_LOG_INFO("FLASH end address: 0x%x", addr);


    }



  • Your fstorage_options has to be something like that.


    NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage_options) =
    {
        .evt_handler = fstorage_evt_handler,
        .start_addr  = DATA_START_ADDRESS,
        .end_addr    = DATA_END_ADDRESS
    };

    You have to take care in the region between [DATA_START_ADDRESS - DATA_END_ADDRESS] the application does not put anything.

    Maybe you can define an array of that size and mapp it through the Linker script in that region.

  •  After you trigger an Erase you have to wait until it is finished. Can you check if this is correct?

     
        while (nrf_fstorage_is_busy(&m_nvm))
        {
             (void) sd_app_evt_wait();
        }

    If this is not the case i dont it has to be something else which disturbs your erase operation.

  • Thank you for help.

    Yes, I did everything like it is done in different examples.
    The problem is that the program does not return from the very botom-level procedure, the queue-one. There is a queue of tasks in SoftDevice. So my program puts this task (ERASE) to the queue, and "asks" the queue to proceed this task. The queue does - it starts:

    /* 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;

    /* Put the operation on the queue. */
    (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);

    queue_start();

    Then I proceeded to
        queue_start();

    if ( (!nrf_atomic_flag_set_fetch(&m_flags.queue_running))
    && (!m_flags.paused))
    {
    queue_process();
    }

    Then to
        queue_process();

    switch (m_p_cur_op->op_code)
    {
    case NRF_FSTORAGE_OP_WRITE:
    rc = write_execute(m_p_cur_op);
    break;

    case NRF_FSTORAGE_OP_ERASE:
    rc = erase_execute(m_p_cur_op);
    LedRedOff ();
    break;

    default:
    rc = NRF_ERROR_INTERNAL;
    break;
    }

    Attention: I had added "LedRedOff();" after "erase_execute(...);"

    My procedure is

       rc = erase_execute(m_p_cur_op);

    I went into it. The procedure is simple:

    /* Erase flash page(s). */
    static uint32_t erase_execute(nrf_fstorage_sd_op_t const * p_op)
    {
    LedRedOn ();
    return sd_flash_page_erase(p_op->erase.page + p_op->erase.progress);
    }

    "LedRedOn();" is mine.

    So - this is the final point. The program switces on red led by "LedRedOn();", goes to "sd_flash_page_erase(p_op->erase.page + p_op->erase.progress);", and does not return. It never does "LedRedOff();"

    Here is "sd_flash_page_erase(...);"
    SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number));

    This must be SoftDevice call.

    What is strange: 1) Everything works if you use debugger or J-Link; 2) Nothing works in 4 locations. We tested this problem on 2 PCA10040 boards and on 2 boards, made by ours. The revisions of NRF52832 are also different (different silicon designs of the chips). 3) There is one more project, using NRF52832. It is much-much bigger. And - it works! We use same approaches in coding - but one project works, and second - does not.

    Looking forward for the help of Nordic Support Team!

  • Hello,

    Is it possible that the flash page you are attempting to erase may be protected by the BPROT module (Note: SDK bootloader does use BPROT to configure flash regions)? This protection is by default disabled in debug interface mode, so that would help explain why you don't see the hardfault when you're debugging.

  • Sorry. What is SDK bootloader? No, I didi not do the protection for any pages of flash. How to remove the protection, if it is switched on by default?

  • Can you read out the BPROT configuration registers to make sure flash protection is not enabled? The bootloader (BLE Secure DFU Bootloader) is an optional component you can program to add support for device firmware updates over BLE or a Serial interface.

Reply Children
Related