Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

DFU with external QSPI memory

Hi,

   I am working on project, in which we using nordic nRF52840 chip. We need to flash the app+SD+BL image file in external QSPI memory.

After prevalidation, the DFU controller starts to send flash image package, we need to receive this and need to save in external QSPI memory. Once the postvalidation is successful, then read all the flash image package stored in external QSPI memory and write it to internal flash memory.

For that we use secure bootloader example code as reference file. I need to know where i need to modify the secure bootloader code.

I noticed that after prevalidation, the flash is erased in on_data_obj_create_request() function in nrf_dfu_req_handler.c file, and flash is written in on_data_obj_write_request() under the same c file. Is that right?

Thanks & Regards

Mohammad Gouse

Parents
  • Hi Hung Bui,

      I have modified the files nrf_fstorage_nvmc.c, nrf_flash.c, nrf_dfu_flash.c (with their corresponding header file) to have external qspi memory interface.

    Once the device enter into DFU mode, it initialize the nrf_dfu_req_handler_init(), so I modified this function by adding nrf_dfu_qspi_init() in it.

      In this project, MX25R6435F used as external QSPI memory. The memory map of this will be same as Nordic system memory map, but without MBR and Bootloader (In our case bootloader in internal flash memory).

    Step 1: After pre-validation, I need to copy the image file (SD + APP) to external QSPI. Now I need to know where I need to change the code to proceed to next step.

  • Hi Mohammad, 

    I assume you are familiar with the DFU procedure as described here

    After you pass the pre-validation (received the init packet and then got the NRF_DFU_OP_OBJECT_WRITE to execute it), you will receive the data objects. 

    They will be handled inside nrf_dfu_data_req(). It will start with the NRF_DFU_OP_OBJECT_CREATE and the page will be erased with the call to nrf_dfu_flash_erase() inside on_data_obj_create_request(). You would need to modify that function to erase the QSPI flash page instead. 

    Next is NRF_DFU_OP_OBJECT_WRITE , which handled in on_data_obj_write_request(). You need to modify nrf_dfu_flash_store() to store on QSPI. And so on. 

    I'm not 100% sure why you would need to make the addressing on QSPI the same as on the internal chip. But it's up to you. You can have a look at our discussion with TomWS above to know about other stuff you need to modify. 

  • Hi Hung Bui,

      Thanks for your response.

    I have modified nrf_dfu_flash_erase to qspi_earse in on_data_obj_create_request() and nrf_dfu_flash_store to QSPI store in on_data_obj_write_request().

    Its that enough for storing the firmware to QSPI memory?

    The addressing is same as internal chip, so i assume that i don't need to change nrf_dfu_bank0_start_addr, nrf_dfu_bank1_start_addr, nrf_dfu_app_start_address and nrf_dfu_softdevice_start_address. And also the nrf_dfu_cache_prepare().

    Is that correct?

    If yes, then i will proceed to post validation process.

  • Hi Mohammad, 

    Unfortunately, I haven't tried to change the storage from internally to QSPI before, so I don't know for sure if that all you need. 

    Before you go to the next step, please verify that you can store the image on QSPI flash and it stored properly. 

    One advantage of having external flash is that you can store all 3 image (SD+BL+APP) at once compare to the traditional DFU to do that we need to do it in 2 tries (first SD+BL, after that APP). To utilize this, you need to modify the bootloader to take all 3 images and update the app after BL updated. 

  • Hi Hung,

    While i am testing secure bootloader with external QSPI, i am getting the following error,

    C:\vault>nrfutil dfu usb-serial -pkg app_dfu_pkg.zip -p COM5 -b 115200
    [###################################-] 98% 00:00:01
    Traceback (most recent call last):
    File "C:\Python27\Scripts\nrfutil-script.py", line 11, in <module>
    load_entry_point('nrfutil==5.2.0', 'console_scripts', 'nrfutil')()
    File "c:\python27\lib\site-packages\click\core.py", line 764, in __call__
    return self.main(*args, **kwargs)
    File "c:\python27\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
    File "c:\python27\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
    File "c:\python27\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
    File "c:\python27\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
    File "c:\python27\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
    File "c:\python27\lib\site-packages\nordicsemi\__main__.py", line 1001, in usb_serial
    timeout)
    File "c:\python27\lib\site-packages\nordicsemi\__main__.py", line 956, in do_serial
    dfu.dfu_send_images()
    File "c:\python27\lib\site-packages\nordicsemi\dfu\dfu.py", line 117, in dfu_send_images
    self._dfu_send_image(self.manifest.softdevice_bootloader)
    File "c:\python27\lib\site-packages\nordicsemi\dfu\dfu.py", line 102, in _dfu_send_image
    self.dfu_transport.send_firmware(data)
    File "c:\python27\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 302, in send_firmware
    self.__execute()
    File "c:\python27\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 421, in __execute
    self.__get_response(DfuTransportSerial.OP_CODE['Execute'])
    File "c:\python27\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 502, in __get_response
    raise NordicSemiException('Extended Error 0x{:02X}: {}'.format(resp[3], data))
    pc_ble_driver_py.exceptions.NordicSemiException: Extended Error 0x0C: The hash of the received firmware image does not match the hash in the init packet.

    Pls help me to solve this issue

  • Hi Mohammad, 

    The error suggests that after the image is received on the nRF52 side, the calculation (post validation) of the image received showing that the hash of the packet doesn't match with the hash in the init packet. 

    You would need to check if : 

    - The image you received and stored properly (read the flash out and compare it with the original image) 

    - Check if the calculation in post validation postvalidate_app() is correct

    - Check if the hash received in the init packet is parse correctly. 

Reply
  • Hi Mohammad, 

    The error suggests that after the image is received on the nRF52 side, the calculation (post validation) of the image received showing that the hash of the packet doesn't match with the hash in the init packet. 

    You would need to check if : 

    - The image you received and stored properly (read the flash out and compare it with the original image) 

    - Check if the calculation in post validation postvalidate_app() is correct

    - Check if the hash received in the init packet is parse correctly. 

Children
  • Hi Hung,

     Inside on_data_obj_write_request(), i am using ret_code_t ret = nrf_drv_qspi_write( p_req->write.p_data,  p_req->write.len, write_addr) to write into QSPI instead of writing into flash. 

    Is that correct?

  • Hi Mohammad, 

    Yes, it's the correct place to replace the nrf_dfu_flash_store() with your qspi function. 

    You then need to check if the image copied to the qspi flash correctly after the image is fully transferred. 

  • Hi Hung,

    <info> nrf_dfu_serial_usb: USB power detected
    <info> nrf_dfu_serial_usb: USB ready
    <warning> nrf_dfu_serial_usb: Could not read from CDC. Error: 0x92.
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_RECEIPT_NOTIF_SET
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_MTU_GET
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (command)
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (command)
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (command)
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (command)
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (command)
    <info> nrf_dfu_validation: PB: Init packet data len: 62
    <info> nrf_dfu_validation: Signature required. Checking signature.
    <info> nrf_dfu_validation: Calculating hash (len: 62)
    <info> nrf_dfu_validation: Verify signature
    <info> nrf_dfu_validation: Image verified
    <info> nrf_dfu_validation: Write address set to 0x00001000
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <info> nrf_dfu_req_handler: Writing valid init command to flash.
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (data)
    <info> nrf_dfu_req_handler: crc = 0x0, offset = 0x0, max_size = 0x1000
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
    <info> nrf_dfu_req_handler: Creating object with size: 1708. Offset: 0x00000000, CRC: 0x00000000
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)

    ------------------------------------------QSPI write---------------------------------------
    <info> nrf_dfu_req_handler: Wirting to qspi at address 0x1000 with length 0x400
    <info> nrf_dfu_req_handler: Data inconsistent at location = 1023, QSPIData[1023] = 0 and Imagedata[1023] = 32
    <info> nrf_dfu_req_handler: Data inconsistent, times = 1
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <info> nrf_dfu_req_handler: Wirting to qspi at address 0x1400 with length 0x2AC
    <info> nrf_dfu_req_handler: Data inconsistent at location = 683, QSPIData[683] = 70 and Imagedata[683] = 3
    <info> nrf_dfu_req_handler: Data inconsistent, times = 1

    ------------------------------------------------------------------------------------
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
    <info> nrf_dfu_req_handler: Offset:1708, CRC:0x4009821F
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (data)
    <info> nrf_dfu_req_handler: Whole firmware image received. Postvalidating.
    <info> nrf_dfu_validation: Hash verification. start address: 0x1000, size: 0x6AC
    <warning> nrf_dfu_validation: Hash verification failed.
    <info> nrf_dfu_validation: Expected FW hash:
    <info> nrf_dfu_validation: 97 AF 3F C4 72 7B DD 8B|..?.r{..
    <info> nrf_dfu_validation: 21 75 95 95 DF 47 D9 88|!u...G..
    <info> nrf_dfu_validation: D1 38 7A C0 32 8C 0C E4|.8z.2...
    <info> nrf_dfu_validation: 0A 11 68 6E 78 7A B3 54|..hnxz.T
    <info> nrf_dfu_validation: Actual FW hash:
    <info> nrf_dfu_validation: 4F 4A FE AE 1A 61 B8 CB|OJ...a..
    <info> nrf_dfu_validation: 96 05 85 07 BA 8B 88 60|.......`
    <info> nrf_dfu_validation: 9E C0 F7 38 11 1D C3 6A|...8...j
    <info> nrf_dfu_validation: BD 04 FC 39 3C 13 BA B6|...9<...
    <warning> nrf_dfu_serial: DFU request completed with result: 0xB
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <info> nrf_dfu_req_handler: All flash operations have completed. DFU completed.
    <info> app: Resetting bootloader.
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <info> app: Inside main
    <info> app: In nrf_bootloader_init
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <info> app: Enter nrf_bootloader_fw_activate
    <info> app: No firmware to activate.
    <info> app: Boot validation failed. No valid app to boot.
    <info> app: DFU mode because app is not valid.
    <info> nrf_bootloader_wdt: WDT is not enabled
    <info> app: in weak nrf_dfu_init_user
    <info> app: Entering DFU mode.
    <info> app: Enter main loop
    <info> nrf_dfu_serial_usb: USB power detected
    <info> nrf_dfu_serial_usb: USB ready

    This is the output from NRF_LOG. The last byte written to QSPI is not same as image received.

  • So you have checked what written in QSPI and the last byte was not the same ? Could you check why that happens ? Note that the size of the last packet is not the same size as other packet. 

  • Hi Hung,
    I used blinky_pca10056_mbr.hex found in examples under nordic SDK 15.3 to generate the dfu_app_pkg.zip. I followed the below steps,

    1. In the blinky_pca10056_mbr example code, i modified the FLASH_START=0x26000, in order to place code above SD section.

    2. Then i generated the settings file,
    nrfutil settings generate --family NRF52840 --application blinky_pca10056_mbr.hex --application-version 5 --bootloader-version 2 --bl-settings-version 2 settings.hex

    Bootloader DFU Settings:
    * File: settings.hex
    * Family: NRF52840
    * Start Address: 0x000FF000
    * CRC: 0x236ED638
    * Settings Version: 0x00000002 (2)
    * App Version: 0x00000005 (5)
    * Bootloader Version: 0x00000002 (2)
    * Bank Layout: 0x00000000
    * Current Bank: 0x00000000
    * Application Size: 0x000006AC (1708 bytes)
    * Application CRC: 0x4009821F
    * Bank0 Bank Code: 0x00000001
    * Softdevice Size: 0x00000000 (0 bytes)
    * Boot Validation CRC: 0x1202D358
    * SD Boot Validation Type: 0x00000000 (0)
    * App Boot Validation Type: 0x00000001 (1)

    3. Then I merged the blinky_pca10056_mbr.hex and settings.hex into app_settings.hex

    4. Finally the dfu_app_pkg is generated,

    nrfutil pkg generate --hw-version 52 --sd-req 0x00 --application-version 5 --application app_settings.hex --key-file Test2.key app_dfu_pkg.zip

    5. I am sending the app_dfu_pkg.zip,
    nrfutil dfu usb-serial -pkg app_dfu_pkg.zip -p COM5 -b 115200

    6. The output,
    <info> app: Enter nrf_bootloader_fw_activate
    <info> app: No firmware to activate.
    <info> app: App is valid
    <info> app: DFU mode requested via button.
    <info> nrf_bootloader_wdt: WDT is not enabled
    <info> app: in weak nrf_dfu_init_user
    <info> app: Entering DFU mode.
    <info> app: Enter main loop
    <info> nrf_dfu_serial_usb: USB power detected
    <info> nrf_dfu_serial_usb: USB ready
    <warning> nrf_dfu_serial_usb: Could not read from CDC. Error: 0x92.
    <info> nrf_dfu_validation: Signature required. Checking signature.
    <info> nrf_dfu_validation: Calculating hash (len: 63)
    <info> nrf_dfu_validation: Verify signature
    <info> nrf_dfu_validation: Image verified
    <info> app: Enter nrf_dfu_cache_prepare()
    <info> app: required_size: 0xD9324.
    <info> app: single_bank: false.
    <info> app: keep_app: false.
    <info> app: keep_softdevice: false.
    <info> app: SD_PRESENT: false.
    <info> app: Bank contents:
    <info> app: Bank 0 code: 0x01: Size: 0xD9324
    <info> app: Bank 1 code: 0x00: Size: 0x0
    <info> app: pass: 0.
    <info> app: cache_address: 0xDB000.
    <info> app: cache_too_small: true.
    <info> app: keep_firmware: false.
    <info> app: delete_more: true.
    <info> app: pass: 1.
    <info> app: cache_address: 0x1000.
    <info> app: cache_too_small: false.
    <info> app: keep_firmware: true.
    <info> app: delete_more: false.
    <info> nrf_dfu_validation: Write address set to 0x00001000
    <info> nrf_dfu_req_handler: Writing valid init command to flash.
    <info> nrf_dfu_req_handler: Whole firmware image received. Postvalidating.
    <info> nrf_dfu_validation: Convert to hash to big-endian format for use in nrf_crypto
    <info> nrf_dfu_validation: Hash verification. start address: 0x1000, size: 0xD9324
    --------------------------- Hash verification succeed -----------------------
    <info> nrf_dfu_validation: Invalidating old application in bank 0.
    <info> nrf_dfu_req_handler: All flash operations have completed. DFU completed.
    <info> app: Resetting bootloader.
    <info> app: Inside main
    <info> app: Enter nrf_bootloader_fw_activate
    <info> app: Valid App
    <info> app: Enter nrf_dfu_app_continue
    <info> app: Setting app as valid
    <info> app: Resetting bootloader.
    <info> app: Inside main
    <info> app: Inside main

    --------- But the Led Blink doesn't working --------------

Related