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

Serial DFU causing nrf_dfu_flash: Flash write failed (0x3)

Hi Nordic Team,

I am using SDK 16.0.0 with Softdevice S132 version 7.0.1 on the NRF52832 and using SES v4.52c on Linux. I have managed to run and sucessfully execute the DFU BLE example. But I need to be able to run the DFU over serial so have adapted the example code given here to SDK 16 and added it to my bootloader. When I run the the BLE DFU, everything works flawlessly and I get complete firmware update if I remove the NRF_POWER->TASKS_CONSTLAT = 1; in spis_dfu_transport_init() and the NRF_POWER->TASKS_LOWPWR = 1; in spis_dfu_transport_close() which came with the SPI SDK 14.2 example. 

The issue is if I try to run a DFU over SPI, I get 'nrf_dfu_flash: Flash write failed (0x3): addr=0x00026000, len=0x7F bytes, pending 0' when the firmware tries to write the first block of firmware to the Application Start Address. The same function does not fail during the BLE upgrade of the same firmware. 


What I have already done: 
  • As mentioned above I have removed calls to NRF_POWER in the SPIS init and deinit functions
  • I have moved the Bootloader Start Address to 0x70000 to avoid the error in Segger Embedded Studio outlined here and also to have enough space for Logging functionality
  • Run the SPI DFU code without the BLE transport registered (the same error persists) 
  • Increased the wait times between Write and Execute, between Create and Write, between Execute and subsequent Writes...
  • Enabled NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED before I understood that the problem was caused by write to flash not working at all.
  • Disabled the SLIP library for the SPI DFU as it's not needed for our application.

My Section Placement Macros are as follows: 

FLASH_PH_START=0x0
FLASH_PH_SIZE=0x80000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x10000
FLASH_START=0x70000
FLASH_SIZE=0x6000
RAM_START=0x20005968
RAM_SIZE=0xa698

Output of firmware runnning BLE DFU: 

<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_RECEIPT_NOTIF_SET
00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
00> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (data)
00> <debug> nrf_dfu_req_handler: crc = 0x0, offset = 0x0, max_size = 0x1000
00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
00> <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 3
00> <debug> nrf_dfu_flash: Flash erase success: addr=0x00026000, pending 0
00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
...
...
00> <debug> nrf_dfu_ble: Buffer 0x200078F4 acquired, len 244 (244)
00> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000260F4, src=0x200078F4, len=244 bytes), queue usage: 1
00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
00> <debug> nrf_dfu_ble: Buffer 0x200079E8 acquired, len 244 (244)
00> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000261E8, src=0x200079E8, len=244 bytes), queue usage: 2
00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
00> <debug> nrf_dfu_ble: Buffer 0x20007ADC acquired, len 244 (244)
00> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000262DC, src=0x20007ADC, len=244 bytes), queue usage: 3
...
...
00> <debug> nrf_dfu_flash: Flash write success: addr=0x000261E8, pending 13

Output of the same firmware running Serial DFU (SPI) 

<debug> nrf_dfu_validation: Write address set to 0x00026000
<debug> nrf_dfu_settings: Writing settings...
<debug> nrf_dfu_settings: Erasing old settings at: 0x0007F000
<debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 0
<debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 0
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, src=0x2000889C, len=896 bytes), queue usage: 1
<debug> nrf_dfu_flash: Flash write success: addr=0x0007F000, pending 0
<info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
<debug> nrf_dfu_settings: Writing settings...
<debug> nrf_dfu_settings: Erasing old settings at: 0x0007E000
<debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007E000, len=1 pages), queue usage: 1
<debug> nrf_dfu_flash: Flash erase success: addr=0x0007E000, pending 0
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007E000, src=0x20008C1C, len=896 bytes), queue usage: 1
<debug> nrf_dfu_flash: Flash write success: addr=0x0007E000, pending 0
<debug> nrf_dfu_req_handler: Writing valid init command to flash.
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_serial: Sending Response: [0x4, 0x1]
<info> app:  Transfer completed. Received: 0 bytes
<info> app:  No command received start RX again
<info> app:  Transfer completed. Received: 6 bytes
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
<debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00026000, len=1 pages), queue usage: 1
<debug> nrf_dfu_flash: Flash erase success: addr=0x00026000, pending 0
<debug> nrf_dfu_req_handler: Creating object with size: 4096. Offset: 0x00000000, CRC: 0x00000000
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_serial: Sending Response: [0x1, 0x1]
<info> app:  Transfer completed. Received: 0 bytes
<info> app:  No command received start RX again
<info> app:  Transfer completed. Received: 128 bytes
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00026000, src=0x20007273, len=127 bytes), queue usage: 1
<debug> nrf_dfu_flash: Flash write failed (0x3): addr=0x00026000, len=0x7F bytes, pending 0
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<info> app:  Transfer completed. Received: 128 bytes
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0002607F, src=0x20007273, len=127 bytes), queue usage: 1
<debug> nrf_dfu_flash: Flash write failed (0x3): addr=0x0002607F, len=0x7F bytes, pending 0

This seems similar to the issue outlined here

Parents
  • You are trying to write to an odd flash address - this won't work. Flash writes must be 4-byte aligned.

    In your case, write 128 bytes per DFU packet and not 127. Any yes, that means your raw packet will be a bit larger than 128 bytes.

  • Thank your response, I have changed the packet size to 130 so I can get a data size of 128 as suggested but I still have the same error as logged below. Am I still missing something? 

    EDIT: Both the source and destination address to nrf_df_flash have to be 4 byte aligned, problem solved. Removing SLIP has the side effect of misalignment of the source address in RAM caused by the OPCODE

    <debug> nrf_dfu_validation: Write address set to 0x00026000
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <debug> nrf_dfu_req_handler: Writing valid init command to flash.
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_serial: Sending Response: [0x4, 0x1]
    <info> app:  Transfer completed. Received: 0 bytes
    <info> app:  No command received start RX again
    <info> app:  Transfer completed. Received: 6 bytes
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00026000, len=1 pages), queue usage: 0
    <debug> nrf_dfu_flash: Flash erase success: addr=0x00026000, pending 0
    <debug> nrf_dfu_req_handler: Creating object with size: 4096. Offset: 0x00000000, CRC: 0x00000000
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_serial: Sending Response: [0x1, 0x1]
    <info> app:  Transfer completed. Received: 0 bytes
    <info> app:  No command received start RX again
    <info> app:  Transfer completed. Received: 129 bytes
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00026000, src=0x20007273, len=128 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write failed (0x3): addr=0x00026000, len=0x80 bytes, pending 0
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> app:  Transfer completed. Received: 129 bytes
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00026080, src=0x20007273, len=128 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write failed (0x3): addr=0x00026080, len=0x80 bytes, pending 0
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> app:  Transfer completed. Received: 129 bytes
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00026100, src=0x20007273, len=128 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write failed (0x3): addr=0x00026100, len=0x80 bytes, pending 0

  • Thank you , your answer made me discover that both the source and destination address to nrf_df_flash have to be 4 byte aligned. Works like a charm now. 

Reply Children
No Data
Related