This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Can not erase flash by nrf_fstorage_sd backend

I have a problom about using nrf_fstorage_erase won't call nrf_fstorage_sys_evt_handler.

The project is on nrf52832 and using SDK 15.3, Softdevice s132 6.1.1.
When I use nrf_fstorage_nvmc to be backend, everything is fine, but change backend to nrf_fstorage_sd, the erase seem like only finish 1page and never entery
nrf_fstorage_sys_evt_handler to trigger NRF_EVT_FLASH_OPERATION_SUCCESS or NRF_EVT_FLASH_OPERATION_ERROR.

I'm sure I include all file needed to be include, include nrf_sdh_soc.h and I also enable the softdevice by using nrf_sdh_enable_request.
The function which I used to erase flash is down below.

void MemoryOperation_Erase1(void)
{
	ret_code_t err_code;
	
	err_code = nrf_fstorage_erase(&m_fs, 0x71000, 2, NULL);
	if(err_code != NRF_SUCCESS)
	{
		NRF_LOG_ERROR("MemoryOperation_Erase1 Error : %d", err_code);
	}
	
	wait_for_flash_ready();
}

void MemoryOperation__Erase2(void)
{
	ret_code_t err_code;
	
	err_code = nrf_fstorage_erase(&m_fs, 0x73000, 11, NULL);
	if(err_code != NRF_SUCCESS)
	{
		NRF_LOG_ERROR("MemoryOperation__Erase2 Error : %d", err_code);
	}
	
	wait_for_flash_ready();
}

void wait_for_flash_ready(void)
{
    /* While fstorage is busy, sleep and wait for an event. */
    while (nrf_fstorage_is_busy(&m_fs))
    {
       sd_app_evt_wait();
    }
}

I also find a subject similar my problem : https://devzone.nordicsemi.com/f/nordic-q-a/63808/missing-softdevice-call-to-nrf_fstorage_sys_evt_handler

But I can't understand how to fix it.

Did I miss something to check?
if anyone know how to find the problem will be appreciated.

Many Thanks,
Marcus

Parents
  • Maybe it's something wrong with registering the softdevice observer which should be handled in top of nrf_fstorage_sd.h:

    /* Define a nrf_sdh_soc event observer to receive SoftDevice system events. */
    NRF_SDH_SOC_OBSERVER(m_sys_obs, 0, nrf_fstorage_sys_evt_handler, NULL);

    Maybe you are missing nrf_sdh_soc.c?

    Best regards,
    Kenneth

  • Hi Kenneth

    Thanks for your reply.

    Sorry, it's my fault.

    I test the example flash_fstorage with s132 and change the function nrf_fstorage_write to nrf_fstorage_erase, it works pretty good.So I compare all files include sdk_config.h, and I found that nRF_SoftDevice → NRF_SDH_ENABLE → Dispatch model → NRF_SDH_DISPATCH_MODEL need to be setting with NRF_SDH_DISPATCH_MODEL_INTERRUPT, not polling. And finally it works.

    But I have another qusetion that when I erase the address after 0x73000, either example or my application are not work. Is it because I have bootloader on 0x73000?
    How can softdevice know I have a bootloader in it?

    Many thanks,
    Marcus

  • Hi Marcus,

    Thanks for sharing the error.

    In terms of finding the end address, I suggest to do like FDS do it:

    static uint32_t flash_end_addr(void)
    {
        uint32_t const bootloader_addr = BOOTLOADER_ADDRESS;
        uint32_t const page_sz         = NRF_FICR->CODEPAGESIZE;
    
    #if defined(NRF52810_XXAA) || defined(NRF52811_XXAA)
        // Hardcode the number of flash pages, necessary for SoC emulation.
        // nRF52810 on nRF52832 and
        // nRF52811 on nRF52840
        uint32_t const code_sz = 48;
    #else
       uint32_t const code_sz = NRF_FICR->CODESIZE;
    #endif
    
        uint32_t end_addr = (bootloader_addr != 0xFFFFFFFF) ? bootloader_addr : (code_sz * page_sz);
    
        return end_addr - (FDS_PHY_PAGES_RESERVED * FDS_PHY_PAGE_SIZE * sizeof(uint32_t));
    }

    The BOOTLOADER_ADDRESS is defined in start of app_util.h as:

    #define BOOTLOADER_ADDRESS      ((*(uint32_t *)MBR_BOOTLOADER_ADDR) == 0xFFFFFFFF ? *MBR_UICR_BOOTLOADER_ADDR : *(uint32_t *)MBR_BOOTLOADER_ADDR) /**< The currently configured start address of the bootloader. If 0xFFFFFFFF, no bootloader start address is configured. */

    In case some pages are reserved by other modules, then FDS also have a reserved pages define:

    #define FDS_PHY_PAGES_RESERVED      ((FDS_VIRTUAL_PAGES_RESERVED * FDS_VIRTUAL_PAGE_SIZE) / FDS_PHY_PAGE_SIZE)

    Best regards,
    Kenneth

  • Hi Kenneth

    Thanks for your reply.

    My Bootloader is start at 0x73000.
    For some reason, I need to erase my bootloader and upgrade it, that why I asked how does softdevice know I have bootloader in it.
    And because the bootloader is build by my own, so it can not used DFU to upgrade it.

    Does there any way to pass or bypass the examine and let me can erase the bootloader?

    Many thanks,
    Marcus

  • Hi Kenneth

    Thanks for your reply and the documented you provide.

    Now the API can erase flash include the bootloader, but it still a little bit weird.
    When I used debug mode to check any wrong with erase process, everything is fine,
    the API can erase all address in flash include bootloader address 0x73000.
    But when I just download the program by using keil, it seems like never erase, the bootloader still in flash.

    What's different between debug mode and download program?
    should I check the any status before I erase?

    Many thanks,
    Marcus

Reply
  • Hi Kenneth

    Thanks for your reply and the documented you provide.

    Now the API can erase flash include the bootloader, but it still a little bit weird.
    When I used debug mode to check any wrong with erase process, everything is fine,
    the API can erase all address in flash include bootloader address 0x73000.
    But when I just download the program by using keil, it seems like never erase, the bootloader still in flash.

    What's different between debug mode and download program?
    should I check the any status before I erase?

    Many thanks,
    Marcus

Children
  • Hi Kenneth

    I think I found the reason that why I can not erase the address after 0x73000 where my bootloader start at.

    The problem is in my own bootloader. Before jump into application, the bootloader will call nrf_bootloader_flash_protect to protect the bootloader area, so when application wants to erase bootloader, it trigger the cpu hardfault and the erase was failed of course.
    And because using debug tool will let DISABLEINDEBUG register disable the protect, that's also why
    I can erase the bootloader when using debug mode on application.

    Many thanks,
    Marcus

Related