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

  • 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

  • But when a tries to run the same code compiled for the S140 on the nRF52840, the function call stuck in the handler.

    I haven't found anything similar yet.  Are you certain you are writing to the correct flash area?

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

    It's a little difficult to tell what can cause this. What parameters are you sending the sd_flash_write function? Could you please provide me a list of all parameters you are passing to the sd_flash_write function before the hard fault occurs?

    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.

    Fully understandable but if you are writing to the wrong memory section, you might have to rewrite your library. 

    Thank you!

    Kind regards,
    Øyvind

  • From the SoftDevice documentation for sd_flash_write()

    Flash Write.
    
    Commands to write a buffer to flash
    
    If the SoftDevice is enabled: This call initiates the flash access command, and its completion will be communicated to the application with exactly one of the following events:
    
    NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
    NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
    If the SoftDevice is not enabled no event will be generated, and this call will return NRF_SUCCESS when the write has been completed
    
    Note
    This call takes control over the radio and the CPU during flash erase and write to make sure that they will not interfere with the flash access. This means that all interrupts will be blocked for a predictable time (depending on the NVMC specification in the device's Product Specification and the command parameters).
    The data in the p_src buffer should not be modified before the NRF_EVT_FLASH_OPERATION_SUCCESS or the NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled.
    This call will make the SoftDevice trigger a hardfault when the page is written, if it is protected.

    But if the softdevice was never enbled, the function is perfectly working.

     As you can see, the SD will return NRF_SUCCESS when not enabled.

  • 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;
    	}

Related