How much RAM does Marlin need on average? Can you load parts from flash into RAM and then discard that part later and load another part? I imagine that would allow you to run Marlin with less actual RAM. I hear about Marlin program memory, but I never seem to hear about RAM specifically, so I think what I was reading was flash memory specifically.
If I am reading the specification sheet correctly for the Atmega1284 used in the ender 3 there are 3 “memory” pools besides the program storage. Pool A is the 32 8 bit registers, pool B is a 16kB SRAM and pool C is a 4kB EEPROM. So there really isn’t any storage available for virtual memory tricks. Also the program memory can have 1 fetch per clock cycle, the SRAM requires 2 clock cycles to fetch, and the EEPROM requires halting the CPU for a number of cycles to fetch or store. So it is best to think of the program storage as all you get and that the program also encompasses all of the working data. If your printer uses a different SOC then the limits will be different.
My understanding is that registers are abstracted away by the Arduino IDE to the point where they are not be meaningful to us, and EEPROM/Flash isn’t present in all printer hardware, so you’re basically limited to SRAM… and that’s a precious resource used for critical work like motion planner queue buffering. Not an expert though.
Oh, and unlike a PC where you have to load a program from hard disk to RAM to execute it, I’m pretty sure Atmegas run programs directly from program memory, at least in the sense we care about at the Arduino IDE programming level. In reality it’s loading one instruction at a time to registers, but that’s abstracted away by the compiler. So we only worry about it in a few specific high-optimized code snippets where devs have opted for machine language instructions for peak execution speed.
The Arduino IDE does say how much RAM is being used by a program. And there’s flash which is effectively software fixed in place at flash time. Both are impacted by the build time options. 8 bit micro controllers are very, very limited on what they can do to the point it’s impressive that so much performance can be squeezed out of them.
Flash is like the Arduino’s hard drive. It’s where your program is stored. When the IDE compiles, it shows you how large the compiled program is, and what percentage of the available flash on the selected board it will use.
RAM is used for the program’s variables, and good practice for projects like Marlin is to use statically-allocated variables. This means that every variable uses a certain amount of RAM that is allocated once, then never freed for another purpose. The same variable uses the same bit of RAM for the program’s duration, and a limited number of variables are created to ensure that you don’t run out of RAM. When your program compiles, it will also tell you how much of the controller’s available ram is allocated to global variables.
You can also have local variables that will only exist while a certain function is running, but with the large number of developers, the large number of optional features that come with their own global variables, the small amounts of available RAM, the differences in available RAM on different build targets, the fact that many of those build targets are operating without much headroom, and the large number of users compiling the code who don’t know how to fix memory problems if they do occur, it’s considered to be a bad idea to use dynamically-allocated memory and risk the uncertainty about how much you will need at any given time.
There are a few pieces of large, static information, like the bitmaps drawn on the LCD, that use the PROGMEM keyword, which means that they are stored in flash and read directly from there when the program uses them, rather than using RAM to store them.
EEPROM is a relatively small area of non-volatile storage that is available for the program to store information that will persist when the controller is reset or powers down. Marlin uses this to store variables like steps/mm, Feedrate/acceleration/jerk limits, PID parameters, etc. Default values for these are entered at compile time, but this system allows you to change them and store those changes (using M500) without recompiling.
Couldn’t have said it better.
RAM on an atmel is for variables, different than RAM on a PC which also loads the program. There is no penalty for an atmel when running code from eeprom.