Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12748 Discussions

Updating application in EPCS via UART

Altera_Forum
Honored Contributor II
2,158 Views

My customer requires the ability to download updated application code via UART. 

 

We use the JTAG tools to store the FPGA configuration data and app code in EPCS flash memory before shipping. The files are converted to flash S record format. 

 

If I understand the boot process correctly, the application code is located in the next EPCS byte after the FPGA configuration data. Is this correct? 

How can I determine where the application data starts? I"ve read in the forums that there is a header in the sof file that contains this data. Where is this header described? 

 

Are the configuration and application files stored in S record format? Or are they unpacked before writing to the EPCS flash? 

 

If the app code is stored in the next byte of EPCS, to save a new app I presume I would need to preserve the last EPCS block of config data, correct? 

 

Thanks in advance for your help. 

 

Dan
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
850 Views

There are a lot of posts in the forum about how to do this. 

The basics: 

1 - Application code is unpacked before storing in the flash (not in S-record format). So you can safely convert the application file to binary and deploy that. 

2 - Application code is typically located immediately following the FPGA configuration data. This is simply because the default EPCS bootloader will search for the end of the config data and begin boot loading from there. The algorithm for finding the end of the fpga config data can be discovered by looking at the current EPCS bootloader found in: 

C:\altera\91\nios2eds\components\altera_nios2\boot_loader_sources\boot_loader_epcs_bits_<device_family>.S 

 

Now some things to consider about remote update ... 

1 - What happens if you corrupt the application code while you're downloading new code? Usually you provide a safe boot app and a user boot app. You never touch the safe boot app so that you can default back to it if remotely updating your user application fails. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
850 Views

Thanks, Jake. I stumbled on boot_loader_epcs_bits_cyclone.S last night. To summarize the algorithm: 

 

- read the config data in EPCS memory a byte at a time, starting at offset zero 

- discard 0xFF for an arbitrarily long time 

- if you find anything other than 0x56, this is not config data 

- discard 4 bytes 

- the next 4 bytes contain the config data size, but the bits are reversed on a byte basis 

- the size is in bits, round up to the next byte 

 

Once I have the config data size, I need to preserve the last EPCS erase block, so I plan on reading in the last part of the config data, prepending it to my app code, and then writing to EPCS. 

 

We've already planned on having two sets of configuration data and application code to boot from, but thanks for the tip. We are checking CRC16 on the downloaded data before writing. 

 

The boot source says "Quartus stores the bytes in bit reversed order". Is this true for every byte in EPCS, or just the config data length? Do I need to reverse the bits in my app code before writing? 

 

Dan
0 Kudos
Altera_Forum
Honored Contributor II
850 Views

The NIOS application code should NOT be bit-reversed. The FPGA configuration image MUST be bit reversed. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
850 Views

Our sof file is 1,839,715 bytes long. Multiplying by 8 bits per byte, the length in EPCS should be around 0x00E09318. Bit reversing on a byte basis yields 0x0007C918. The flash sof file starts with: 

 

S0110000675477732E736F662E666C61736897 

S32500000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA 

S3250000002056EFEFAFEFEFEFCFDFDF9FDFDF8F9F9FBFBF9F9FFFBFDFBFDFDFDFFFBFBF9F9FE3 

The 4-7th bytes after the "56" are 0xEFEFCFDF. Bit reversing gives a length of 0xF3F7F7F7, obviously too large. No zeroes appear after the 56. 

 

What do I not understand? 

 

Dan 

0 Kudos
Altera_Forum
Honored Contributor II
850 Views

Hi Dan, in the past we had the same requirement with remote firmware update. Our solution now is (similar as described from jakobjones) to use 2 images for FPGA configuration data as well as for the firmware. 

The first (safe image) is stored at address 0x0 in the EPCS. The firmware follows the configuration data, we use the default boot copier for that. 

The second (application image) is stored at a fix address in EPCS64. We use actually 0x240000 for the FPGA configuration data and 0x440000 for the application firmware. 

For the application I have changed the default boot copier to load programm code from a fixed address. 

To boot the application image we use the alt_remote_update function. The safe firmware image reads the remote_update status register. In case of power on (status = 0) the remote_update block is configured with the EPCS page address where the application configuration is stored and the watchdog activated. Then the reconfigure input is set to '1'. 

If reconfigure not succeeds the safe image is loaded again and it is possible to change the application image over the remote interface. 

It sounds complicated but it works very robustly. An advantage is that you can easy change the firmaware or FPGA image and don't have to make a backup of the last configuration data sector. 

 

Jens
0 Kudos
Altera_Forum
Honored Contributor II
850 Views

It seems I was looking at the code for the wrong device, we use a cyclone 3. Attempting to decipher boot_loader_epcs_bits_sii_siii_ciii.S

0 Kudos
Altera_Forum
Honored Contributor II
850 Views

// 3) If we arrive at this point we have assume that there is valid-looking 

// configuration data. Extract its length. If the extracted length is all  

// "1", assume that we're looking at erased flash. In this case, we have 

// no other recourse than to hang. 

// 

// The configuration bitstream length is encoded in a particular bit of a  

// run of bytes. Total length field is 32 bits, which goes from CB Option  

// bits 86..55 corresponding to bit[3] of byte[39] to byte[33] (for the most  

// significant 7 bits) followed by the range of bits made up of bit[2] of  

// bytes[72..48].  

//  

// The note about EPCS bit reversal still applies (so we're really looking  

// at bits[4] and [5], respectively. 

 

 

My best guess is to grab a single bit from 32 different bytes to build the 32 bit length value. The first 7 bits are found in bit 4 of byte 33 thru 39. The remaining 25 bits are found in bit 5 of bytes 48 thru 72. Astoundingly complex... 

 

Dan
0 Kudos
Reply