USB DFU on a NRF52833

Hi,

I am trying to implement USB DFU on a NRF52833 with nRF5 SDK for Thread and Zigbee v4.1.0 and nRF5 SDK v16.0.0.

  •  In a first step I want to perform this on the devkit.
  •  In a second step on our custom PCB.

Unfortunatelly there is no NRF52833 USB bootloader example. So i performed this on a NRF52840 (pca10056).

1. What I managed to do is flashing the "pca10056_usb_debug" via the first USB port and then connecting to the other USB port. Then I performed

nrfutil dfu usb-serial -pkg blinky_mbr.zip -p COM16

which was also successful judging by the LEDs. Now I want to create an own .zip (infocenter.nordicsemi.com/index.jsp and this is where I have problems. Public and private keys are provided but when I run

nrfutil pkg generate --hw-version 52 --application out.hex --key-file priv.pem package.zip

I get the error message

Usage: nrfutil pkg generate [OPTIONS] ZIPFILE
Try 'nrfutil pkg generate --help' for help.
Error: --sd-req required. 

Which means I have to specify a soft device version. I am confused about this because I though soft devices can be used but are not required since this is neither an BLE nor an ANT project.

How do I know which version I have to pass to create the .zip?

Parents
  • Hi,

    I could do it the following way:

    nrfutil pkg generate --sd-req 0x00 --hw-version 52 --application-version 1 --application out.hex --key-file priv.pem package.zip

    As described in the documentation https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v16.0.0%2Flib_bootloader_dfu_validation.html&anchor=lib_dfu_image in the chapter "Updates without a SoftDevice".

  • Hi,

    Great that you figured it out! Does this mean the issue can be closed?

    Best regards,

    Marte

  • Hi,

    Try to enable single-bank updates by setting NRF_DFU_SINGLE_BANK_APP_UPDATES to 1. 

    Best regards,

    Marte

  • Hi,

    thanks for your quick reply. I get the same error message.

  • Hi,

    I see that you have made changes to the memory layout in section placement macros. FLASH_START is the start address of the program, so in the bootloader project, secure_bootloader_usb_mbr_pca10100e, this will be the start address of the bootloader. This should be 0x78000, but you have set this to 0x24000, which is too low.

    If you look at the memory layout I linked to in one of my previous replies, you will see that for nRF52833 you have the following:

    Usage Memory range nRF52833 (S113 v7.0.x) Memory range nRF52833 (S140 v7.0.x)
    Bootloader settings 0x0007 F000 - 0x0008 0000 (4 kB) 0x0007 F000 - 0x0008 0000 (4 kB)
    MBR parameter storage 0x0007 E000 - 0x0007 F000 (4 kB) 0x0007 E000 - 0x0007 F000 (4 kB)
    Bootloader 0x0007 8000 - 0x0007 E000 (24 kB) 0x0007 8000 - 0x0007 E000 (24 kB)
    Application area (incl. free space) 0x0001 C000 - 0x0007 8000 (368 kB) 0x0002 6000 - 0x0007 8000 (328 kB)
    SoftDevice 0x0000 1000 - 0x0001 C000 (112 kB) 0x0000 1000 - 0x0002 6000 (148 kB)
    Master Boot Record (MBR) 0x0000 0000 - 0x0000 1000 (4 kB) 0x0000 0000 - 0x0000 1000 (4 kB)

    This is with SoftDevice, but even without SoftDevice and MBR the application area is 0x0 to 0x78000. You can also see this in the section placement macros in your application, where FLASH_START is 0x0 and FLASH_SIZE is 0x7e000. Right now you are programming the bootloader at 0x24000 - 0x36000, and then you try to perform DFU with an application that should be located in the area 0x0 - 0x78000, but part of this is already taken by the bootloader. The size of bootloader flash, 0x12000, is also larger than it needs to be. As you can see in the the memory layout, you only need 0x6000. 

    Best regards,

    Marte

  • Hi,

    thank you for the info. I adjusted the values but get an error:

    <!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" size="0x4" />
        <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=".dfu_trans" inputsections="*(SORT(.dfu_trans*))" address_symbol="__start_dfu_trans" end_symbol="__stop_dfu_trans" />
        <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=".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=".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=".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" size="0x4" />
        <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=".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>
      <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>
    

    I can make it build with FLASH_START=0x75000 or lower.

    But this way it won't flash:

    For reference I used the nRF52840. According to the documentation the bootloader should start at 0x000F 8000. But in the working example it starts at 0xF4000.

  • Hi,

    Nppn7 said:
    For reference I used the nRF52833. According to the documentation the bootloader should start at 0x000F 8000. But in the working example it starts at 0xF4000.

    You are looking at the memory layout for nRF52840. The memory layout in my previous reply is for nRF52833, and is what you should look at. This is the same as the two columns at the right in the picture you posted. You see there that the bootloader starts at 0x78000, and not 0xF8000, which is outside of range for the nRF52833, as it has a flash size of 512 kB, so it only goes up to 0x80000.

    Pca10010 projects with an at the end (pca10010e) are nRF52820 projects, so secure_bootloader_usb_mbr_pca10010e is a nRF52820 project, and not nRF52833, which is why the flash and RAM settings do not correspond with the memory layout for nRF52833. The project is still configured as a nRF52820 project, which is causing you to get the errors you get. If you want to transfer this project to nRF52833 you can look at the guide Transferring the project to nRF52820 hardware, and reverse the steps there to transfer the project from nRF52820 to nRF52833, instead of from nRF52833 to nRF52820.

    Best regards,

    Marte

Reply
  • Hi,

    Nppn7 said:
    For reference I used the nRF52833. According to the documentation the bootloader should start at 0x000F 8000. But in the working example it starts at 0xF4000.

    You are looking at the memory layout for nRF52840. The memory layout in my previous reply is for nRF52833, and is what you should look at. This is the same as the two columns at the right in the picture you posted. You see there that the bootloader starts at 0x78000, and not 0xF8000, which is outside of range for the nRF52833, as it has a flash size of 512 kB, so it only goes up to 0x80000.

    Pca10010 projects with an at the end (pca10010e) are nRF52820 projects, so secure_bootloader_usb_mbr_pca10010e is a nRF52820 project, and not nRF52833, which is why the flash and RAM settings do not correspond with the memory layout for nRF52833. The project is still configured as a nRF52820 project, which is causing you to get the errors you get. If you want to transfer this project to nRF52833 you can look at the guide Transferring the project to nRF52820 hardware, and reverse the steps there to transfer the project from nRF52820 to nRF52833, instead of from nRF52833 to nRF52820.

    Best regards,

    Marte

Children
  • Hi,

    of course you are right. That was a typo. I was using the nRF52840 as a reference.

    I followed the guide you proposed and did the reverse things. I have a problem with step 3. Adding NRF52833_XXAA is fine, but adding NRF52 causes trouble:

    If I remove it it throws less errors. What I do not understand is step 5. Where do I get the corresponding values for the nRF52833 (nRF52833 memory map)? I couldn't even find the ones for the nRF52820 as a reference (nRF52820 memory map).

    This is how it looks like now:

    <!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" size="0x4" />
        <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=".dfu_trans" inputsections="*(SORT(.dfu_trans*))" address_symbol="__start_dfu_trans" end_symbol="__stop_dfu_trans" />
        <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=".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=".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=".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" size="0x4" />
        <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 = "0x0007E000" 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 = "0x0007F000" 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=".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>
      <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>
    

    The error message:

  • Hi,

    Nppn7 said:
    Where do I get the corresponding values for the nRF52833

    There are multiple ways to get this. The simplest way would be to open a nRF52833 project in SES and look at what these values are set to there.

    You can also find it by looking at the memory map you linked. As is stated there, flash memory is divided into 128 pages of 4 kB each. In the figure you see that the last page starts on 0x7F000. Since each page is 4 kB, or 0x1000, the end of flash will be 0x7F000+0x1000=0x80000. You can do the same for RAM.

    Another way is to use the size of available flash and RAM to and find the hex address from this. The nRF52833 has 512 kB flash, which is 512 * 1024 = 524 288 bytes. There are multiple converters available that convert from decimal to hex, and using this you find that the hex value is 0x80000.

    Best regards,

    Marte

Related