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

Enabling Softdevice fails in bootloader when trying to initialize multiple DFU transports

Hi,

I'm working on a bootloader that combines both the BLE and UART transport layers. We have custom hardware containing the nRF52832 chip running on SDK 15.3, and we're using softdevice s132 v6.1.1.

I started with the secure BLE bootloader example pca10040_ble_debug and then slowly added in the UART transport layer. I did this by first adding the file nrf_dfu_serial_uart.c to the project and then working through any errors when building in SES. Roughly, from memory, I think it involved the following additional changes to the project:

  • Added these additional files:
    • nrf_dfu_serial.c
    • nrf_drv_uart.c
    • nrfx_uart.c
    • nrfx_uarte.c
    • nrfx_prs.c
    • slip.c
  • Added these additional include paths:
    • ../../../../../components/libraries/slip
    • ../../../../../integration/nrfx/legacy
    • ../../../../../modules/nrfx/drivers/include
    • ../../../../../modules/nrfx/drivers/src/prs

  • Merging the sdk_config.h files from both the pca10040_ble_debug and pca_10040_uart_debug example projects.

The project builds without errors, but when running, I do not see dfu_targ advertising, and timed out when trying to perform a DFU over UART using nrfutil. Debugging through the issue, the error occurs when trying to enable the softdevice when initializing the BLE DFU transport layer. I get the following debug printout:

<info> app: Entering DFU mode.
<debug> app: Initializing transports (found: 2)
<debug> nrf_dfu_ble: Initializing BLE DFU transport
<debug> nrf_dfu_ble: Setting up vector table: 0x00072000
<debug> nrf_dfu_ble: Enabling SoftDevice.
<debug> app: Failed to initialize transport 0, error 4096
<error> app: Could not initalize DFU transport: 0x00001000
<error> app: Received an error: 0x00000003!

Error code 4096 is "NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN" which is "unknown LFCLK source". However, I don't think this is really the issue since it is set up the same way as always when bootloaders, softdevices, applications have had no issue running. Also, to further debug, I removed the file nrf_dfu_serial_uart.c from the project, cleaned, and then built again and the softdevice enabled without issue. I even saw dfu_targ advertising. Which means that the issue is with adding in the additional transport layer, but I don't know why it would cause an unknown LFCLK source error to occur.

Wondering if it was a global issue with having multiple transport layers, I edited the project file to list nrf_dfu_serial_uart.c first so it would be the first transport layer initialized and it initialized successfully with the following debug printout:

<info> app: Entering DFU mode.
<debug> app: 
<debug> nrf_dfu_serial_uart: serial_dfu_transport_init()
<debug> nrf_dfu_serial_uart: serial_dfu_transport_init() completed
<debug> nrf_dfu_ble: Initializing BLE DFU transport
<debug> nrf_dfu_ble: Setting up vector table: 0x00072000
<debug> nrf_dfu_ble: Enabling SoftDevice.
<debug> app: 
<error> app: Could not initalize DFU transport: 0x00001000
<error> app: Received an error: 0x00000003!

Lastly, after doing a lot of research online, I noticed that a lot of other people's issues stemmed from FLASH or RAM size / placement. I tried changing the values but it did not have any effect. Nor do I think it's the issue since there was no suggesting in the debug printouts to change any of the RAM or FLASH values. But for the record, here are my values:

FLASH_PH_START=0x0
FLASH_PH_SIZE=0x80000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x10000
FLASH_START=0x72000
FLASH_SIZE=0xc000
RAM_START=0x200057b8
RAM_SIZE=0xa848

**NOTE: I also tried running the project on a DK board and the same issue happens.

Any suggestions or help would be much appreciated. Thanks.

Parents
  • Hello,

    Can you try to define DEBUG in your preprocessor definitions? It should use the app_error_handler() instead of app_error_handler_bare(). I suggest that you add the err_code to the app_error_handler() logging as well (I don't know why it is removed):

    void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
    {
        NRF_LOG_ERROR("error: %d, %s:%d", error_code, p_file_name, line_num);
        on_error();
    }

    What place in your code does it point to? 

    Best regards,

    Edvin

  • Hi Edvin,

    Thank you for your reply! I defined DEBUG in my preprocessor definitions and added err_code to the app_error_handler and it gives the following output:

    <info> app: Entering DFU mode.
    <debug> app: Initializing transports (found: 2)
    <debug> nrf_dfu_ble: Initializing BLE DFU transport
    <debug> nrf_dfu_ble: Setting up vector table: 0x00072000
    <debug> nrf_dfu_ble: Enabling SoftDevice.
    <debug> app: Failed to initialize transport 0, error 4096
    <error> app: Could not initalize DFU transport: 0x00001000
    <error> app: error: 3, /My_Directory/nRF5_SDK_15.3.0_59ac345/examples/dfu/secure_bootloader/main.c:144

    That points to the APP_ERROR_CHECK in main right after nrf_bootloader_init. The two lines look like this:

    143:    ret_val = nrf_bootloader_init(dfu_observer);
    144:    APP_ERROR_CHECK(ret_val);

    It looks like error code 3 refers to NRF_ERROR_INTERNAL. Does that tell us anything? Thanks.

  • Hello Adam,

    That is great news that it worked out. 

    2. If you compile your bootloader, you can look at the hex file to see how large it is. It is a bit tricky to see directly by opening it in a text editor, but you can use nRF Connect for Desktop -> Programmer, and upload your hex file there. It should show the start and stop address for that hex file. It will look something like this:

    This is an unmodified pca10056_s140_ble bootloader with start address 0x000F8000, and you can see that the end address is 0x000FDDE0. It needs to end before 0x000FE000, and it needs to start on a new page, so either 0x000F8000, 0x000F7000, 0x000F6000, and so on. 

    So if the bootloader stops before 0x000FEFFF, you can push it one page up.

    1. It isn't really trivial to change the bootloader start address over DFU. However, it it possible on the nRF52832 (but not the nRF52840). My colleague Bjørn has described this in this ticket. However, it is not possible to do this with the bootloader from SDK15.3.0, because the bootloader start address is stored in the MBR, instead of the UICR. Is the bootloader in field from another SDK than SDK15.3.0?

    BR,

    Edvin

  • Hi Edvin,

    2. Thanks for the tip, I'll definitely use that when working out flash size and placement.

    1. Unfortunately the bootloader in the field is from SDK 15.3. That being said, it's a smaller number of initial devices. We will look to flash this new combined USB/BLE bootloader on all new devices that are shipped. How would I go about determining what would be a safe size for future-proofing this new bootloader? In other words, do you think the current start address of 0x70000 and size of 0xe000 should be adequate moving forward? I'd like to be able to leave as much space for our application as possible.

    Thanks,

    Adam

  • Ideally, the bootloader shouldn't be subject to a lot of feature changes. Most bootloader updates are due to softdevice migration, when you move from one softdevice to another (the application and bootloader needs to use the same version of the softdevice).

    If you have combined the BLE and USB bootloader, then the size will increase, but the size is not likely to increase that much in future releases of the SDK (those two combined). How large did the bootloader actually end up being? Unless it is from 0x70000 to 0x7dfff (or only leaving a couple of bytes) you should be fine. 

    Best regards,

    Edvin

  • Yeah, we had previously done a bootloader update when migrating from SDK 14.2 to 15.3 and upgrading the softdevice, but didn't run into the size issue.

    When loading the hex file in nRF Connect Programmer, there seems to be two memory regions from 0x70000 to 0x7D2AC. I'm assuming those are both for the bootloader.

    Lastly, I'm assuming it is safe to predict that we should be fine for future-proofing?

    Thanks,

    Adam

  • As long as you only loaded one .hex file, they belong to the same file yes. So in this case it is the bootloader ranges from 0x00070000 to 0x0007D2AC. I don't know exactly how nRF Connect for Desktop -> Programmer interprets that it is two several files, but I believe it looks for certain familiar chunks and sizes, in order to tell whether it is an application or a softdevice or MBR and so on. So since this is a bit modified, it probably gets confused. 

    By the way, it looks like it uses the memory layout for the nRF52840. It doesn't really matter, but if you plug in an nRF52832 DK, it will use the memory range for that device. But again, it doesn't really matter. You should only look at the numbers.

    As for your memory settings. It looks good now. You still have the area from 0x7D2AC to 0x7DFFF for future expansion. You may already have done this, but remember to disable logging and turn back optimization (set it to -O3) and compile after you are done implementing the bootloader, because this will reduce the size of the bootloader. You may have already done this, but just in case. 

    Best regards,

    Edvin

Reply
  • As long as you only loaded one .hex file, they belong to the same file yes. So in this case it is the bootloader ranges from 0x00070000 to 0x0007D2AC. I don't know exactly how nRF Connect for Desktop -> Programmer interprets that it is two several files, but I believe it looks for certain familiar chunks and sizes, in order to tell whether it is an application or a softdevice or MBR and so on. So since this is a bit modified, it probably gets confused. 

    By the way, it looks like it uses the memory layout for the nRF52840. It doesn't really matter, but if you plug in an nRF52832 DK, it will use the memory range for that device. But again, it doesn't really matter. You should only look at the numbers.

    As for your memory settings. It looks good now. You still have the area from 0x7D2AC to 0x7DFFF for future expansion. You may already have done this, but remember to disable logging and turn back optimization (set it to -O3) and compile after you are done implementing the bootloader, because this will reduce the size of the bootloader. You may have already done this, but just in case. 

    Best regards,

    Edvin

Children
Related