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

Application failing validation in bootloader

I'm working with a development prototype board with the nRF52832.  It is connected to a main processor in our design over UART.  We are working towards being able to do the DFU process from our main processor connected over the UART.  I have a functioning bootloader, main application, and softdevice on the board, loaded through the SWI interface with Segger Embedded Studio.  The bootloader is based on the serial secure DFU bootloader example in SDK 14.2.0.  I used nrfutil to create a bootloader settings page and flashed that to the board using Segger download tool.  However, when the bootloader comes up, it fails to validate the main app and will not jump to the main app if with the settings page on the board.  After further debugging, I've narrowed it down to this code below in nrf_dfu_app_is_valid() where it fails the s_dfu_settings.bank_0.bank_code check.  The CRC check is successful.  If I comment out ONLY the bank_code check, the validation is successful, meaning the CRC is fine. 

    if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP)
    {
       // Bank 0 has no valid app. Nothing to boot
       NRF_LOG_DEBUG("Return false in valid app check");
       return false;
    }

I've not been able to figure out why that bank_code check fails since the bootloader settings output seemed to indicate all was good including the bank Code check:

C:\Python27\Scripts\nrfutil settings generate --family NRF52 --application nRF52_App.hex --application-version 0 --bootloader-version 1 --bl-settings-version 1 bootloader_setting.hex

Generated Bootloader DFU settings .hex file and stored it in: bootloader_setting.hex

Bootloader DFU Settings:
* File: bootloader_setting.hex
* Family: nRF52
* Start Address: 0x0007F000
* CRC: 0xFF49BF5C
* Settings Version: 0x00000001 (1)
* App Version: 0x00000000 (0)
* Bootloader Version: 0x00000001 (1)
* Bank Layout: 0x00000000
* Current Bank: 0x00000000
* Application Size: 0x0000DD08 (56584 bytes)
* Application CRC: 0x1AD351F3
* Bank0 Bank Code: 0x00000001

Any ideas why this is failing?

Parents
  • Hi,

    The bootloader settings page you have generated seems correct and valid. However, it is clearly not present on your device when you debug it (as you see CRC is 0). Therefore, I have a few questions:

    • How did you program the bootloader settings page? I recommend that you program it using nrfjprog with the --sectorerase option. If you do it as the last file you program you can be confident that it is not overwritten by anything else.
    • Can you verify that the settings page is programmed correctly using "nrfjprog --verify <settings.hex>"?
  • I've been using Segger Embedded Studio to flash the .hex files (Target->download file->download Intel Hex File).  I issued this command to get a hex dump below (nrfjprog -f nrf52 --memrd 0x7F000 --n 256).  I've also reattached the the bootloader settings file to compare since it may have changed since the last one.  It looks like the data is the same but in a different byte order.  I'm trying to resolve that in my mind (endian-ness) but I think that is okay? 

    The CRC check is still returning 0 thus invalidating the application. I've modified the nrf_dfu_app_is_valid() code to return false if the CRC value == 0, else return true. It returns false (and doesn't turn on an LED). That is the only check in the function (see code below).  I know the bootloader is running because I flash another LED if the nrf_power_gpregret_get() returns the value set in the application before the reset. The only explanation that I have is that it's not reading the correct location in flash for the bootloader settings page. Would that be a possibility and how could I confirm that is or is not the problem? I have not been able to getting logging or debugging working in the bootloader app (still trying). 

    bool nrf_dfu_app_is_valid(void)
    {
        NRF_LOG_DEBUG("Enter nrf_dfu_app_is_valid");
    //  if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP)
    //  {
    //     // Bank 0 has no valid app. Nothing to boot
    //     NRF_LOG_DEBUG("Return false in valid app check");
    //     return false;
    //  }
    
        if (s_dfu_settings.bank_0.image_crc == 0)
        {
            return  false;
        }
    //  if (s_dfu_settings.bank_0.image_crc != 0)
    //  {
    //      uint32_t crc = crc32_compute((uint8_t*) CODE_REGION_1_START,
    //                                   s_dfu_settings.bank_0.image_size,
    //                                   NULL);
    //
    //      if (crc != s_dfu_settings.bank_0.image_crc)
    //      {
    //          // CRC does not match with what is stored.
    //          NRF_LOG_DEBUG("Return false in CRC");
    //          return  false;
    //      }
    //  }
    
        NRF_LOG_DEBUG("Return true. App was valid");
        return true;
    }
    

    nrfjprog -f nrf52 --memrd 0x7F000 --n 256

    0x0007F000: A54A1F93 00000001 00000001 00000001   |..J.............|
    0x0007F010: 00000000 00000000 0000DD08 1AD351F3   |.............Q..|
    0x0007F020: 00000001 00000000 00000000 00000000   |................|
    0x0007F030: 00000000 00000000 00000000 00000000   |................|
    0x0007F040: 00000000 00000000 00000000 00000000   |................|
    0x0007F050: 00000000 00000000 00000000 FFFFFFFF   |................|
    0x0007F060: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F070: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F080: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F090: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|

    I also verified the settings page file as requested:

    nrfjprog --verify bl_settings_only.hex
    Parsing hex file.
    Verifying programming.
    Verified OK.

    bl_settings_only.hex
Reply
  • I've been using Segger Embedded Studio to flash the .hex files (Target->download file->download Intel Hex File).  I issued this command to get a hex dump below (nrfjprog -f nrf52 --memrd 0x7F000 --n 256).  I've also reattached the the bootloader settings file to compare since it may have changed since the last one.  It looks like the data is the same but in a different byte order.  I'm trying to resolve that in my mind (endian-ness) but I think that is okay? 

    The CRC check is still returning 0 thus invalidating the application. I've modified the nrf_dfu_app_is_valid() code to return false if the CRC value == 0, else return true. It returns false (and doesn't turn on an LED). That is the only check in the function (see code below).  I know the bootloader is running because I flash another LED if the nrf_power_gpregret_get() returns the value set in the application before the reset. The only explanation that I have is that it's not reading the correct location in flash for the bootloader settings page. Would that be a possibility and how could I confirm that is or is not the problem? I have not been able to getting logging or debugging working in the bootloader app (still trying). 

    bool nrf_dfu_app_is_valid(void)
    {
        NRF_LOG_DEBUG("Enter nrf_dfu_app_is_valid");
    //  if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP)
    //  {
    //     // Bank 0 has no valid app. Nothing to boot
    //     NRF_LOG_DEBUG("Return false in valid app check");
    //     return false;
    //  }
    
        if (s_dfu_settings.bank_0.image_crc == 0)
        {
            return  false;
        }
    //  if (s_dfu_settings.bank_0.image_crc != 0)
    //  {
    //      uint32_t crc = crc32_compute((uint8_t*) CODE_REGION_1_START,
    //                                   s_dfu_settings.bank_0.image_size,
    //                                   NULL);
    //
    //      if (crc != s_dfu_settings.bank_0.image_crc)
    //      {
    //          // CRC does not match with what is stored.
    //          NRF_LOG_DEBUG("Return false in CRC");
    //          return  false;
    //      }
    //  }
    
        NRF_LOG_DEBUG("Return true. App was valid");
        return true;
    }
    

    nrfjprog -f nrf52 --memrd 0x7F000 --n 256

    0x0007F000: A54A1F93 00000001 00000001 00000001   |..J.............|
    0x0007F010: 00000000 00000000 0000DD08 1AD351F3   |.............Q..|
    0x0007F020: 00000001 00000000 00000000 00000000   |................|
    0x0007F030: 00000000 00000000 00000000 00000000   |................|
    0x0007F040: 00000000 00000000 00000000 00000000   |................|
    0x0007F050: 00000000 00000000 00000000 FFFFFFFF   |................|
    0x0007F060: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F070: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F080: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F090: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|
    0x0007F0F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF   |................|

    I also verified the settings page file as requested:

    nrfjprog --verify bl_settings_only.hex
    Parsing hex file.
    Verifying programming.
    Verified OK.

    bl_settings_only.hex
Children
  • Hi,

    The bootloader linker configuration defines where the bootloader settings are located, which is typically the last flash page. If you use GCC you can see this in the bootloader linker script (secure_dfu_ble_gcc_nrf52.ld). For instance in <SDK 14.2>\examples\dfu\bootloader_secure_ble\pca10040\armgccsecure_dfu_ble_gcc_nrf52.ld you have this line which defines the bootloader settings address:

      bootloader_settings_page (r) : ORIGIN = 0x0007F000, LENGTH = 0x1000

    This start address should match the start address of the bootloader setting .hex file you use (You can see a graphical representation of the .hex file using the nRF Connect programmer app).

Related