0
\$\begingroup\$

I am programming a CDC Bootloader. What I want to do is to run the program, from there write a bootloader key to the ram at a specific address and watchdog reset the MCU. The Bootloader reads exactly the same address and checks if it has the bootloader key in it. If it is the bootloader key it will execute the bootloader protocol, otherwise start the sketch again.

Now the question is: What address to use? Ive heard that a few addresses of the ram pointer are reserved for some peripheral registers. Ive also heard about the stack management in ram. So what would be the best place to put such a magic bootloader key?

As an example on an Arduino Leonardo (32u4) with 2,5kb ram they save it at the 2kb address: https://github.com/arduino/Arduino/blob/master/hardware/arduino/bootloaders/caterina/Caterina.c#L69

Any suggestions for a 16u2 and 32u2 with 500/1000 byte ram? Or maybe another way to pass the bootloader this information? Can anyone explain me why they used 0x0800 for a 32u4 or was this maybe just a 'random' place? I don't want to conflict with any program as less as possible and dont want to break programs with this kind of ram writing.

Edit: It is important to find a normally not used ram address since you can revert this bootloader watchdog reset. See this: https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/CDC.cpp#L96-L98

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

It really doesn't matter that much where you put your key, as long as your program and bootloader both agree on it.

You will just be setting a couple of bytes in RAM, setting the watchdog, then you should enter a while(1); loop so nothing else happens. You should also disable interrupts before you start as well. It doesn't matter if you overwrite memory used by the program, since that program is no longer running. Once the bootloader is finished and done with, it doesn't care what you do with that bit of RAM, so you can just use it as per normal in your program.

If you do want to "reserve" the memory in your program so it doesn't get used for anything else, you can place a variable in a separate section located at a specific address, and nothing else will be put there. Something like:

volatile uint32_t blkey __attribute__((section(".blkey")));

and then tell the compiler where that section is located by adding this to the linker:

-Wl,-section-start=.blkey=0x<ADDRESS>

That way you don't really care about what else is going on - that section is then set aside from the rest of your program.

\$\endgroup\$
10
  • \$\begingroup\$ What they did is that you also can go back and reverse that watchdog reset. See this: github.com/arduino/Arduino/blob/master/hardware/arduino/cores/… So it could possibly overwrite some important stuff and it matters where to put the key. \$\endgroup\$
    – user50993
    Nov 27, 2014 at 18:22
  • \$\begingroup\$ Fair enough, if you want that functionality, but why would you change your mind in the few milliseconds between calling the enter bootloader function and it rebooting? \$\endgroup\$
    – Majenko
    Nov 27, 2014 at 18:34
  • \$\begingroup\$ See the comments in the link. Because the PCs virtual Serial port can trigger DTR several times and it might be a wrong signal. Thatswhy! Your new solution sounds good but what if this address fragments the ram? Wouldnt it be better to use the very first or last address? And whats the first/last address since some addresses can be registers i've heard.Isnt there something more easy than this? compiler flags for Arduino are a bit more complicated but still possible. just asking for any other solutions. Thx :) \$\endgroup\$
    – user50993
    Nov 28, 2014 at 16:57
  • \$\begingroup\$ It is normal to use either the first or last word of RAM, yes. That way it can't fragment. \$\endgroup\$
    – Majenko
    Nov 28, 2014 at 16:58
  • \$\begingroup\$ And how can i find out whats the first address? People told me 0x0000 - some value is are special register, not the actual ram. Also RAMEND is a but more than the actual ram size. \$\endgroup\$
    – user50993
    Nov 28, 2014 at 17:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.