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

sd_flash_write HardFault when softdevice is enbled

Hi,

I'm currently in trouble with the sd_flash_write function. I've already a library using this function running on the nRF52832 with the S132 softdevice. But when a tries to run the same code compiled for the S140 softdevice on the nRF52840, the function call get stuck in the hardfault handler.

I use the SDK version 15.2.0

If the softdevice is enabled, the hardfault always occurs at the address 0x24ADC and with the PC = 0x14a3a. But if the softdevice was never enbled, the function is perfectly working.

Do you have an idea why the function break the softdevice ?

I know the there are some other smart functons to manage the memory but I aready have an optimized library for the memory managment using the sd_flash_write function and sd_flash_page_erase.I don't want to redo all my library.

Regards

Parents
  • Hello, 

    Can you please provide the whole error message you receive? 

    Have you tried to do run 

    nrfjprog - e
     and then reprogram?

    Kind regards,
    Øyvind

  • I already tries the nrfjprog -e and the nrfjprog --recover

    There is no error msg, I have just the break point in the app_error_fault_handler with id = 1; pc = 0x14a3a and info = 0

    Can you tell me what is the corresponding problem in the softdevice ?

    Thanks

  • This is my Flash erase and write functions :

    uint32_t BLE_SoftDeviceFlashErase(uint32_t page_number) {
    	uint32_t error;
    	flashDone = 0;
    	if (bleStatus == BLE_UNINITIALIZED) {
    		error = sd_flash_page_erase(page_number);
    		return error;
    	}
    
    	error = sd_flash_page_erase(page_number);
    	if (error == NRF_SUCCESS) {
    		while (!flashDone);
    	}
    
    	return error;
    }
    
    
    uint32_t BLE_SoftDeviceFlashWrite(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size) {
    	uint32_t error;
    	flashDone = 0;
    	if (bleStatus == BLE_UNINITIALIZED) {
    		error = sd_flash_write((uint32_t *) p_dst, p_src, size);
    		return error;
    	}
    
    	error = sd_flash_write((uint32_t *) p_dst, p_src, size);
    	if (error == NRF_SUCCESS) {
    		while (!flashDone);
    	}
    	
    	return error;
    }

    and I catches the done event with these functions :

    void ble_stack_init(void) {
    	ret_code_t err_code;
    
    	err_code = nrf_sdh_enable_request();
    	APP_ERROR_CHECK(err_code);
    
    	// Configure the BLE stack using the default settings.
    	// Fetch the start address of the application RAM.
    	uint32_t ram_start = 0;
    	err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    	APP_ERROR_CHECK(err_code);
    
    	// Enable BLE stack.
    	err_code = nrf_sdh_ble_enable(&ram_start);
    	APP_ERROR_CHECK(err_code);
    
    	// Register a handler for BLE events.
    	NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    	NRF_SDH_SOC_OBSERVER(m_soc_observer, APP_SOC_OBSERVER_PRIO, soc_evt_handler, NULL);
    }
    
    void soc_evt_handler(uint32_t sys_evt, void * p_context) {
        if (sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS) {
        	flashDone = 1;
        }
    }

    My flash library calls the flash functions with pageAddr = 0x80000 and PAGE_SIZE_WORD = 1024 (pageBuffer isn't modified durring the write) :

    // Erase the Page
    	error = BLE_SoftDeviceFlashErase(pageAddr/(uint16_t)NRF_FICR->CODEPAGESIZE);
    	if (error != NRF_SUCCESS) {
    		internalFlashStatus = INTERNAL_FLASH_STATE_ERROR;
    		return;
    	}
    
        // Write new Page
    	error = BLE_SoftDeviceFlashWrite((uint32_t *) pageAddr, pageBuffer, PAGE_SIZE_WORD);
    	if (error != NRF_SUCCESS) {
    		internalFlashStatus = INTERNAL_FLASH_STATE_ERROR;
    		return;
    	}

  • Thanks for the information! According to the PC, you are asserting due to advertising while writing to flash.

    I see that you have tried to cover events from flash writing with soc_evt_handler(). Please make sure that you start and stop advertisement when writing to flash and that you receive the event NRF_EVT_FLASH_OPERATION_SUCCESS before advertising. 

  • I tried to run my test flash code without calling the ble_advertising_init function but the problem still occur with the same PC

    Also I don't find a function to stop the advertising in the ble_advertising.h file. there is only the start function : ble_advertising_start

  • Can you please send me your code? 

    What version of the SoftDevice are you using? 

  • I'm using the sdk v15.2.0 but i tried the v15.3.0 and the problem still occur.

    I can't upload the archive of my project, an error occur when I try to upload my zip file. it's an eclipse project with a custom makefile. have you an email address where I can send the zip archive ?

    I also checked the ACL module status registers before the flash writing and the flash isn't protected.

Reply Children
  • Francois Mazard said:
    can't upload the archive of my project, an error occur when I try to upload my zip file. it's an eclipse project with a custom makefile.

     How big is the .zip file? It may be too large to upload. Try to delete build artifacts from the .zip file and try again.

     Our policy does not allow support customers to send email directly. It has to go through DevZone, or you have to add it to some sort of filesharing e.g. Box, DropBox etc.

    -Øyvind

  • how much is the maximum size allowed ?

    In my archive, I have included the sdk for an easier compilation. I removed it but you'll need to add it manually in the nRF5_SDK/nrf5_SDK_15.2.0 folder

    TestFlash.zip

  • Francois Mazard said:
    how much is the maximum size allowed ?

     I don't have a clear number, but I believe about 30-50MB is the limit. 
    Edit: According to the admin of DevZone, it should be able to handle up to 1GB. Unfortunately, we are having some stability issues which causes errors sporadically in regards to file transfer.

    Francois Mazard said:
    In my archive, I have included the sdk for an easier compilation

    This would explain the reason for the error.  A full SDK is about 500MB.

     

    Francois Mazard said:
    I removed it but you'll need to add it manually in the nRF5_SDK/nrf5_SDK_15.2.0 folder

     I was able to add all the missing files and got your code running. I was also able to reproduce the error but was not able to find the source of the error. The Hard Fault Assertion is due to flash writing, and it is taking too much time while something in the SoftDevice needs resources. I am discussing the issue with my colleagues and will get back to you. 

    I tried to run my test flash code without calling the ble_advertising_init function but the problem still occur with the same PC

    We see the same issue. And the ble_advertising_init() function does not start advertising, we cannot clearly see what is causing the assertion. But it does assert in the BLE_SoftDeviceFlashWrite() function. While waiting, please debug the BLE_SoftDeviceFlashWrite() function. 

    Thanks!

  • Ok, I'll continue to investigate on my side.

    Anyway, do you have a reference code for the sd_flash_write usage with the softdevice enbled ? If Yes can you sent it to me, It will be usefull for the debugging

    Thanks

  • Francois Mazard said:
    Ok, I'll continue to investigate on my side.

     Great, thank you!

    Francois Mazard said:
    Anyway, do you have a reference code for the sd_flash_write usage with the softdevice enbled

    The only example I could find was in the ANT Bootloader example (\examples\dfu\experimental\ant_bootloader\).

    volatile uint8_t mb_flash_busy = false;
    /*
     * sd_flash_page_erase() and sd_flash_write() generates an event at SD_EVT_IRQHandler
     * Please include run this function inside SD_EVT_IRQHandler
     *
     */
    void ant_boot_settings_sys_event_handler(uint32_t sys_evt, void * p_context)
    {
        if ((sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS) || (sys_evt == NRF_EVT_FLASH_OPERATION_ERROR))
        {
            mb_flash_busy = false;
        }
    }

    uint32_t ant_boot_settings_save(ant_boot_settings_t * boot_settings)
    {
        ret_code_t err_code = NRF_SUCCESS;
    
        mb_flash_busy = true;
        err_code      = sd_flash_write((uint32_t *) ANT_BOOT_SETTINGS_LOCATION,
                                       (uint32_t*)boot_settings,
                                        ANT_BOOT_SETTINGS_SIZE / 4);
        if (err_code == NRF_SUCCESS)
        {
            while (mb_flash_busy); // wait until it is done
        }
        else
        {
            return err_code;
        }
    
        return err_code;
    }

    uint32_t ant_boot_settings_clear(ant_boot_settings_t * boot_settings)
    {
        ret_code_t err_code = NRF_SUCCESS;
    
        // Clears \ presets the bootloader_settings memory
        memset(boot_settings, 0xFF, sizeof(ant_boot_settings_t));
    
        // Erases entire bootloader_settings in flash
        mb_flash_busy = true;
        err_code      = sd_flash_page_erase(FLASH_LAST_PAGE); // last flash page
        if (err_code == NRF_SUCCESS)
        {
            while (mb_flash_busy); // wait until it is done
        }
        else
        {
            return err_code;
        }
    
        return err_code;
    }


    I hope this is of any help to you. 

    Kind regards,
    Øyvind

Related