6 Replies Latest reply on Jul 27, 2020 12:17 AM by HemanthR_06

    Failsafe Firmware on SPI

    GeLe_3002426

      Hi, was following this example (FX3 Fail Safe Firmware Update ) and code but modified this code to boot to SPI.

       

      So, firstly, what works. As demonstrated in the above example, I have separated my EEPROM into multiple sections with these hardcoded addresses

       

      EEPROM Memory organization:

      START ADDRESS

      CONTENT

      0x0000

      Second Stage Boot-loader image

      0x2800

      Primary Firmware image

      0x34800

      Secondary Firmware image

      0x2600(Single Byte)

      Firmware Update Byte (0x00 – Primary FW, 0xFF – Secondary FW)

       

      Using the Imgcombine.zip file, I made something that did not require C# and verified that it writes multiple image files into a single image file. That is, I write the Bootloader to 0x0, the Primary firmware image to 0x2800, and the Secondary firmware image to 0x34800.

      I've used the Cypress flash tool to download this image to SPI

      By flipping the Firmware Update byte, I have successfully used the second stage bootloader into the Primary or the Secondary firmware images.

       

      What has NOT been successful is when I boot to the Primary firmware image and try to write a new secondary image. While running the primary image, I have a function that writes a new image that it transfers over USB and writes to SPI address 0x34800. I have verified that the SPI writes are correct (doing a read after the entire contents are written and comparing), and I have also verified that the entire 180+kB image is correctly written byte for byte into SPI starting @ 0x23800.

       

      On reset, the software does not boot.

       

      In stranger behaviour, when I boot to the secondary firmware (starting at 0x34800) and write the USB image to the SPI starting at 0x2800, the software hangs mid write and when power cycled, the hardware I assume has tried to boot from SPI but has done a failsafe fallback to USB. Seems like I'm overwriting the active RAM instance??

       

      Lastly, I have used my read utilities to pull the first 200k off my SPI EEPROM. Other than the first four bytes ( 0x43, 0x59, 0x1C, 0xB0) the data between what is written on the SPI and the image that I flashed on using the Cypress utility is different!

       

      This suggests that the SPI flash process does something to the image?

      Is this documented anywhere?

      What do I need to do with a compiled .img file to directly burn it to a specific SPI address and have it run?

        • 1. Re: Failsafe Firmware on SPI
          HemanthR_06

          Hi,

           

          Regarding the comments:

          "By flipping the Firmware Update byte, I have successfully used the second stage bootloader into the Primary or the Secondary firmware images.":

           

          1. Can I know how you performed the data toggle at location 0x2600:

          - Is it through your primary/ secondary firmware? Or

          - By generating the combined image file to contain different data @0x2600?

           

          2. After you program flash @0x34800 using the running primary firmware, I note that you have a read routine in the primary firmware which verified if the image is correctly written - which shows it correctly programmed the Flash as you said. After this, you mentioned that software does not boot. So, is it coming up as Bootloader device?

           

          Regards,

          Hemanth

          • 2. Re: Failsafe Firmware on SPI
            GeLe_3002426

            Thanks for the quick reply Hemanth

             

            1) Good question -

            I have written to 0x2600 only when I generate the combined image. I just tried writing in primary / secondary firmware and it goes back to the bootloader

             

            2) Yes - here is a dump from my syslog verifying that once I write to the 0x2600 byte, the device comes up as a bootloader.

            Mar 29 12:22:45  kernel: [  318.484492] usb 2-3: New USB device found, idVendor=04b4, idProduct=4720, bcdDevice= 0.00

            Mar 29 12:22:45  kernel: [  318.484500] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0

            Mar 29 12:22:45  kernel: [  318.484504] usb 2-3: Product: FX3

            Mar 29 12:22:45  kernel: [  318.484508] usb 2-3: Manufacturer: Cypress

            Mar 29 12:22:45  mtp-probe: checking bus 2, device 13: "/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3"

             

             

            I've included a brief section of the code here that controls the byte. The functions waitForSpiStatus and spiReadBytes are from the spi_test.c file from https://community.cypress.com/servlet/JiveServlet/download/38-42518/Fx3BootAppGcc_Project.zip

             

            #define BOOT_INDEX 0x2600

            uint8_t glDataBuf[5];

             

             

            else if ((wValue == 0x0699)) {

            uint8_t flipped_bit[1];

            status = CyU3PUsbGetEP0Data(1, glDataBuf, &readCount);

            status = waitForSpiStatus();

            status = spiReadBytes( BOOT_INDEX,4,glDataBuf);

            status = CyU3PDebugPrint(4, "\n\rFlipping boot index from %x ",glDataBuf[0]);

            flipped_bit[0]=( (glDataBuf[0]==1)?0:1);//toggle the bit on the boot index

            status = CyU3PDebugPrint(4, " to %x ",flipped_bit[0]);

            do {

            status = spiWriteEnable();

            status = sectorErase(BOOT_INDEX);

            status = waitForSpiStatus ();

            status = spiWriteBytes(BOOT_INDEX, 1, flipped_bit);

            status = waitForSpiStatus ();

            status = spiReadBytes( BOOT_INDEX,1 ,glDataBuf);

            status = CyU3PDebugPrint(4, "\n\rRead Boot Index is now:%x (desired %x) ",glDataBuf[0], flipped_bit[0]);

            } while (glDataBuf[0]!= flipped_bit[0]);

            isHandled = CyTrue;

            } else if ((wValue == 0x0670)) { //read firmware image

            • 3. Re: Failsafe Firmware on SPI
              HemanthR_06

              Hi,

               

              In the sys log above, the pid shown is of Boot programmer. so, is that the log after toggling the byte @0x2600 using bootprogrammer firmware and then board is reset to check if it boots well?

               

              Regards,

              Hemanth

              • 4. Re: Failsafe Firmware on SPI
                HemanthR_06

                Adding to my previous comment, you can try this:

                1. Program the combined image such that primary boots

                2. Ensue primary fw is running

                3. Now through primary fw, change the 0x2600 byte

                4. Now make Fx3 boot as USB Bootloader device (PID 0x00F3)

                5. Use firmware example in the below path to read out the byte @0x2600. Verify whether it is as expected.

                $Fx3_Sdk_Install_Path$\1.3\firmware\serialif_examples\cyfxusbspiregmode

                 

                Regards,

                Hemanth

                • 5. Re: Failsafe Firmware on SPI
                  GeLe_3002426

                  Thanks again for the reply

                  To quickly answer your question, yes it shows as a bootloader on reset, however, I've uncovered the "reason": the sectorErase call actually deletes the entire sector, and being at 0x2600 with the primary firmware at 0x2800, they are both deleted with this call. In fact the entire sector from 0x00000 to 0x0FFFF is erased with this call, thus there is an invalid firmware image. Fall back is that it goes to bootloader.

                   

                  So in good news, moving everything to the following addresses makes the code work "ALMOST" as expected:

                  EEPROM Memory organization:

                  START ADDRESS

                  CONTENT

                  0x0000

                  Second Stage Boot-loader image

                  0x10000

                  Firmware Update Byte

                  0x20000

                  Primary Firmware image

                  0x50000

                  Secondary Firmware image

                   

                  I can now flash the board through my application, check that the firmware update byte has been flipped. On reboot, it boots into the secondary firmware!

                   

                  Now the strange behaviour: on a cold power on (i.e. unplug USB cable and then re-plug it back in) the boot loader hangs, until I hit the reset button (currently using the Denebola board which wires the manual reset button to C5 (RESET) on the CX3) when the board boots correctly.

                   

                  If the Firmware Update Byte is at 0x2600, the board boots fine. However, this cannot be the solution as I cannot then write to 0x2600 as I need to erase prior to writing and my erase would delete the entire sector.

                   

                  I put UART debug code in and writing debug messages to UART, the problem disappeared. Once I remove the UART prints, the hang returns.

                  Any suggestions on killing this Heisenbug?

                  • 6. Re: Failsafe Firmware on SPI
                    HemanthR_06

                    Hi,

                     

                    Based on the above comments, problem most likely is because of EEPROM content getting changed incorrectly. The change which occurs by adding/ removing UART debug code, is the code size.

                     

                    Regards,

                    Hemanth