Have spent several days now searching and reading and think I am nearly there... but not quite. I am using the NIOS II core with SOPC builder. I use Quartus II for the FPGA image. This is a project I have inherited which kept the FPGA image in a ECPS64 and the software image in CFI. I have combined the two and keep them in the EPCS64. Works OK. I have been trying to get the remote update controller to work. I have put it into the core via SOPC and can read and write its registers via NIOS. I can also make it do a reconfig but it always seems to use the factory image. Has any one got a working example using the Cyclone III and NIOS II?I use the following to read 2 of the registers... ParamValue = IORD( REMOTE_UPDATE_CYCLONEIII_0_BASE, 0x4); ParamValue = IORD( REMOTE_UPDATE_CYCLONEIII_0_BASE, 0x0); After power on both registers read 0. After reconfig command, register 0 = 1 and register 4 = 8 Any ideas please? Brain is starting to hurt!
Do you have one or two firmware (sof) images in the EPCS? Do you have one or two software images in the EPCS?When you reconfigure using the remote update core, you need to tell the core where the firmware image is located that you want to use next instead of the one at the beginning of the EPCS. If you have 3 or more firmware images that you need to go between, you will need to have provisions in the firmware image at 0 to decide which one to use. Assume you have 3 firmware images at addresses 0, X and Y. The firmware at 0 boots, decides to reconfigure to X. When the firmware at X is loaded, if it attempts to reconfigure it will always load the firmware at 0.
Hi yes. I have 2 sof and 2 elf files (hopefully). I use sof2flash and elf2flash, convert to bin, join together (cat) and then convert to hex. I then use Quartus Programmer to convert hex to pof and program. I do the same for the second image but set to relative address and put in an offset and reprogram, hopefully leaving the first pof in the bottom of the EPCS64. Does this make sense?
What is happening is the bootloader in your second sof is pointing to the firmware at 0. The bootloader will look for the size of the firmware (sof) and search for the start of the elf just after it.I have dealt with this problem before, but I don't have a great solution for you. I normally place my second firmware/software at a fixed address location well beyond my first firmware/software pair. After this, I modify a copy of the bootloader code to search for this new offset instead of starting at 0. When compiled, it will generate a new .hex file. This file needs to replace the one that your second firmware image is using to boot the software. The stock bootloader software is located in your quartus install directory. Search for boot_loader.S and you should find it. (there is a makefile you can use with the NIOS II command console app if I remember right. I wish I knew how do make this process easier. If anyone else knows of an easier way, I'd be interested too.
Kosh is right, you need to change the bootloader, because the default one assumes Nios firmware is located just after fpga configuration data starting at address 0; then you load new fpga configuration, but the old nios firmware.You need to replace the epcs_controller_boot_rom.hex file in Quartus directory with the customized bootloader image and then rebuild the fpga project. Pay attention that sopc builder overwrites this file with the default bootloader whenever you regenerate the sopc system! Then you must backup your custom hex image and replace it every time you rebuild sopc. What kosh suggested is indeed the standard solution for generating a remote update firmware image. AFAIK there's no way to automate the procedure and make it easier. Anyway it is not that difficult. Consider that the primary fimware (usually referred to as factory firmware image) is seldom changed, so the fixed address location for the updated firmware is not a great problem: normally you only need to generate the special bootloader once.
Just to make sure I understand this correctly... My 1st pof (combined sof and elf) will have the default Altera bootloader in it. This will search for the elf, starting at address 0, and load it into RAM. My 2nd pof, sitting at address 0x200000, is started when I send a reconfig command via NIOS code. I assume this has it's own copy of the default Altera bootloader in it, so it also searches from address 0 for the elf. So I am assuming what I need is the default bootloader in the 1st pof (as it is now) and a modified bootloader in the 2nd pof which starts looking for the elf at address 0x200000.Does this sound about right?
You can probably just put the boot code into a user-defined internal memory block, and point the nios reset vector at it.That would remove the problems of the sopc builder repeatedly substituting its own file. After all, I presume that is what happens anyway. It would also let you use TCM for the boot code (probably more useful for the JTAG block though since you are probably copying code to SDRAM and have an instruction cache anyway).
Probably being a bit stupid here but... how do I make the boot_loader........ciii.s file? Changeing it using a text editor is easy enough but then how do I assemble it? I'm not that familiar with the command shell and how to use it.
Here is the CIII bootloader source files attached and the .hex generation procedure.Steps: - open Nios II command shell and go to bootloader project directory - change EPCS_SRC_ADDR in boot_loader.h with desired boot address for Nios application - build the custom bootloader, which generates a epcs_controller_boot_rom_A.hex file (simply type 'make') - replace the existing epcs_controller_boot_rom.hex file in Quartus project with the newly generated one (thus removing _A) - select Quartus Processing menu, then Update Memory Initialization file - select Quartus Processing menu, then Start -> Start Assembler - the generated sof file will boot from the specified address Remark: I copied and pasted from notes written a long ago for one of my designs, so I'm not 100% sure everything is right for you . This also answer to your first question: yes, the hex bootloader code is encapsulated into sof file Good luck!
Making progress, I think. It now doesn't run the second software image at all because I guess it cannot find it. I found another bootloader (I couldn't get the one above to make). This one has these lines in it...//cal // ofset to where the code is loaded in the epcs device // these need to be updated. # define SOFTWARE_OFFSET 0x1c0000 # define EPCS_FLASH_CONTROLLER_0_BASE 0x2000 // offset to the beginning of the hardware for the epcs ( not the rom) # define EPCS_BASE_PLUS_400 (EPCS_FLASH_CONTROLLER_0_BASE+0x400) Embarrasingly not sure what to set them at. I was trying to put my second fpga image at 0x200000 and second code at 0x400000. I set the software offset to 0x400000. What do I do with the other 2. Any ideas please. So near, yet so far!!
Still no luck. I am using the boot loader 'my_boot_loader_standalone.S'. I change the lines as shown below. SOPC says my EPCS base address is 0x801800. I put my software file at 0x400000 using the Quartus Programmer.// ofset to where the code is loaded in the epcs device // these need to be updated. # define SOFTWARE_OFFSET 0x400000 # define EPCS_FLASH_CONTROLLER_0_BASE 0x801800 On power up my 1st FPGA and 1st software image run fine. When I reconfig, my 2nd FPGA image runs but no software seems to run. Any help much appreciated.
I don't know if it applies to your system, but on my designs I layout my EPCS flash locations as:Address 0: Factory SOF Address (-after Factory SOF): Factory Software Address 0x500000: Application SOF Address (-after Application SOF): Application Software Where -after is done using the --after switch in my programming script (for the NIOS II command shell) Example below: sof2flash --input=fpga_factory.sof --output=fpga_factory.flash --epcs --verbose elf2flash --input=software_factory --output=software_factory.flash --epcs --after=fpga_factory.flash --verbose This is done since the bootloader normally points to the starting address of your .SOF (normally 0, my modified code points to 0x500000). From here it determines the size of your .SOF and seeks to the end to look for your software. I hope this helps.
I'd start doing what I would do to debug a bootloader....Find some simple peripheral (like a LED) and see if I can make it work (eg flash). That gives you some confidence that you stand a chance of actually booting something. If you have a UART it is a bit easier - you can write single bytes to the fifo and follow the progress.
Thats what I am doing. My FPGA toggles a pin. My software toggles another pin. The toggle frequency is different depending on the image loaded. At power up the 1st image is loaded and this can be confirmed by the pin toggle frequencies. When I reconfig (via serial command) the 2nd FPGA image is loaded (pin toggle frequency changes) but the pin the software is toggling doesnt toggle anymore. So 2nd software image isnt running. It's something to do with the settings in the bootloader in the 2nd FPGA image.(1st FPGA image uses default bootloader).
Still not working, still confused. Ok. For the 'factory' image I create a combined sof and elf and convert/program it into the EPCS64 using the Quartus Prorammer. This works as it should. For the second sof I use modified boot loader code and then using Quartus Programmer I put it into the EPCS64 at address 0x0200000. The remote reconfig in the 'factory' image points to this address. The second elf is programmed in at address 0x0400000. Factory version still works fine. Send a reconfig command and 2nd sof is run ok but second elf isnt, no software running at all. If I build the 2nd sof with default boot loader it loads the 'factory' elf which then runs ok. So I end up with 2nd FPGA image running and 'factory' software.I am using a bootloader called 'my_boot_loader_standalone.S' My SOPC reports my EPCS has a base address of 0x0801800. The bootloader needs # define SOFTWARE_OFFSET. Where is this offset from? I put in 0x0400000 which is where my elf starts in the EPCS. Is this correct? It also asks for# define EPCS_FLASH_CONTROLLER_0_BASE which I have set to 0x0801800. Again is this correct? Sorry to be stupid here but I seem to be going around in circles.
The meaning of SOFTWARE_OFFSET constant depends on your actual bootloader.If this a 'true' offset probably the correct value would be 0x200000 rather than 0x400000 (i.e. the offset between fpga image and elf) But it could also refer to the free space offset from end of fpga sof image to start of elf, although this would be not recommended since this is not a well defined value. Other smart bootloaders (IIRC the default one, too), are able to automatically detect the end of sof image and start loading from there. Look into the bootlaoder code and find it out.