0 Replies Latest reply on Apr 18, 2018 12:06 AM by tonoc_2194386

    DCT read problem during migration from SDK 4.1 to 6.1

      Hi,

       

      I am working with ISM43903 modules that currently run SDK 4.1.

      When I use OTA2 mechanism to upgrade the software to one based on SDK 6.1 I get into trouble.

      After some digging I think I have found why.

       

      During OTA2 upgrade bootloader and failsafe app are not upgraded, so they stay as they were in SDK 4.1.

      Extract app and main app are upgraded to SDK 6.1, so when they write DCT, it becomes marked with new version.

       

      DCT 6.1 version is set to in wiced_dct_finish_new_dct() in wiced_dct_external_common.c as below:

       

      new_dct_version->version            
      = DCT_BOOTLOADER_SDK_CURRENT;
      
      new_dct_version->sequence++;                        
      /* always increment the sequence */
      
      

       

      Now when bootloader or failsafe (from SDK 4.1) tries to read OTA2 config structure  from DCT written with software basaed on SDK 6.1 it gets to the function wiced_dct_get_current_address(), which in turn reads version of both DCTs using wiced_dct_validate_and_determine_version().

      During determining version wiced_dct_minimal_check_dct_version() is called, which returns WICED_FALSE (we are reading DCT written by SDK 6.1 using code from SDK 4.1).

       

      In this case the following code is used:

      this_dct_version = DCT_BOOTLOADER_SDK_VERSION;
      goto _version_test_done_and_deinit_sflash;
      

       

      What is important, in such a case CRC is not checked and sequence number is not checked, only version from old SDK is returned (even for non-current DCT)

       

      The code in wiced_dct_get_current_address() that decides which DCT is current looks as below:

          use_dct1 = WICED_TRUE;
          if ((dct1_sdk_version == DCT_BOOTLOADER_SDK_UNKNOWN) && (dct2_sdk_version == DCT_BOOTLOADER_SDK_UNKNOWN))
          {
              goto _both_dcts_invalid;
          }
          else if ((dct1_sdk_version != DCT_BOOTLOADER_SDK_UNKNOWN) && (dct2_sdk_version != DCT_BOOTLOADER_SDK_UNKNOWN))
          {
              /* Both DCTs are valid
               * determine most recent using version # (and sequence # if versions are the same)
               */
              if (dct1_sdk_version < dct2_sdk_version)
              {
                  use_dct1 = WICED_FALSE;
              }
              else if (dct1_sdk_version == dct2_sdk_version)
              {
                  /* if one of the version data has initial_write == 1, it is the correct one to use! */
                  if ((dct2_initial_write != 0) && (dct2_initial_write != 0xFF))
                  {
                      use_dct1 = WICED_FALSE;
                  }
                  else if ((dct1_initial_write != 0) && (dct1_initial_write != 0xFF))
                  {
                      use_dct1 = WICED_TRUE;
                  }
                  else if (dct1_sequence < dct2_sequence)
                  {
                      use_dct1 = WICED_FALSE;
                  }
              }
          }
          else if (dct1_sdk_version == DCT_BOOTLOADER_SDK_UNKNOWN)
          {
              /* dct2 is valid, use that */
              use_dct1 = WICED_FALSE;
          }
      

       

      In case when both DCTs were written with SDK 6.1 software and are read with SDK 4.1 software (bootloader or failsafe) we get dct1_sdk_version and dct2_sdk_version set to 0x401, dct1_sequence and dct2_sequence set to 0, so we end up with use_dct1 set to TRUE. But as CRC is not checked and sequence number not checked, DCT1 may be invalid in fact. So in this case bootloader or failsafe ends up with reading incorrect OTA2 boottype.

       

       

      So the question is: how to make this upgrade working correctly ? (Without upgrading bootloader and failsafe on already produced devices)