I think that the disabling of RAM during sleep is really only of value to people who are sweating every single hour of battery life.
My opinion: Arduino is like popping the hood on a modern car and seeing a bunch of plastic covers. It engine bay looks nice and simple, but all those covers just make it harder to get at what is underneath.
So lets’s pop the hood and start removing engine covers:
- Go to Arduino/File/Preferences and check both ‘show verbose output’ boxes
- build your sketch
- look at the second last line in all that verbose output to find out where your build actually got done. Here is an example from my build: "C:\\Users\\robin\\AppData\\Local\\Arduino15\\packages\\SparkFun\\tools\\arm-none-eabi-gcc\\8-2018-q4-major/bin/arm-none-eabi-size" -A "C:\\Users\\robin\\AppData\\Local\\Temp\\arduino_build_183998/ReflowController.ino.axf"
- cd to the temp directory that Arduino is using: "cd C:\\Users\\robin\\AppData\\Local\\Temp", fixing up the slashes for whatever you are using to get to that directory
- you should see a map file there. Mine was named 'ReflowController.ino.map'. Open it with your favorite editor.
It’s a big, big file. Use your editor to find where all the symbols are assigned to RAM. Look for the highest RAM address you can find. Remember that RAM addresses always start with 0x100xxxxx. Here is my map file for my project showing the largest RAM address:
.heap 0x10021214 0x0 load address 0x0002c594
0x10021214 __end__ = .
0x10021214 PROVIDE (end = .)
*(.heap*)
0x10021214 __HeapLimit = .
It looks like the HeapLimit is the last variable in RAM at 0x10021214. I can’t actually tell you if that is where the Heap starts or ends (but I bet that it is the first address of the Heap). That is another complication. If your code uses the heap, then how much is it allocating? I am betting that any allocations my sketch makes will be using space after 0x10021214 in my example build. But again, who knows how Arduino does it. I find it better to use a mechanism where I define where the heap is and how big it is so that I know its limits. So maybe with Arduino, it would be easiest to just leave all the RAM turned on. If you decide to use a different development environment in the future, well, they are more complex, but they sure give you control over everything. Plus, nothing beats a hardware debugger. I use the Segger Embedded Studio. Here is the output from its map file:
***********************************************************************************************
*** ***
*** LINK SUMMARY ***
*** ***
***********************************************************************************************
Memory breakdown:
67 690 bytes read-only code
6 046 bytes read-only data
150 701 bytes read-write data
Region summary:
Name Range Size Used Unused Alignment Loss
---------- ----------------- ---------- ------------------ ------------------ ------------------
FLASH 00010000-0007ffff 458 752 73 740 16.07% 385 000 83.92% 12 0.00%
RAM 10000000-1005ffff 393 216 150 701 38.33% 242 515 61.67% 0 0.00%
That’s a nice summary. If you want details, it has them all too. Here is the overview of the RAM space:
0x10000000 __RAM1_segment_start__ ---- Gb [ Linker created ]
0x10000000 __RAM1_segment_used_start__
---- Gb [ Linker created ]
0x10000000 __RAM_segment_start__ ---- Gb [ Linker created ]
0x10000000 __RAM_segment_used_start__
---- Gb [ Linker created ]
0x100048B0 __heap_start__ ---- Gb [ Linker created ]
0x100248B0 __heap_end__ ---- Gb [ Linker created ]
0x10060000 __RAM1_segment_end__ ---- Gb [ Linker created ]
0x10060000 __RAM1_segment_used_end__ ---- Gb [ Linker created ]
0x10060000 __RAM_segment_end__ ---- Gb [ Linker created ]
0x10060000 __RAM_segment_used_end__ ---- Gb [ Linker created ]
0x10060000 __stack_end__ ---- Gb [ Linker created ]
The beauty of this little section is that all of those symbols are available to my program. So if it wanted, it could take a look at heap_end and then calculate what pages of RAM need to have their power retained during deep sleep.
Arduino is a great way to get started fast, but a sub-optimal way to develop a complex application. That’s probably enough opinions for one day though. I think there are lots of development systems with hardware debugging now, but I still use Segger. I like it!