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,

    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.

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

Children
  • 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

  • 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

Related