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.

Reply
  • 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.

Children
  • Hello Adam,

    Well, as you pointed out in your initial post, this refers to NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN. 

    Can you set a breakpoint at nrf_sdh.c on line 214 (ret_code = sd_softdevie_enable(...))?

    What are your:

    clock_lf_cfg.source
    clock_lf_cfg.rc_ctiv
    clock_lf_cfg.rc_temp_ctiv
    clock_lf_cfg.accuracy

    Not what you set them to above, but what are the numerical values when you hit line 214?

  • Hi Edvin,

    That was a breakpoint I had previously set, however I only looked at the values I set them to. Unfortunately the numerical values when I hit line 214 are 0xff for all 4 values.

    To double check, I went back and removed the file nrf_dfu_serial_uart.c from the project, cleaned and built, and at line 214 the values were what they were set to on lines 204-207.

  • I think we might be up against the flash limit of the nRF52. Without including nrf_dfu_serial_uart.c in the project we get the following build result:

    Aka 512.5 kB of flash storage used.

    WITH nrf_dfu_serial_uart.c included, we get the following results:

    Aka 516.5 kB of flash storage used.

    Is there a reason why in either case no error was thrown / nothing complained? I'm assuming this could be where the issue is coming from? If so, is there any way we could cut down on the size of flash needed while still keeping the dual transport layer functionality?

    For the record, under Project Options > Code Generation > Optimization Level, I already have it on "Optimize For Size"

    ...assuming this is the issue. If not, please let me know what else I can try.

  • What are your flash settings for the bootloader project? You can try to set the flash start address lower, and the size bigger. I see that you are using SES. SES has a bug where it doesn't tell you if the flash overflows the size that you have provided. It only throws the error if the size is overflowing the actual physical flash size (trying to write to an address higher than the highest flash address on the device). 

    If you are using the debug_version, remember that you have some flash to spare, because turning off optimization and including the NRF_LOG module will take up a lot of flash. However, it is difficult to remove them while debugging, because it is more difficult to see whats going on. 

    So try to move the flash start address down, and increase the size with a couple of pages. 

    Best regards,

    Edvin

  • Hi Edvin,

    That was not a bug that I was aware of with SES. Thank you for bringing it to my attention! It would be good to have that feedback, because I mainly use "build and debug" which does not give flash usage, so I had no indication that there could be an issue.

    That being said, our flash start address was 0x72000 with a flash size of 0xc000. I tried lowering the flash start address to 0x70000 and increase the size to 0xe000 and everything worked! It ran without error, initialized both DFU transport layers and I was able to perform a DFU both over BLE using the nRF Toolbox app and via USB using nrfutil. Thank you very much for the help!

    With that issue resolved, I have a couple of related questions:

    1. We currently have some units of our product out with customers. The current bootloader they are running is a BLE bootloader with a flash start address of 0x78000 and flash size of 0x6000. As far as I know, this will cause an issue if I provide them with an DFU package that would include the new bootloader? Is there any way to allow them to update their bootloader without us having to physically flash their devices?
    2. Now that I am aware that the SES bug exists, my concern is that we have no way of knowing whether or not there is overlap between our application and our bootloader. In theory, APP_FLASH_START + APP_FLASH_SIZE should equal BOOTLOADER_FLASH_START, correct? If that's so, as we add more features to our app, do we have any way of knowing if it exceeds its allocated APP_FLASH_SIZE besides having issues with the bootloader?

    Thanks,

    Adam

Related