Forum Discussion
Altera_Forum
Honored Contributor
16 years agoRunning multiple images from EPCS (Factory & User)
Hi,
I am aware that there have been many topics on subjects similar to these. I have read many of them and tried to make use of the suggestions and advice offered there but am still having a few issues. My aim is to have a fixed factory image at the base of the EPCS device which will allow a User image to be remotely programmed to a higher location in the EPCS. I have hardware and software images (based on AN429) which are able to write designs to the EPCS memory. I am now trying to configure the EPCS (and required custom bootloader) to load the user image and fall back to the remote configuration factory image if this fails. I have created a combined hardware and software image for both the factory design (including bootloader) and the user image and programmed them to the EPCS. However when i reboot the FPGA the factory image is always loaded. I think i have a reasonable understanding of the steps that are needed to achieve what I want but i may have misunderstood some parts or missed something out. If anyone could give me a few pointers that would be great. The steps i have taken are shown below I am using a Stratix II EP2S60 on a custom PCB and Quartus 7.2 (fully licensed). Thanks in advance, Andy -------------------------------- I have taken the following steps:- Remote Config Image - CPU reset vector is EPCS offset 0x0
- User image - CPU reset vector is EPCS offset 0x0
- Remote configuration image contains the SII remote update IP core created by jakobjones (showthread.php?t=3658)
- I have created a custom bootloader using the trio_bootloader example from this topic (showthread.php?t=20623) by replacing the system.h file with my file from the Remote config sofwtare image and running the makefile
- I have included the bootloader hex file in the Remote Config hardware project using the following assignment parameter:
epcs:the_epcs|altsyncram:the_boot_copier_rom INIT_FILE trio_boot_loader_epcs.hex Yes. This corresponds to the name of the EPCS controller in the design- I have created a .flash file for the remote update image as follows:
sof2flash --input=hw_rem.sof --output=hw_rem.flash --epcs
elf2flash --input=sw_rem.elf --output=sw_rem.flash --after=hw_rem.flash --epcs --boot=trio_boot_loader_epcs.srec
cat hw_rem.flash sw_rem.flash > rem_image.flash- I have created a .flash file for a sample user image project (basic hardware, software flashes LEDs) as follow:
sof2flash --input=hw_usr.sof --output=hw_usr.flash --epcs
elf2flash --input=sw_usr.elf --output=sw_usr.flash --after=hw_usr.flash --epcs --boot=trio_boot_loader_epcs.srec
cat hw_usr.flash sw_usr.flash > usr_image.flash- I have programmed the rem_image.flash image to the base of the EPCS and the usr_image.flash to the EPCS with an offset of 0x300000 (which equates to the line
in the bootloader.h part of the custom bootloader.#define TRIO_USER_IMAGE_ADDRESS 0x300000
13 Replies
- Altera_Forum
Honored Contributor
Thanks for that, I think i get it!
I think i may however have run into a more serious problem. Reading the manual "7.Configuring StratixII and StratixIIGX Devices" I see that the MSEL input pins have to be set accordingly to run remote system upgrade. Table 7-1 says that for Remote system upgrade with AS the value of MSEL[3:0] should be 1110. The problem is the custom board I am using (not designed by me) does not have any jumpers or switches to configure the input to the MSEL pins. All it has is a three pin header with a jumper which when placed over the leftmost two pins is AS and the rightmost two pins PS. I assume that this is driving a single bit of the MSEL signal with the rest appropriately hardwired to support the modes AS and PS. I know that you cannot see the board but does this sound a reasonable conclusion? I assume therefore that without being able to correctly set all 4 pins of the MSEL input i won't be able to correctly use the remote update circuitry. Is this correct? Are there any alternative methods I could consider? Thanks, Andy - Altera_Forum
Honored Contributor
Andy, I think it is better when the user image also uses the altremote_update function. You can switsh betweeen the images. In case of a functional error in your user firmware you can fallback to the factory image. I'm using Active Serial and Remote in booth images.
I don't know how your altremote wrapper works. My wrapper has an Avalon Slave Interface which allows to access the altremote register (they called parameter in altremote userguide) and to control the reconfig port. The only thing what to do is to write the sector address of your user fpga image (not user firmware) on parameter 0x100. When your image is at address 0x300000 then you have to write the sector numer 48 to that parameter. (refer 3. Serial Configuration Devices EPCS1,EPCS4, EPCS16, EPCS64, and EPCS128 Data Sheet, table 3-4 in case of EPCS64). After parametrizing the sector to boot from you must assert a '1' to the reconfig pin of altremote_update block (this should be done by your wrapper hardware). Here is the component instantiation in the wrapper. The component was generated with MegaWizard.
And here is a little piece of firmware code:COMPONENT ru_rmtupdt_i7q PORT ( reconfig : IN STD_LOGIC ; param : IN STD_LOGIC_VECTOR (2 DOWNTO 0); reset_timer : IN STD_LOGIC ; read_param : IN STD_LOGIC ; reset : IN STD_LOGIC ; data_in : IN STD_LOGIC_VECTOR (11 DOWNTO 0); busy : OUT STD_LOGIC ; clock : IN STD_LOGIC ; data_out : OUT STD_LOGIC_VECTOR (11 DOWNTO 0); pgmout : OUT STD_LOGIC_VECTOR (2 DOWNTO 0); write_param : IN STD_LOGIC ); END COMPONENT;
Jensswitch (ulImage) { case 0: //select factory image IOWR_32DIRECT( pParam->Fpga.ulpSOPCBaseAddress, RU_PAGESEL_OFFSET*4, EPCS64_FACT_SECT ); usleep(100); ulTempReg = IORD_32DIRECT( pParam->Fpga.ulpSOPCBaseAddress, RU_PAGESEL_OFFSET * 4 ); usleep(100); if(ulTempReg != EPCS64_FACT_SECT) { ulMessageOut( "ReloadFPGA with Factory failed (wrong sector)!\n" ); return 1; } //reconfigure IOWR_32DIRECT(pParam->Fpga.ulpSOPCBaseAddress, RU_CONFIGURE_OFFSET*4, 0x1); usleep(100); break; case 1: //select application image IOWR_32DIRECT(pParam->Fpga.ulpSOPCBaseAddress, RU_PAGESEL_OFFSET*4, EPCS64_APP_SECT); usleep(100); ulTempReg = IORD_32DIRECT(pParam->Fpga.ulpSOPCBaseAddress, RU_PAGESEL_OFFSET*4); usleep(100); if(ulTempReg != EPCS64_APP_SECT) { ulMessageOut( "ReloadFPGA with Application failed (wrong sector)!\n" ); return 1; } //reconfigure IOWR_32DIRECT(pParam->Fpga.ulpSOPCBaseAddress, RU_CONFIGURE_OFFSET*4, 0x1); usleep(100); } - Altera_Forum
Honored Contributor
Jens, thanks for that, I think i now understand better how the system should work. I have a couple more questions if thats ok..
I've realised the main problem is that my Factory image does not properly initiate the altremote_update reconfiguration into the user image. I've spent the last few hours trying to work out how it should work and reading various manuals but can't get my head round it. My quartus project for the Factory image is set to configuration scheme "Active Serial" and configuration mode "Remote", the User image is set to "Active Serial" and "Standard". Is this correct? I'm using the SOPC component linked in my previous post from jakobjones which provides a wrapper for the altremote_update block. I have set the altremote_update to use the operation mode "Active_Serial_Remote". This block contains a collection of functions for reading/writing from the block from the C code but i don't really know what they do. I don't really understand how the various status registers of the remote_update block work In the post you linked to you say: --- Quote Start --- 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'. --- Quote End --- This is what i need to do. Could you show me your code for doing these things (setting the EPCS page address, setting the watchdog, initiating reset etc)? Thanks again, Andy