This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ERROR: Not valid hex file when flashing code to new DK board

I am using an nRF52840 DK board that I just bought, but have ran into a weird issue that I have never come across when using our old nRF52840 DK. I have a script that I use to first compile my project code, and then flash everything onto my DK board. Here is the code of that script:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#! /bin/bash
## Compile bootloader and application:
boot_make='../nrf-sdk/examples/dfu/secure_bootloader/pca10040_s132_ble/armgcc/'
boot=${boot_make}_build/nrf52832_xxaa_s132.hex
softdevice='../nrf-sdk/components/softdevice/s132/hex/s132_nrf52_7.0.1_softdevice.hex'
app_make='../nrf-sdk/examples/ble_peripheral/ble_app_technolingus/pca10040/s132/armgcc/'
app=${app_make}_build/nrf52832_xxaa.hex
make -C "$boot_make"
make -C "$app_make"
nrfutil settings generate --family NRF52 --application "$app" --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex
nrfjprog -e
nrfjprog --program "$softdevice" --verify
nrfjprog --program "$boot" --verify --log .
nrfjprog --program "$app" --verify
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

My code compiles and the hex files are generated as a result of the calls to make -C "$boot_make" and make -C "$app_make". However, when the script finishes programming the softdevice, it complains with ERRORS about the other .hex files I am trying to flash. Here is that output for your reference:

Only moments ago, when running the same code for an older DK (same nRF52840), this script worked fine and everything flashed correctly. I cant figure out why this new DK board causes the programming to fail. What might be causing this new behavior (even though there is no code change)?

I have also attached the log output file from logging the first failing nrfjprog --program command for your reference....if it helps.

The only other thing I have tried is to erase my device from Segger ES (Target > Connect JLink, Target > Erase All), download the secure bootloader ble example, then download my custom application. When I Build and Debug this code, my project always fails at this function, with the same error (NRF ERROR NO MEM "No bootloader found"):

Fullscreen
1
APP_ERROR_CHECK(ble_dfu_buttonless_async_svci_init());
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


https://devzone.nordicsemi.com/cfs-file/__key/support-attachments/beef5d1b77644c448dabff31668f3a47-e7cffbc33f2f4d6bb1e0d9576c0082cb/log.log

Parents
  • Hi, 

    Seem you are programming s132_nrf52_7.0.1_softdevice.hex and nrf52832_xxaa_s132.hex to nRF52840DK. For nRF52840, you use --family NRF52840 to generate the setting. 

    To use the new version of nRF52840DK, you have to run "nrfjprog --recover" to disable the approtect. See this blog

    Regards,
    Amanda

  • That makes complete sense, thanks. Do you know why our previous nRF52840 DK is able to run this nRF52832 code without ERROR? I feel like I would have been able to encounter/resolve this bug much sooner if the first DK board worked in the same way as this new one...Im curious to hear your thoughts.

    Also, I did what you suggested. I made sure to refer to the correct s140 SoftDevice for the nRF52840. The softdevice flashes perfectly to the DK board, as before. I am simplifying my script for step-by-step debugging, and all I try to do after flashing the softdevice is to flash the bootloader. I made edits to the script to also reference the correct bootloader, as you can see here:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #! /bin/bash
    # nRF52840
    ## Compile bootloader and application:
    boot_make='../nrf-sdk/examples/dfu/secure_bootloader/pca10056_s140_ble/armgcc/'
    boot=${boot_make}_build/nrf52840_xxaa_s140.hex
    softdevice='../nrf-sdk/components/softdevice/s140/hex/s140_nrf52_7.0.1_softdevice.hex'
    make -C "$boot_make"
    nrfjprog -e
    nrfjprog --program "$softdevice" --verify
    nrfjprog --program "$boot" --verify --log .
    nrfjprog --reset
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    Unfortunately, these new changes dont seem to help. I am still encountering the same ERROR from the nrfjprog command line tool, which you can see here:

    Lastly, I have included the log output from this failed flash for your reference. What could be causing this error? What should I try to debug this issue? Thank you so much for your help with this.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    [2022-Apr-20 17:43:01] [ info] --------------------------------------------------------------------------------
    [2022-Apr-20 17:43:01] [ info] nrfjprog --program ../nrf-sdk/examples/dfu/secure_bootloader/pca10056_s140_ble/armgcc/_build/nrf52840_xxaa_s140.hex --verify --log .
    [2022-Apr-20 17:43:01] [ info] nrfjprog version 10.12.1
    [2022-Apr-20 17:43:01] [ info] --------------------------------------------------------------------------------
    [2022-Apr-20 17:43:01] [debug] [ nRF0x0] - open_dll
    [2022-Apr-20 17:43:01] [ info] [ nRF0x0] - Load library at /Applications/Nordic Semiconductor/nrfjprog/libjlinkarm_unknown_nrfjprogdll.dylib.
    [2022-Apr-20 17:43:01] [ info] [ nRF0x0] - Library loaded, loading member functions.
    [2022-Apr-20 17:43:01] [ info] [ nRF0x0] - Member functions succesfully loaded.
    [2022-Apr-20 17:43:01] [ info] [Backend] - Logger callback at 0x10ec03300 registered in Segger backend logger.
    [2022-Apr-20 17:43:01] [ info] [ JLink] - [Info ] [JLink ] Logger callback at 0x10ec03300 registered in JLink logger.
    [2022-Apr-20 17:43:01] [debug] [nRFUnknown] - Just_open_dll_tagged_callback
    [2022-Apr-20 17:43:01] [debug] [Backend] - open_dll
    [2022-Apr-20 17:43:01] [ info] [Backend] - No J-Link DLL path was provided. Attempting to auto detect.
    [2022-Apr-20 17:43:01] [ info] [Backend] - Load library at /Applications/SEGGER/JLink/libjlinkarm.dylib.
    [2022-Apr-20 17:43:01] [ info] [Backend] - Library loaded, loading member functions.
    [2022-Apr-20 17:43:01] [ info] [Backend] - Member functions succesfully loaded.
    [2022-Apr-20 17:43:01] [debug] [Backend] - dll_version
    [2022-Apr-20 17:43:01] [ info] [Backend] - Segger dll version 7.60.a loaded.
    [2022-Apr-20 17:43:01] [debug] [Backend] - set_core_data
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi, 

    cor10 said:
    Could it be erasing all of the SoftDevice/Bootloader/AppImage/Settings that I just flashed, and this is why it complains about "No Bootloader"?

    Seems that might cause the issue. Can you try this post?

    -Amanda

  • I have looked at that post, which references this post. The post you shared has a solution for nrf52833 chips, so I stuck to the post that I just linked.

    I use both the SEGGER Embedded Studio Build & Debug method and the make/Makfile/nrfjprog CLI method of flashing code onto my custom device. As such, Im not sure which MDK version to download at this website. I ended up downloading the most recent GCC version, and replaced the previous mdk/ directory in the nrf-sdk with this new downloaded mdk/ directory. I then ran 'nrfjprog --recover' and then ran my flashing script (the one from above that uses Make). Everything compiles and flashes fine. But when I open the SEGGER Embedded Studio IDE and click Target>Connect, I get this same Pop-up message from the CTRL-AP every single time. The only way I can connect to the device is by running that ERASE ALL. Am I using this new mdk/ correctly? What else can I try?

    EDIT: All the stuff below is WRONG. I performed all of these steps after attempting to flash my SoftDevice/Bootloader/Application/Settings, WITHOUT having called 'nrfjprog --reset'. Now, when I make sure to run the reset command after the programming, I am back to the very beginning of this issue, which is: I cannot connect to the SEGGER Debugger without the CTRL-AP requiring that I ERASE ALL, and this erases all of my firmware I just flashed. So I get the "Bootloader Not Found" error again :( ...I did not think it would be this tough to transition from s132 to s140

    ==========================================================================

    ==========================================================================

    I was able to perform Step 3: CTRL-AP ERASEALL from that post, and this seemed to grant me access into the device so I can debug. However, I still get an ERROR with the value 0x4 like I originally experienced. But, one good thing is that this error is no longer thrown by this function:

    Fullscreen
    1
    APP_ERROR_CHECK(ble_dfu_buttonless_async_svci_init());
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Now that I can debug, I have tracked the issue to my ble_init() code. Specifically, in the file nrf_sdh_ble.c, my error arises in the function nrf_sdh_ble_enable():

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ret_code_t nrf_sdh_ble_enable(uint32_t * const p_app_ram_start)
    {
    // Start of RAM, obtained from linker symbol.
    uint32_t const app_ram_start_link = *p_app_ram_start;
    ret_code_t ret_code = sd_ble_enable(p_app_ram_start);
    if (*p_app_ram_start > app_ram_start_link)
    {
    NRF_LOG_WARNING("Insufficient RAM allocated for the SoftDevice.");
    NRF_LOG_WARNING("Change the RAM start location from 0x%x to 0x%x.",
    app_ram_start_link, *p_app_ram_start);
    NRF_LOG_WARNING("Maximum RAM size for application is 0x%x.",
    ram_end_address_get() - (*p_app_ram_start));
    }
    else
    {
    NRF_LOG_DEBUG("RAM starts at 0x%x", app_ram_start_link);
    if (*p_app_ram_start != app_ram_start_link)
    {
    NRF_LOG_DEBUG("RAM start location can be adjusted to 0x%x.", *p_app_ram_start);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    In my case, there are two issues.

    First, the ret_code value from sd_ble_enable(p_app_ram_start) is 0x4. This ERROR has come up before, and looking in ble.h, I can see that this is NRF ERROR NO MEM.

    Second, the first if-case in this function is TRUE, which means I should update my RAM start location. However, when I update the RAM start location to where it says in the code, I can no longer build my project because it says there is insufficient RAM space:

    This is strange because all this same code runs perfectly and fits perfectly within our previous nRF52832 device, and the nRF52840 has more space, so what could be causing this??

    Either way, I revert the RAM start to where it was previously. This builds and runs, but again, fails on the sd_ble_enable() function call with NRF ERROR NO MEM.

    What should I do now to get this code to run?

  • Hi, 

    cor10 said:
    The only way I can connect to the device is by running that ERASE ALL. Am I using this new mdk/ correctly? What else can I try?

    I add the disable function as that post I provided in the previous link into the bootloader, and it can disable the approtect and attach debugger without asking the erase. Can you try it?

    Once you program the images, you can run "nrfjprog --memrd 0x10001208" to check the value of APPROTECT register at 0x10001208. Value 0x5a means the DK is unlocked, then the segger would not ask to erase the kit to attach.   

    cor10 said:

    First, the ret_code value from sd_ble_enable(p_app_ram_start) is 0x4. This ERROR has come up before, and looking in ble.h, I can see that this is NRF ERROR NO MEM.

    Second, the first if-case in this function is TRUE, which means I should update my RAM start location. However, when I update the RAM start location to where it says in the code, I can no longer build my project because it says there is insufficient RAM space:

    What are the SD version and the ram start address in this situation? What is the debug log? It should give enough info to guide you to modify the ram start address.

    -Amanda

  • Hi Amanda,

    I add the disable function as that post I provided in the previous link into the bootloader, and it can disable the approtect and attach debugger without asking the erase. Can you try it?

    I downloaded the most recent MDK version. This new MDK has the exact same file 'system_nrf52_approtect.h' as the one in the link you shared. Are you suggesting I edit this file and remove the if-case that checks to see if defined(ENABLE_APPROTECT)? This way APPROTECT will never be used, is that correct?

    Once you program the images, you can run "nrfjprog --memrd 0x10001208" to check the value of APPROTECT register at 0x10001208. Value 0x5a means the DK is unlocked, then the segger would not ask to erase the kit to attach.  

    I have done this multiple times, but it doesnt matter. I check the value and it shows 0x5A after successfully programming all the images. So it seems like it will work. But then when I run the 'nrfjprog --reset' command, this APPROTECT seems to get re-enabled, because when I then try and connect the DK to the SEGGER IDE, the same pop-up message appears saying that "CTRL-AP indicates that the device is secured", and the only way I can actually connect is if I accept the pop-up message and ERASE everything....which brings me back to the 'No Bootloader Found' error.

    The issue with the RAM start adress doesnt matter that much (please see my EDIT comment above), because I only got to that point in the debugging process after I forgot to run the 'nrfjprog --reset' command (after performing the nrfjprog flash programming commands to write the SoftDevice/Bootloader/App/Settings). I believe it is necessary to run the 'nrfjprog --reset' command before the DK board can actually run the code, right?

    What are the SD version and the ram start address in this situation? What is the debug log? It should give enough info to guide you to modify the ram start address.

    SoftDevice: Version 16.0.0
    RAM start address, originally from my s132 version of the project: 0x20002270
    Suggested RAM start address from the debug log:  0x2003FFCC
    The debug output definitely gave me enough information to modify the RAM start address. Im not sure if you were able to read my entire last post, but even with this information, when I try to modify the RAM start address, I can no longer BUILD the project, because it says there is insufficient RAM space (please see attached screenshot from my last response).
    But this is important: This RAM start issue is not my problem. Right now I still cant even connect to the DK if I run the 'nrfjprog --reset' command. What do you suggest I try now? Thank you so much for your time.

  • Hi,

    cor10 said:
    Are you suggesting I edit this file and remove the if-case that checks to see if defined(ENABLE_APPROTECT)? This way APPROTECT will never be used, is that correct?

    No, I suggest you add the disable function to the secure_bootloader as that post. 

    cor10 said:
    I believe it is necessary to run the 'nrfjprog --reset' command before the DK board can actually run the code, right?

    Yes. I think that because the bootloader doesn't have the disable function, after 'nrfjprog --reset' the DK gets locked again. You can read the value at 0x10001208 to check.  

    Can you try this bootloader 5556.secure_bootloader_ble_s140_pca10056_debug.hex with the disable protect function? I added the function according to that post

    To build the diable protection, you might need to update MDK for SDK16.0.0, but don't modify the content of the files. 

    Here is the test file 287845.7z for nRF52840DK. You can run the bat file to run the image and attach the segger. 

    -Amanda

Reply
  • Hi,

    cor10 said:
    Are you suggesting I edit this file and remove the if-case that checks to see if defined(ENABLE_APPROTECT)? This way APPROTECT will never be used, is that correct?

    No, I suggest you add the disable function to the secure_bootloader as that post. 

    cor10 said:
    I believe it is necessary to run the 'nrfjprog --reset' command before the DK board can actually run the code, right?

    Yes. I think that because the bootloader doesn't have the disable function, after 'nrfjprog --reset' the DK gets locked again. You can read the value at 0x10001208 to check.  

    Can you try this bootloader 5556.secure_bootloader_ble_s140_pca10056_debug.hex with the disable protect function? I added the function according to that post

    To build the diable protection, you might need to update MDK for SDK16.0.0, but don't modify the content of the files. 

    Here is the test file 287845.7z for nRF52840DK. You can run the bat file to run the image and attach the segger. 

    -Amanda

Children
  • Ok, now I understand what you mean about that post you linked. When I clicked it at first, I went to the selected/verified solution of the post, which mentioned downloading the newest MDK version and so I tried that. The disable function you are referring to did not solve the problem for the person who made the post, so I overlooked that.

    Now that I understand, I added the disable function to my secure_bootloader solution in the main.c file at the beginning of the main() function, exactly as is suggested in the post you linked (I didnt use your .hex file because I have necessary configs set in the sdk_config.h file). However, this solution does not work for me. I notice that the #if statement appears inactive in my SEGGER IDE, so perhaps it is never run:

    Also, let me show you the series of commands I make from my terminal so you can see my situation more clearly:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    % nrfjprog --recover
    Recovering device. This operation might take 30s.
    Writing image to disable ap protect.
    Erasing user code and UICR flash areas.
    % nrfjprog --memrd 0x10001208
    0x10001208: 0000005A |Z...|
    % nrfjprog --memrd 0x40000558
    0x40000558: 00000000 |....|
    % ./dfu-bl-settings-nrf52840.sh
    DONE nrf52840_xxaa_s140
    DONE nrf52840_xxaa
    Note: Generating a DFU settings page with backup page included.
    This is only required for bootloaders from nRF5 SDK 15.1 and newer.
    If you want to skip backup page generation, use --no-backup option.
    Generated Bootloader DFU settings .hex file and stored it in: settings.hex
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    As you can see above, I first recover the DK and then perform a read operation to check the APPROTECT disable value. It is 0x5A so that seems good. Then I run my flash programming script (shared below for your reference). This flashes the newest secure_bootloader with the disable function added to main as you suggested. Once all the programming finishes, I again attempt to perform a read to check on APPROTECT, but it immediately tells me that I cannot talk to the DK unless I recover it again, aka APPROTECT is not disabled.

    Here is my programming script:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #! /bin/bash
    ## Compile bootloader and application:
    boot_make='../nrf-sdk/examples/dfu/secure_bootloader/pca10056_s140_ble/armgcc/'
    boot=${boot_make}_build/nrf52840_xxaa_s140.hex
    softdevice='../nrf-sdk/components/softdevice/s140/hex/s140_nrf52_7.0.1_softdevice.hex'
    app_make='../nrf-sdk/examples/ble_peripheral/ble_app_technolingus/pca10056/s140/armgcc/'
    app=${app_make}_build/nrf52840_xxaa.hex
    make -C "$boot_make"
    make -C "$app_make"
    nrfutil settings generate --family NRF52840 --application "$app" --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex
    nrfjprog -e
    nrfjprog --program "$softdevice" --verify
    nrfjprog --program "$boot" --verify --log .
    nrfjprog --program "$app" --verify
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Regardless of these efforts, I was able to find a (hacky) solution!!! If I write 0x5A to the APPROTECT.DISABLE register (0x40000558), I am able to access the DK device even after running the 'nrfjprog --reset' command. I also make sure that the value of UICR.APPROTECT register (0x10001208) is 0x5A.

    Fullscreen
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    So, I can now successfully connect to the SEGGER IDE for debugging and my code is finally running! HOWEVER, with this solution, I notice that whenever my DK device is powered OFF and then back ON again, the DK goes back into the APPROTECT state and locks me out. So if I turn my device OFF, I can no longer connect to the SEGGER IDE for debugging, and I have to recover the device and run my programming script again. Even though I do not re-write to the APPROTECT.DISABLE register, I notice that the value is still 0x5A after erasing everything and re-programming. Do you know why this happens when the device is turned OFF? Is there a way I can avoid this behavior after power OFF? Or is there a more elegant solution?

    Thank you :)

  • Hi, 

    You can add "APPROTECT_HW_DISABLE" to Project -> Preprocessor -> Processor Definitions to enable the tag. Once programming the bootloader with  APPROTECT_HW_DISABLE, it will write the 

    cor10 said:
    Even though I do not re-write to the APPROTECT.DISABLE register, I notice that the value is still 0x5A after erasing everything and re-programming. Do you know why this happens when the device is turned OFF? Is there a way I can avoid this behavior after power OFF? Or is there a more elegant solution?

    Not sure why caused that. 

    cor10 said:
    I notice that whenever my DK device is powered OFF and then back ON again, the DK goes back into the APPROTECT state and locks me out. So if I turn my device OFF, I can no longer connect to the SEGGER IDE for debugging, and I have to recover the device and run my programming script again. Even though I do not re-write to the APPROTECT.DISABLE register, I notice that the value is still 0x5A after erasing everything and re-programming.

    What is the value of 0x10001208 after powered OFF and ON? Guess the value at UICR.APPROTECT register is written by your image. It should use the bootloader with APPROTECT_HW_DISABLE that can write  UICR.APPROTECT register (0x10001208) to 0x5A.

    -Amanda

  • Amanda, thank you for sticking with me through this battle. With that Preprocessor Definition, the approtect_hw_disable() #if-statement runs properly and allows access to the debugger every time now.

    Also, I figure that the value of the APPROTECT.DISABLE register seems to be RESET to 0x0 after a power OFF/ON, which is why I was seeing the APPROTECT come up again. But now with the new working secure_bootloader, the device disables APPROTECT functionality even after being turned OFF/ON.

    Thank you, I have learned a lot!

    Cheers,

    Corten