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.

  • Yes. The case was in BPROT register. After moving my flash page to other address - it works finally.

    Many thanks.

    p.s. How to configure that BPROT?

  • As mentioned in the BPROT chapter, all the protection bits are cleared after a reset. This means that there must be something in your device FW that sets the protection bits (assuming they were set).

    What was the address of the flash page you tried to erase earlier?

  • I was trying to erase 0x6d000 flash page, one page. BPROT bit was set for this page, so it called for a hardfault event.

    After sliding to 0x70000 address the problem was gone.

    You tell - the SW sets this bits? All right, will read more about this feature.

    Great help!

    Thanks a lot!

    Alex.

  • Hello Vidar.

    Still has question about BPROT: I never set the bits of this register, and I do not need it - but almost all flash memory is protected against writing/erasing pages. All, except small region,  blocks 115-119. May be - debugger needs it. But - who switches on the protection of all the rest?

  • o.k.

    As we use Keil IDE, there is a window there, with ROM areas mapping.

    I just excluded the area, I want to erase, from ROM map - and Keil now is not setting NO bits at all in BPROT register.


    My ROM area, I want to erase, is one page long, and starts from 0x6D000 address.

    I can do it myself, instead - I mean - switch on all ROM pages protection, I want.

    I guess, at this point, the ticket can be closed.

    Thanks everybody!

Reply Children
  • It's good that you found a workaround, but I really don't see how the linker configuration could affect the BPROT settings when you don't have anything in your application code that accesses the BPROT registers.

    Have you checked if the protection bits get set if you run any of the other SDK examples?

  • Hello.

    Doing the checks now. Yes, the information is contradictory.

    The program works. Sometimes. Sometimes - does not.

    The program starts to execute from the address 0xA80
    Then it jumps somewhere (I guess this is SoftDevice procedures)
    Then returns, and jumps to the address 0x783D4. Is that Bootloader? Do not know.
    But, in this code, the program sets BPROT register in different ways.
    Sometimes all CONFIGx registers of BPROT are set as 0xFFFFFFFF
    Sometimes - the area from 0x73000 to 0x78000 are set as Not-protected.
    Sometimes this area expands from 0x71000
    Sometimes from 0x70000
    Sometimes nothing is protected at all

    What is program doing there? How to manage that BPROT bits? Still not clear.

    I thought at the beginning, that if I define 

    NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage_options) =
    {
    /* Set a handler for fstorage events. */
    .evt_handler = fstorage_evt_handler_options,

    /* 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 = WORK_FLASH_DATA_ADDR,
    .end_addr = WORK_FLASH_DATA_END,
    };

    this area will stay unprotected. I was wrong.

    In few words: 1) I do not switch on the protection 2) who does it - I can not understand 3) How to overcome it - I can not understand 4) Why our main project still works - I can not understand

     


  • 0x71000 and 0x78000 are both common start addresses for the bootloader. Could you please check if you have anything at these addresses? You can use the programmer app in nRF connect for this.

    Memory layout read from nRF52832 with the Programmer app

  • nRF_Connect_Programmer_1629478104493.hex

    Do not know about NRF Connect, but if to load my Application.hex file into J-Flash program - it shows, that only the region 0x26000 to 0x6EFFF is occupied

  • All right. Looks like there was some mess with the Soft Device and the Bootloader from the previous runs of the program on this device.

    1) I got to J-Flash, and program Application_complete.hex file into my NRF52832. Application_complete.hex is a merged file of s132_nrf52_7.0.1_softdevice.hex + Application.hex + Bootloader.hex + settings_application.hex. This file does not work properly.

    2) I go to Keil IDE, load the project. which generates Application.hex, and start it in Debug mode. It sometimes work, sometimes not. Note: I have NOT erased Whole chip after J-Link session. So the chip has s132_nrf52_7.0.1_softdevice.hex, Bootloader.hex and  settings_application.hex inside.

    3) I go to J-Flash again, make Whole Chip Erase, load ONLY s132_nrf52_7.0.1_softdevice.hex. Return to Keil, and everything looks like working fine. No Bootloader there. No settings_application.hex.

    Why? Why if not to erase Whole Chip, and not to re-load s132_nrf52_7.0.1_softdevice.hex - why it goes to Bootloader portion of ROM? Is that normal?

    4) I am not sure, that if my Application works fine without Bootloader - it will work good WITH bootloader. I will check it tomorrow or on Monday. Why Bootloader cares about BPROT register?

    Attached is the file, read from the chip with "fresh" softdevice and containing no Bootloader.nRF_Connect_Programmer_1629479650636(No Bootloader).hex

Related