Unable to write to flash memory using direct memory access functions like sd_flash_page_erase & sd_flash_write (nrf52840 nrf SDK 17.1.0)

    // Register the event handler using the NRF_SDH_SOC_OBSERVER macro
    NRF_SDH_SOC_OBSERVER(m_sys_evt_observer, 0, sys_evt_dispatch, NULL);
    
    // Event handler function prototype
void sys_evt_dispatch(uint32_t sys_evt, void * p_context) {
    // Your system event handling code here
    // For example, handle the flashBusy flag or other system events
    ilumi_debug("System event : %d\r\n",sys_evt);
    if (sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS){
    	ilumi_debug("NV op ok\r\n");
    	setFlashIdle(1);
    }else if (sys_evt == NRF_EVT_FLASH_OPERATION_ERROR){
    	// will get flash op error if too much command, will investigate later
    	ilumi_debug("NV op fail\r\n");
    	setFlashIdle(0);
    }
}

//--------------------------------------------------------------------------------------------------//
ret_code_t disable_soft_device(void){
    ret_code_t error_code = sd_softdevice_disable();
    if (error_code != NRF_SUCCESS  && error_code != NRF_ERROR_INVALID_STATE) {
        ilumi_log("Failed to disable SoftDevice: 0x%x\r\n", error_code);
        return 0;
    }
    return 1;
}

ret_code_t enable_soft_device(void){
    nrf_clock_lf_cfg_t const clock_lf_cfg =
    {
        .source       = NRF_SDH_CLOCK_LF_SRC,
        .rc_ctiv      = NRF_SDH_CLOCK_LF_RC_CTIV,
        .rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
        .accuracy     = NRF_SDH_CLOCK_LF_ACCURACY
    };
    ret_code_t error_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);
    if (error_code != NRF_SUCCESS  && error_code != NRF_ERROR_INVALID_STATE) {
        ilumi_log("Failed to enable SoftDevice: 0x%x\r\n", error_code);
        return 0;
    }
    return 1;
}

//----------------------------------------------------------------------------------------------//
    #define FLASH_PAGE_VALID             ((uint32_t) 0xAABBCCEE)
    #define  USER_FLASH_START_ADDRESS    0x000FF000 //also tried fd0000, fe000
    #define  USER_FLASH_SIZE      	         0x1000


#define FLASH_RETRY_TIMES               	(8)
static volatile uint8_t flash_error = 0;
static volatile uint8_t flashBusy 	= 0;
extern ret_code_t enable_soft_device(void);
extern ret_code_t disable_soft_device(void);
void flashErasePage(uint8_t * addr){
	uint32_t error_code;
    disable_soft_device();
	// uint32_t page_number = (uint32_t)addr >> 12; //nRF52 page size is 4096Byte
    uint32_t page_number = (uint32_t)addr / USER_FLASH_SIZE;
    ilumi_log("page number: %d\r\n",page_number);
	int8_t retry = FLASH_RETRY_TIMES;
	retry_flash_op:
		while((error_code = sd_flash_page_erase(page_number))  == NRF_ERROR_BUSY); //if busy keeps trying, is this efficient?
		// error_code = sd_flash_write( (uint32_t*) addr, buffer_ptr, word_len))
        if(error_code == NRF_SUCCESS){
			// this SUCCNSS just means that the erase command have been accpected by stack, we need to wait for erase finish
			flashBusy = 1;
		    while(flashBusy) (void) sd_app_evt_wait();
		    if(flash_error){
		    	flash_error = 0;
		    	retry--;
		    	if(retry){
		    		goto retry_flash_op;
		    	}else{
		    		ilumi_log("nv page erase retry fail");
		    	}
		    }
//		    LOG_INFO("nv page erase OK, addr=0x%x", addr);
		}else{
	        ilumi_log("nv page erase cmd reject, err:0x%x addr=0x%x", error_code, addr);
		}
}

int8_t flashWrite( uint8_t *addr, uint16_t len, uint8_t *buf ){
	uint32_t error_code;
	uint32_t word_len;
    //uint32_t * buffer_ptr = NULL;		// buf address could be not WORD-aligned need to create a buffer for it
    int8_t ret = 0;

	if(len == 0) return -1;

	if((len & 0x3) == 0){				// len has to be divide by 4 because flash is WORD-aligned
		word_len = len >> 2; 			// word size is 4x the len
	}else{
		word_len = (len >> 2) + 1;
	}

	uint32_t buffer_ptr[word_len];
	//if((buffer_ptr = (uint32_t*)malloc(word_len<<2)))
	{
		memcpy(buffer_ptr, buf, word_len<<2);
        disable_soft_device();
        int8_t retry = FLASH_RETRY_TIMES;
retry_flash_op :
		while((error_code = sd_flash_write( (uint32_t*) addr, buffer_ptr, word_len)) == NRF_ERROR_BUSY);	//sd_flash_write size 32bit word size, addr must be word aligned
        if(error_code != NRF_SUCCESS){
            ret = -1;
			ilumi_log("sd nv write fail, err=0x%x addr=0x%x len=0x%x wordlen=0x%x srcaddr=0x%x", error_code, addr, len, word_len, buf);
		}else{
			flashBusy = 1;
		    while (flashBusy) (void) sd_app_evt_wait();
		    if(flash_error){
		    	flash_error = 0;
		    	retry--;
		    	if(retry){
		    		goto retry_flash_op;
		    	}else{
                    ret = -1;
		    		ilumi_log("sd nv write retry fail");
		    	}
		    }
//			NRF_LOG_INFO("sd nv write OK, addr=0x%x len=0x%x wordlen=0x%x", addr, len, word_len);
		}
	}
    return ret;
}

void setFlashIdle(uint8_t is_flash_op_success){
	// previously this is a potential bug becasue no matter what value in is_flash_op_success,
	// this function will set flashBusy to idle, while for NRF51 is_flash_op_success is not being used
	// following path should fix the problem
	flashBusy = 0;
	if(is_flash_op_success == 1) flash_error = 0;
	else flash_error = 1;
	enable_soft_device();
}

/*********************************************************************
 * Save user data to NV
 * @param addr  addr pointer of area
 * @param data  data buffer point
 * @param length  length of data buffer
 * @param flash_page_size
 */
void update_nv_data(uint16_t length, uint8_t* data, uint8_t * addr, uint16_t flash_page_size) {
    uint32_t signature;
    int8_t ret;

    if (length > flash_page_size) {
        ilumi_log("data size > NV page size\r\n", flash_page_size, addr);
        return;
    }

    // Get the current signature from the flash address
    signature = *((uint32_t*) addr); // get 32bit signature

    // If the current flash sector is valid, erase it first
    if (FLASH_PAGE_VALID == signature) {
        flashErasePage(addr);
    }

    // Write the updated data to the flash
    ret = flashWrite(addr, length, data);

    // If flashWrite failed, invalidate the current flash sector by setting the signature to 0
    if (0 != ret) {
        signature = 0x00;
        flashErasePage(addr); // Always erase first
        flashWrite(addr, sizeof(signature), (uint8_t *)&signature); // Write this last
    }
}

/*********************************************************************
 * clear the backup flags to user data to NV
 * @param length    length of data buffer
 * @param data      data buffer pointer
 * @param offset    offset to the data struct
 * @param addr      addr pointer of area
 * @param flash_page_size
 */
void clear_reset_flag_data(uint16_t length, uint8_t* data, uint32_t offset, uint8_t * addr, uint16_t flash_page_size) {
    uint32_t signature;

    if (length > flash_page_size) {
        ilumi_log("data size > NV page size\r\n", flash_page_size, addr);
        return;
    }

    // Get the current signature from the flash address
    signature = *((uint32_t*) addr); // get 32bit signature

    // Write the updated flag to the flash if the current page is valid
    if (FLASH_PAGE_VALID == signature) {
        flashWrite(addr + offset, length, data);
    }
}

/*
 * if not valid data, return 0;
 */
uint8_t load_nv_data(uint16_t length, uint8_t* data, uint8_t * addr, uint16_t flash_page_size) {
    uint32_t signature;

    // Log the NV loading attempt
    ilumi_log("load NV addr: 0x%x, page size: %d\r\n", addr, flash_page_size);

    if (length > flash_page_size) {
        ilumi_log("len: %d exceed pg size\r\n", length);
        return 0;
    }

    // Get the current signature from the flash address
    signature = *((uint32_t*) addr); // get 32bit signature
    ilumi_log("signature : 0x%x\r\n",signature);
    // Load from the valid segment
    if (FLASH_PAGE_VALID == signature) {
        ilumi_log("user data load ok\r\n");
        memcpy(data, addr, length);
    } else {
        ilumi_log("addr bad\r\n");
        return 0;
    }

    return 1;
}
 
void clear_nv_data(uint8_t * addr) {
    flashErasePage(addr);
}
<!DOCTYPE Linker_Placement_File>
<Root name="Flash Section Placement">
  <MemorySegment name="FLASH1" start="$(FLASH_PH_START)" size="$(FLASH_PH_SIZE)">
    <ProgramSection load="no" name=".reserved_flash" start="$(FLASH_PH_START)" size="$(FLASH_START)-$(FLASH_PH_START)" />
    <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START)" />
    <ProgramSection alignment="4" load="Yes" name=".init" />
    <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
    <ProgramSection alignment="4" load="Yes" name=".text"  />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".crypto_data" inputsections="*(SORT(.crypto_data*))" address_symbol="__start_crypto_data" end_symbol="__stop_crypto_data" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_queue" inputsections="*(.nrf_queue*)" address_symbol="__start_nrf_queue" end_symbol="__stop_nrf_queue" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".dfu_trans" inputsections="*(SORT(.dfu_trans*))" address_symbol="__start_dfu_trans" end_symbol="__stop_dfu_trans" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".svc_data" inputsections="*(.svc_data*)" address_symbol="__start_svc_data" end_symbol="__stop_svc_data" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_const_data" inputsections="*(SORT(.log_const_data*))" address_symbol="__start_log_const_data" end_symbol="__stop_log_const_data" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_balloc" inputsections="*(.nrf_balloc*)" address_symbol="__start_nrf_balloc" end_symbol="__stop_nrf_balloc" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_ble_observers" inputsections="*(SORT(.sdh_ble_observers*))" address_symbol="__start_sdh_ble_observers" end_symbol="__stop_sdh_ble_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_backends" inputsections="*(SORT(.log_backends*))" address_symbol="__start_log_backends" end_symbol="__stop_log_backends" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_req_observers" inputsections="*(SORT(.sdh_req_observers*))" address_symbol="__start_sdh_req_observers" end_symbol="__stop_sdh_req_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_state_observers" inputsections="*(SORT(.sdh_state_observers*))" address_symbol="__start_sdh_state_observers" end_symbol="__stop_sdh_state_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_stack_observers" inputsections="*(SORT(.sdh_stack_observers*))" address_symbol="__start_sdh_stack_observers" end_symbol="__stop_sdh_stack_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_soc_observers" inputsections="*(SORT(.sdh_soc_observers*))" address_symbol="__start_sdh_soc_observers" end_symbol="__stop_sdh_soc_observers" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections" address_symbol="__start_nrf_sections" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_dynamic_data"  inputsections="*(SORT(.log_dynamic_data*))" runin=".log_dynamic_data_run"/>
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_filter_data"  inputsections="*(SORT(.log_filter_data*))" runin=".log_filter_data_run"/>
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".fs_data"  inputsections="*(.fs_data*)" runin=".fs_data_run"/>
    <ProgramSection alignment="4" load="Yes" name=".dtors" />
    <ProgramSection alignment="4" load="Yes" name=".ctors" />
    <ProgramSection alignment="4" load="Yes" name=".rodata"  />
    <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
    <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
    <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
    <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".mbr_params_page" address_symbol="__start_mbr_params_page" end_symbol="__stop_mbr_params_page" start = "0x000FE000" size="0x1000" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".bootloader_settings_page" address_symbol="__start_bootloader_settings_page" end_symbol="__stop_bootloader_settings_page" start = "0x000FF000" size="0x1000" />
  </MemorySegment>
  <MemorySegment name="RAM1" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">
    <ProgramSection load="no" name=".reserved_ram" start="$(RAM_PH_START)" size="$(RAM_START)-$(RAM_PH_START)" />
    <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START)" address_symbol="__app_ram_start__"/>
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run" address_symbol="__start_nrf_sections_run" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".log_dynamic_data_run" address_symbol="__start_log_dynamic_data" end_symbol="__stop_log_dynamic_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".log_filter_data_run" address_symbol="__start_log_filter_data" end_symbol="__stop_log_filter_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run_end" address_symbol="__end_nrf_sections_run" />
    <ProgramSection alignment="4" load="No" name=".fast_run" />
    <ProgramSection alignment="4" load="No" name=".data_run" />
    <ProgramSection alignment="4" load="No" name=".tdata_run" />
    <ProgramSection alignment="4" load="No" name=".bss" />
    <ProgramSection alignment="4" load="No" name=".tbss" />
    <ProgramSection alignment="4" load="No" name=".non_init" />
    <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
    <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack"  address_symbol="__StackLimit" end_symbol="__StackTop"/>
    <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
  </MemorySegment>
  <MemorySegment name="uicr_bootloader_start_address" start="0x10001014" size="0x4">
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_bootloader_start_address" address_symbol="__start_uicr_bootloader_start_address" end_symbol="__stop_uicr_bootloader_start_address" start = "0x10001014" size="0x4" />
  </MemorySegment>
  <MemorySegment name="uicr_mbr_params_page" start="0x10001018" size="0x4">
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_mbr_params_page" address_symbol="__start_uicr_mbr_params_page" end_symbol="__stop_uicr_mbr_params_page" start = "0x10001018" size="0x4" />
  </MemorySegment>
</Root>
<!DOCTYPE Linker_Placement_File>
<Root name="Flash Section Placement">
  <MemorySegment name="FLASH1" start="$(FLASH_PH_START)" size="$(FLASH_PH_SIZE)">
    <ProgramSection load="no" name=".reserved_flash" start="$(FLASH_PH_START)" size="$(FLASH_START)-$(FLASH_PH_START)" />
    <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START)" />
    <ProgramSection alignment="4" load="Yes" name=".init" />
    <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
    <ProgramSection alignment="4" load="Yes" name=".text" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_soc_observers" inputsections="*(SORT(.sdh_soc_observers*))" address_symbol="__start_sdh_soc_observers" end_symbol="__stop_sdh_soc_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".pwr_mgmt_data" inputsections="*(SORT(.pwr_mgmt_data*))" address_symbol="__start_pwr_mgmt_data" end_symbol="__stop_pwr_mgmt_data" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_ble_observers" inputsections="*(SORT(.sdh_ble_observers*))" address_symbol="__start_sdh_ble_observers" end_symbol="__stop_sdh_ble_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_req_observers" inputsections="*(SORT(.sdh_req_observers*))" address_symbol="__start_sdh_req_observers" end_symbol="__stop_sdh_req_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_state_observers" inputsections="*(SORT(.sdh_state_observers*))" address_symbol="__start_sdh_state_observers" end_symbol="__stop_sdh_state_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_stack_observers" inputsections="*(SORT(.sdh_stack_observers*))" address_symbol="__start_sdh_stack_observers" end_symbol="__stop_sdh_stack_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_queue" inputsections="*(.nrf_queue*)" address_symbol="__start_nrf_queue" end_symbol="__stop_nrf_queue" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_balloc" inputsections="*(.nrf_balloc*)" address_symbol="__start_nrf_balloc" end_symbol="__stop_nrf_balloc" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".cli_command" inputsections="*(.cli_command*)" address_symbol="__start_cli_command" end_symbol="__stop_cli_command" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".crypto_data" inputsections="*(SORT(.crypto_data*))" address_symbol="__start_crypto_data" end_symbol="__stop_crypto_data" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_const_data" inputsections="*(SORT(.log_const_data*))" address_symbol="__start_log_const_data" end_symbol="__stop_log_const_data" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_backends" inputsections="*(SORT(.log_backends*))" address_symbol="__start_log_backends" end_symbol="__stop_log_backends" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections" address_symbol="__start_nrf_sections" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".cli_sorted_cmd_ptrs"  inputsections="*(.cli_sorted_cmd_ptrs*)" runin=".cli_sorted_cmd_ptrs_run"/>
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".fs_data"  inputsections="*(.fs_data*)" runin=".fs_data_run"/>
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_dynamic_data"  inputsections="*(SORT(.log_dynamic_data*))" runin=".log_dynamic_data_run"/>
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_filter_data"  inputsections="*(SORT(.log_filter_data*))" runin=".log_filter_data_run"/>
    <ProgramSection alignment="4" load="Yes" name=".dtors" />
    <ProgramSection alignment="4" load="Yes" name=".ctors" />
    <ProgramSection alignment="4" load="Yes" name=".rodata" />
    <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
    <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
    <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
    <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
  </MemorySegment>
  <MemorySegment name="RAM1" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">
    <ProgramSection load="no" name=".reserved_ram" start="$(RAM_PH_START)" size="$(RAM_START)-$(RAM_PH_START)" />
    <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START)" address_symbol="__app_ram_start__"/>
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run" address_symbol="__start_nrf_sections_run" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".cli_sorted_cmd_ptrs_run" address_symbol="__start_cli_sorted_cmd_ptrs" end_symbol="__stop_cli_sorted_cmd_ptrs" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".log_dynamic_data_run" address_symbol="__start_log_dynamic_data" end_symbol="__stop_log_dynamic_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".log_filter_data_run" address_symbol="__start_log_filter_data" end_symbol="__stop_log_filter_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run_end" address_symbol="__end_nrf_sections_run" />
    <ProgramSection alignment="4" load="No" name=".fast_run" />
    <ProgramSection alignment="4" load="No" name=".data_run" />
    <ProgramSection alignment="4" load="No" name=".tdata_run" />
    <ProgramSection alignment="4" load="No" name=".bss" />
    <ProgramSection alignment="4" load="No" name=".tbss" />
    <ProgramSection alignment="4" load="No" name=".non_init" />
    <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
    <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack"  address_symbol="__StackLimit" end_symbol="__StackTop"/>
    <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
  </MemorySegment>
</Root>


Unable to write to  flash memory using direct memory access functions like sd_flash_page_erase & sd_flash_write (nrf52840 nrf SDK 17.1.0)

Also attached application and bootloader flash placement file

Application :
Memory segment: 
FLASH1 RX 0x0 0x100000;RAM1 RWX 0x20000000 0x40000
Section placement macros:
FLASH_PH_START=0x0

FLASH_PH_SIZE=0x100000

RAM_PH_START=0x20000000

RAM_PH_SIZE=0x40000

FLASH_START=0x27000

FLASH_SIZE=0xd9000

RAM_START=0x20003F08

RAM_SIZE=0x3C0F8

Bootloader :
Memory segment: 
FLASH1 RX 0x0 0x100000;RAM1 RWX 0x20000000 0x40000;mbr_params_page RX 0x000FE000 0x1000;bootloader_settings_page RX 0x000FF000 0x1000;uicr_bootloader_start_address RX 0x10001014 0x4;uicr_mbr_params_page RX 0x10001018 0x4
Section placement macros:
FLASH_PH_START=0x0

FLASH_PH_SIZE=0x100000

RAM_PH_START=0x20000000

RAM_PH_SIZE=0x40000

FLASH_START=0xf4000

FLASH_SIZE=0x6000

RAM_START=0x20005978

RAM_SIZE=0x3a688

Parents
  • Hi,

    Please describe in what way those API calls fail.

    E.g. are they spinlocking forever on NRF_ERROR_BUSY, or do they return a different error code other than NRF_ERROR_BUSY and NRF_SUCCESS, or are you not getting the event afterwards, or do you get an event afterwards but it reports an error (and if so what error), or do you get an event stating that the operation was successful but in reality it was not executed when you check the flash afterwards, or otherwise what happens?

    Regards,
    Terje

  • The operation is successful but when I am reading the data I get the garbage data.
    So my page address is 0xFF000 
    I am also using a bootloader, soft device and application for my project,

    Can you please analyse my flash placement files provided for app & bootloader
    and let me know the selected page is correct or need to change the address

  • Hi,

    Most of the flash placement looks right, except for the bootloader which according to the Memory layout documentation for the nRF5 SDK DFU Bootloader has default location 0x000F8000 to 0x000FE000. Your placement is 0x000F4000 to 0x000FA000. (Size is correct, but start location is shifted by 0x4000). The area you have provided for the bootloader is typically the one used for application data (the last area before the bootloader), so yes, you might get some issues there with application data overwriting the bootloader.

    In any case, please note that flash writing takes time. When the API call returns success, it only means that the operation is queued. You will later get the event which signals the operation is completed (or in case of failure that the operation failed.) I assume that you have waited for this event, and assured it returns success, before reading what was written.

    Regards,
    Terje

Reply
  • Hi,

    Most of the flash placement looks right, except for the bootloader which according to the Memory layout documentation for the nRF5 SDK DFU Bootloader has default location 0x000F8000 to 0x000FE000. Your placement is 0x000F4000 to 0x000FA000. (Size is correct, but start location is shifted by 0x4000). The area you have provided for the bootloader is typically the one used for application data (the last area before the bootloader), so yes, you might get some issues there with application data overwriting the bootloader.

    In any case, please note that flash writing takes time. When the API call returns success, it only means that the operation is queued. You will later get the event which signals the operation is completed (or in case of failure that the operation failed.) I assume that you have waited for this event, and assured it returns success, before reading what was written.

    Regards,
    Terje

Children
  • I have set the bootloader start address to 0xF8000 and try to build the project, I got the following error

    8> /usr/share/segger_embedded_studio_for_arm_7.32a/gcc/arm-none-eabi/bin/ld: error: .rodata is too large to fit in FLASH1 memory segment
    8> /usr/share/segger_embedded_studio_for_arm_7.32a/gcc/arm-none-eabi/bin/ld: error: .data is too large to fit in FLASH1 memory segment
    8> /usr/share/segger_embedded_studio_for_arm_7.32a/gcc/arm-none-eabi/bin/ld: error: section .tdata overlaps absolute placed section .mbr_params_page
    8> /usr/share/segger_embedded_studio_for_arm_7.32a/gcc/arm-none-eabi/bin/ld: section .mbr_params_page VMA [00000000000fe000,00000000000fefff] overlaps section .text VMA [00000000000f83d4,00000000000ff5cf]
    8> /usr/share/segger_embedded_studio_for_arm_7.32a/gcc/arm-none-eabi/bin/ld: section .crypto_data VMA [00000000000ff5d0,00000000000ff5d7] overlaps section .bootloader_settings_page VMA [00000000000ff000,00000000000fffff]

Related