How possible compile a binary for Arduino Due that can run from flash BANK1?

How possible compile a binary for Arduino Due that can run from flash BANK1?

It's possible - I've done it. I've been toying with trying to get an in-application firmware flasher to work. The idea is to have code that is able to write to the opposing flash page when running. That is, you run from FLASH0 and update firmware by writing to FLASH1 then booting to FLASH1 where you can then update firmware by writing to FLASH0 and booting to that. This halves the FLASH space you can use for your sketches but really 256K is still plenty of space for most anything you're going to run on a little processor like this.

What I did was copy flash.ld to a new file flash2.ld

Then, change this line:
rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K */

To be like this in flash.ld:
rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00040000 /* Flash, 256K */

And like this in flash2.ld:
rom (rx) : ORIGIN = 0x000C0000, LENGTH = 0x00040000 /* Flash, 256K */

Now, open the boards.txt file. In there are a bunch of lines that start with:
arduino_due_x.

Copy all of those lines and give the new copy a unique prefix like:
arduino_due_x2

You will find this line:
arduino_due_x2.build.ldscript=linker_scripts/gcc/flash.ld

Change that to:
arduino_due_x2.build.ldscript=linker_scripts/gcc/flash2.ld

Find this line:
arduino_due_x.name=Arduino Due (Native USB Port)

Change it to something like:
arduino_due_x.name=Arduino Due (FLASH0)

Find this line:
arduino_due_x2.name=Arduino Due (Native USB Port)

Change it to:
arduino_due_x.name=Arduino Due (FLASH1)

Find this line:
arduino_due_x.upload.maximum_size=524288

Change it to:
arduino_due_x.upload.maximum_size=292144

Find this line:
arduino_due_x2.upload.maximum_size=524288

Change it to:
arduino_due_x.upload.maximum_size=292144

Now you'll have three Due targets within the Arduino IDE and you can target either FLASH0 or FLASH1 for any of your sketches. Here is the bad news: You can use my steps to compile for FLASH1 and it does work but it will not set the boot bits to boot from FLASH1. You have to find some other way to do that. It does not appear that bossac can even do it. There are two ways to do it. One is to connect to the board over JTAG and set the bit and the other is to do it in software on the board itself. Thus, the best approach is for an on-board bootloader or sketch to set the boot bit so that you can run the FLASH1 sketch.

As I said, I have done all of this. You can check my github account for some code that does all this (GitHub - collin80/FirmwareReceiver) That code runs on the Due and is a library that can receive a firmware update. You have to send the right firmware image depending on whether the sketch is currently running in FLASH0 or FLASH1 because I haven't found a good way to take a single firmware image output from the Arduino IDE and turn it into an image for the other FLASH page. There are too many ways that could go wrong. All of the support for this is really brittle and requires lots of bits and pieces but I have successfully gotten sketches to work with all of this.

Anyway, hope that helps you do whatever it is you want to do.

Thank you for the detailed instruction I will try it soon! Anyways what do you think how many times possible to rewrite the flash memory in the due? I want to balance the flash wearing between the banks with this.

Hello Collin:

Thank you for this post. However I am having some difficulty making this work.
I created a program called Flash0.ino which I attempt to load into Flash Bank 0 and another called Flash1.ino which I load into Flash Bank 1. Both programs are nearly identical as you can see.
The only difference is setting or clearing the GPNVM bit 2 to select which flash bank to boot from on next reset. I also have the program performing a self reset after setting the bit.

I have set the boards.txt, flash.ld and flash2.ld as you have specified (or at least I think I did, please check it). I connect the Due to the PC with the Native port, select Arduino Due (Flash 0) from the boards menu, and then set the serial port. I then upload FLASH0.ino successfully, or so it appears. Immediately upon the upload, the IDE resets the board. I lose the com port and cannot get it back. I can switch the USB cable back to the programming port and get another com port, and can upload a simple program. I can do the same with Flash 1 but again in both cases I lose the com port on the native port, and cannot get both Flash0.ino and Flash1.ino into memory at the same time.

I am obviously doing something wrong: Incorrect boards, flash or flash2 settings, out of sequence, or??

appreciate your help Collin!

Flash_0.ino (208 Bytes)

Flash_1.ino (208 Bytes)

boards.txt (3.72 KB)

flash.txt (5.01 KB)

flash2.txt (5.05 KB)

Note that flash.txt and flash2.txt are indeed saved as flash.ld and flash2.ld on my system, they are shown here as .txt because of the forum's file extension limitation does not allow .ld files to be posted.

how do you clear or set the GPNVM bit 2?

using the function flash_clear_gpnvm(2) function found in the DueFlashStorage library Collin80 posted on github at DueFlashStorage/DueFlashStorage.h at master · collin80/DueFlashStorage · GitHub

try to export compiled binary and use bossac from cli

Never tried that, where do I find a 'how to'? Thanks for your reply!

It's weird that it isn't working for you. So far as I can tell you've done everything properly. Have you tried flashing sketches to the board with an unmodified installation of the IDE to test? Also, I've had lots of trouble when using lines like

flash_clear_gpnvm(2)

It seems to love to lock up the sketch. I believe you've got to run that line with interrupts disabled or you're asking for a lock up. It can be a bit tedious to make sure that things stay stable when you're switching the boot bit. So, try it without doing that and make sure that things are working then add the line back and try to make it stable.

Thanks Collin, I will try without interrupts and post results. You were able to use the IDE to upload both Flash Bank 0 and 1 or did you use BOSSAC?

I used the IDE to flash the FLASH0 sketch. For FLASH1 I used an in-sketch programming library to write to FLASH1 and then set the boot bit and reset.

In sketch programming library?

Hi Collin, still not working....

In the IDE I set the board type to 'Arduino Due (Flash0)', and selelct the Com port that comes up. I am connected to the Native USB port. I open the Flash0 program, compile and download it to the Due- all appears fine, program appears top download, indicates success and of course the IDE resets the board. Immediately the IDE loses the com port, it no longer appears under the Port setting. I can restart the PC, disconnect and reconnect the Due, to no avail - no com port shows up. If I switch the USB cable back to the programming port, I immediately get a Com port, but the board type in the IDE is still set to the (Flash0) port. I can switch the board type to 'Arduino Due (Programming Port) and can re-program the board. Any ideas?

Hi Collin:

For the most part I have this working, with the exception of a program running is Flash Bank 1 resetting the GPNVM bits to boot at Flash Bank 0. When this is done, the board bricks. This work fine when I have the program at Flash 0 set the GPNVM bits to boot from flash 1.

Not sure why, any ideas?