This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Porting the Z-Stack OTA to a custom platform

Other Parts Discussed in Thread: MSP430F5529, Z-STACK, CC2531EMK

Hi everybody,

I've ported ZStack-EXP5438-2.5.1 to a custom platform using a MSP430F5529. Now I'm trying to port the OTA feature to this platform. I have encountered some problem on my way.

I followed the the Z-Stack OTA Upgrade User's Guide.pdf to port the SampleSwitchOta example.

I tried to port the OTA dongle, but it failed since the 5529 does not provide a sufficient flash memory space; 128KB compare to 256KB for 5438. I decided to use the CC2531EMK as OTA dongle (OTA server), which properly works.

I encountered my first problem with the OTA linker file which I have ported to the 5529 reality. The following post talk about it.

I had to add an external memory chip to obtain a sufficient memory space for the downloaded image. So I implemented and integrated an external memory driver. The driver properly works.

I have tried an OTA upgrade with this system, but it failed. The OTA client (MSP430F5529) receives the entire image, but I get the ZCL_STATUS_INVALID_IMAGE error.

The cause of this error is the CRC validation. I do not understand why it occurs. With breakpoints, I have tried to follow the execution and it looks like, when the program reads the OTA preamble into the external memory, that it reads only zero. This is strange because I tested to write and read the external memory with the hal_xnv function, which properly work. Does anyone have an idea?

  • Can you confirm that when the OTA image is built that the CRC is placed in HAL_OTA_CRC_OSET, and it is the same place where it is being read from in HalOTAChkDL()?

    Regards,
    TC.
  • Hi TopCat,

    Thank you for answering. I verified that the CRC is located at the expected memory space. I found a problem with the SPI communication. The MISO pin was not properly configured as a peripheral pin, so it could not receive any data. I fixed this problem. Now the OTA download is successfully completed, but the system does not restart with the new image, actually, it does not restart at all, even after a power off/power on. Any idea?

  • It can take some time to copy from external NV to Flash, can you put a break point in the bootloader to see what is happening?

    TC.
  • I put a break point in the bootloader to observe the problem. The PC register get corrupted, but I did not find the cause. It is loaded with the 0xD0000 value. There is no memory space at that address. I could not observe what assembly instruction had loaded the PC register when the problem occurred suddenly. Perhaps an interrupt since the problem does not occur at the same line of code at each time. I'm still seeking how to resolve this issue. Any ideas?

    This picture shows the line of code right before it happened.

    This picture shows the problem when the PC register has been corrupted.

  • Hi,


    I've implemented OTA functionality and did find some things that I needed to change to have it work correctly, so maybe there's some value in this:

    1) Using a different external SPI flash chip and properly waiting for busy flash:

    In Z-Stack:

    XNV_SPI_BEGIN();
      do
      {
        xnvSPIWrite(XNV_STAT_CMD);
      } while (XNV_SPI_RX() & XNV_STAT_WIP);
      XNV_SPI_END();

    on the chips I tested, this returns immediately (nothing is really waited for). This leads to sometimes / most of the time corrupted data. To do busy-wait for flash reliably, I use:

    XNV_SPI_BEGIN();
    XNV_SPI_TX(XNV_STAT_CMD);
    XNV_SPI_WAIT_RXRDY();
    do {
      XNV_SPI_TX(0);
      XNV_SPI_WAIT_RXRDY();
      } while (XNV_SPI_RX() & XNV_STAT_WIP);
    XNV_SPI_END();

    In zcl_ota.c this is suspect:

              // Element is complete
              if ( zclOTA_ElementTag == OTA_UPGRADE_IMAGE_TAG_ID )
              {
                // The serial flash can take up to 25 ms before it is ready for a read
                uint32 k;
                for ( k=0; k<0xffff; k++ )
                {
                  asm ( "NOP" );
                }

                // When the image is complete, verify CRC
                if ( HalOTAChkDL ( HAL_OTA_CRC_OSET ) != SUCCESS )

    When we wait for the flash properly (by checking the WIP bit in the right way) - there is no need for a delay loop, which is unreliable.

     

    2) The CRC algorithm

    The algorithm used is from IAR's technical note 91733, but in Z-Stack the initial seed with 0x0000 is omitted. So the CRC differs from the one calculated with standard CCITT 0x1021.

    (OTAConverter.exe uses the same non-standard algorithm, so check that the CRC algorithm and params for your image, bootloader and flash are the same).

     

    HTH,

    Sjef.

     

     

     

     

     

     

  • Hi Sjef de Krijger,

    Thank you for your answer.

    I made some further verification and I found my problem.

    In my previous post, I forgot to mention some information. There is a bug (I think this is a bug) within the bootMain function in hal_ota.c. Actually, when the image is completely downloaded, a CRC check is achieved through the HalOTAChkDL function. The CRC was already valid. This means the OTA transfer was fully successful. After the reboot, the bootMain function verifies whether there is another image, if so, it calls dl2rc to copy the downloaded image from the external memory through SPI to the internal flash memory. When attempting to execute a SPI transfer, the function blocked because  XNV_SPI_INIT was not called within the bootMain function, so the SPI was not initialized.

    From this, I was able to copy the downloaded image into the flash, to verify that the calculated CRC was valid, but it did not boot.

    In hal_ota.h, I modified HAL_OTA_DL_MAX, HAL_OTA_DL_OSET and HAL_OTA_DL_SIZE to correspond with the external memory chip specifications.
    In hal_ota.c, dl2rc copies 512 bytes at each copy loop before verifying whether LO_ROM_END has been reached. Therefore, (LO_ROM_END - LO_ROM_BEG + 1) must be a multiple of 512 to make sure not copying outside the LO_ROM space. I modified LO_ROM_END from hal_ota.h and ota.xcl to comply with this specification. This was the solution I was looking for to make properly reboot the system. Further, this can perhaps be modified to avoid losing memory space.

    Thank to the E2E and TI staff members that participate to this community, your support is very helpful.

  • Simon,
    Thank you for posting your findings. Can you clarify the bug you may have found? The OTA is working on our HW platforms.

    regards,
    TC.
  • Hi TopCat,

    It was not really a bug, maybe more a function call missing when using an external FLASH memory as secondary storage. Since the stack supports the use of an external memory (hal_xnv.c) to store the new program version downloaded from OTA, I would have expected, within the file hal_ota.c, function bootMain, between the HAL_BOOT_INIT AND vddWait function calls, to retrieve the following function call to initialize the SPI driver:
    #if HAL_OTA_XNV_IS_SPI
      XNV_SPI_INIT();
    #endif

    Of course, as the TI MSP5438CC2520 (2.5.1) Z-Stack splits the internal memory to use the second memory space as secondary storage, this problem does not occur since the SPI communication is not use to communicate with the internal memory.
    The problem does not occur either with the CC2530EB (2.5.1a) Z-Stack since the equivalent file contains the function call previously mentioned.  

    I hope this clarify my previous post.

    Regard,