Go Down

Topic: RAM use by bootloader (Read 129 times) previous topic - next topic

mibarkway


I want my system to know if it has been started by a reset, or after a power-failure. Mostly this is because it's connected to a pi that goes on and off, which triggers DTR when it starts and resets my Arduino. I want to keep some data too, for which I could use EEPROM, but that's not quite what I am looking for.

So, my idea is to make a global array which should reserve some RAM for me in a fixed spot, store a few bytes of data in there and protect it with a big checksum, or hash, haven't decided yet. Then on each array update I can re-calculate the checksum and keep that up to date.

Then when I boot up, I will add-up the array and if the checksum is correct, then I know that the data in there is Ok and it is a "soft" reset vs a full power-cycle. However, this only works if the RAM is left in peace while the bootloader does its work, hence my question, which is:

How much memory does the bootloader dabble with on start-up..? Does it squish it all with a memory check, or anything..? Is there another reason why this idea wont work..?

Many thanks Arduino folks..!

westfw

Which board?  Optiboot on the avrs will use very little ram (perhaps just a few bytes of stack) unless it actually uploads something, and it doesn't touch ram that it doesn't use.

westfw

(Also, newer versions of optiboot will leave the "reset cause" in various places where the sketch can see it.)

mibarkway


It's an Eligoo Mega. Not sure what version of bootloader it is. Is there an easy way to check..? 

I'll have a play now I think. Shouldn't take tooo long to experiment. I'll see if I can grab all the 8k of RAM into an array, fill it with 0xAA's n see what happens...

mibarkway

#4
Oct 17, 2020, 12:55 pm Last Edit: Oct 17, 2020, 01:20 pm by mibarkway
Uggg... doesn't work. None of my bytes are preserved across a reset (code snippet below). Maybe there is a memory test, or maybe the chip does a power cycle internally, dunno. Will have a think about where to go from here, though brain is a bit blank just at the mo... don't really want to go hacking the bootloader. Might see if I can find a peripheral with some RAM in or something...

char bigArray[6501];

void setup() {
   Serial.begin(57600);
   for (int index=0; index<=6500; index++) {
      Serial.print(bigArray[index]);
      if (index == (index/40)*40) Serial.print("\n");
      bigArray[index] = 'Z';
   }
}


pert

For your experiments, you can eliminate the bootloader as a possible factor in the data loss by connecting an ISP programmer (could be an "Arduino as ISP") to your Mega and then doing a Sketch > Upload using Programmer to upload your test code. Doing that erases the bootloader. Then if you run your experiment again and find that the memory is intact this time, you know the bootloader is the culprit, whereas if the memory is still lost then you know this issue is unrelated to the bootloader.

After that, to return to normal uploads again, you need to do a Tools > Burn Bootloader to replace the bootloader.

If you want to try out optiboot on your Mega, an easy way is to use MegaCore:
https://github.com/MCUdude/MegaCore

tf68


mibarkway


Thanks for the great feedback. There is a good thread on here on finding the reason for a reset, which I got to very quickly googling MCUSR.

I spose the essence of my prob is that I want to store some data across a reset, and I want to update the info a little more often than I feel comfortable to use EEPROM. I know my Pi is going to be starting up from time to time and will reset the Arduino. Among other things, I'm collecting some longer-term average temperatures, so it defeats the object a bit if I lose those when my Pi starts up to read them out...

I can prevent the reset on serial start/DTR, done that before, and previously have hooked in a GPIO from the Pi as a substitute reset, but can't do that here for practical reasons. Plus obvs I will want to update my Arduino code... 

I have ordered a PCF8570P (256 byte I2C RAM chip), so will see how I get on with that. That should just sit there across a reset, so I can poke my data in and make sure its Ok on start-up with a few bytes of checksum. I will update here if that doesn't work, otherwise happy hacking..!

westfw


mibarkway


Oh you complete star, if I change the definition of the array a bit it works just the way I wanted..! That will save me a bit of soldering...

char bigArray[6501] __attribute__ ((section (".noinit")));

(it does seem a bit strange for the compiler/linker to initialise your un-initialized variables for you... However, all of the 6500 bytes now survive a reset which is unexpected. Result)


westfw

Quote
it does seem a bit strange for the compiler/linker to initialise your un-initialized variables for you.
It's required by the C/C++ specifications.
I'm not sure that it makes sense, but it's pretty handy.
I used to work on a system that set all the uninitialized data to -1.  THAT would detect uninitialized pointers pretty quick!  (although these days, many systems don't have memory at location 0, so it works almost as well.)

Go Up