- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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