Memory: Flash or RAM?

Thread Starter

ActivePower

Joined Mar 15, 2012
155
I thought I knew this for a while but then I read some more and now I am beginning to think that I messed up my understanding somewhere. I'd be glad if someone cleared it up for me. Here goes:

1. What memory exactly are we referring to when we say 'load from memory'? I thought it meant RAM. But aren't constants and arrays and other data stored in Flash? More generally, isn't everything present on the Flash immediately upon programming?

2. What does it mean to say that some memory type is 'executable'? I've come across many posts across the internet which say things like 'so-and-so processor can execute out of RAM' and 'smaller controllers execute out of Flash'.
Doesn't everything just execute out of the CPU? If we're talking about the source of the instructions and data to execute - isn't Flash memory the only source as it is the only part which we can program (and hence the only part which isn't empty) on reset?

Also related in this context (and I've always found this confusing), is the RAM usage of a program. I feel I've always used (abused?) the general definition thrown around that RAM is like a scratch-pad for the CPU where it stores all the run-time data and where all the calculations take place. Say, we have an assignment operation:
Rich (BB code):
uint8_t num = 10;    // Initialized variable
From what I've read, the processor maps the 8-bit variable 'num' onto the RAM and the constant '10' onto Flash. What this would mean is that there must occur some time before this assignment takes place, a procedure to somehow 'associate' the value with the variable.
Searching for this, I stumbled upon linker scripts and how we can direct the output to be 'placed' into either Flash or RAM address space which made it even harder to understand. Basically, how can you 'control' what goes into RAM?

Any hints on how to approach this are welcome.

Thanks!
 

tshuck

Joined Oct 18, 2012
3,534
1. What memory exactly are we referring to when we say 'load from memory'? I thought it meant RAM. But aren't constants and arrays and other data stored in Flash? More generally, isn't everything present on the Flash immediately upon programming?
This is a topic many people don't fully understand and gets more convoluted as our processors and technology get more advanced. Saying that it is loaded from memory is about as specific as one can be with regards to a microcontroller - in example, you could have Flash, RAM, and EEPROM on the same microcontroller. The compiler could decide (and rightfully so) to place program constants in the program memory (Flash). It could even put it in RAM (for whatever reason), which would probably not be a good idea. You may even want to write it to the EEPROM if, say, you wanted to keep track of the average temperature of a week's worth of data, you might want to read the previous value, modify it, and store it in nonvolatile memory for future use.

2. What does it mean to say that some memory type is 'executable'? I've come across many posts across the internet which say things like 'so-and-so processor can execute out of RAM' and 'smaller controllers execute out of Flash'.
Doesn't everything just execute out of the CPU? If we're talking about the source of the instructions and data to execute - isn't Flash memory the only source as it is the only part which we can program (and hence the only part which isn't empty) on reset?
Not necessarily. There are processors that can execute instructions from an external device even, so it doesn't matter where the instruction comes from, the processor can process the data (provided it is in the correct format). Some controllers even use DMA to fetch instructions from an external memory, load it into a RAM FIFO and execute the instructions as happy as it would if it were loaded from an internal Flash.

Also related in this context (and I've always found this confusing), is the RAM usage of a program. I feel I've always used (abused?) the general definition thrown around that RAM is like a scratch-pad for the CPU where it stores all the run-time data and where all the calculations take place. Say, we have an assignment operation:
Rich (BB code):
uint8_t num = 10;    // Initialized variable
From what I've read, the processor maps the 8-bit variable 'num' onto the RAM and the constant '10' onto Flash. What this would mean is that there must occur some time before this assignment takes place, a procedure to somehow 'associate' the value with the variable.
Searching for this, I stumbled upon linker scripts and how we can direct the output to be 'placed' into either Flash or RAM address space which made it even harder to understand. Basically, how can you 'control' what goes into RAM?
A good compiler will not simply translate what you write to an exact representation of what you code. In your example, you write:
Rich (BB code):
uint8_t num = 10;    // Initialized variable
The compiler would look at that, then determine where, if anywhere, this variable is used. If this variable isn't used, the compiler will leave it out and save some space by not storing an unused variable.

Now, if the variable is used, the computer would probably allocate this memory in RAM. That is to say that the compiler will store a reference to the location in RAM that the compiler has decided is associated with that variable. So, if num got mapped to address 0x7375472, then everytime the program references num, the compiler knows to replace it with the value stored at address 0x7375472.

If, however, num was only read, and never written to, or modified by the program, the compiler may opt to put that variable in program memory (Flash), as it's value should never change. Right? Not quite. As we see in microelectronics, register values can change without being explicitly told to do so by the program (status registers, ADC results, timers, etc.). To tell the compiler this is one of such registers, we add the keyword 'volatile' in front to denote the value is volatile and can change without program interaction. This tells the compiler that the program just read the location to know what is there, the previously read value may not be correct.

Does this answer all your questions? Probably not, but hopefully things are a little more clear...
 

ErnieM

Joined Apr 24, 2011
8,377
1. What memory exactly are we referring to when we say 'load from memory'? I thought it meant RAM. But aren't constants and arrays and other data stored in Flash? More generally, isn't everything present on the Flash immediately upon programming?
Well... it depends: what kind of memory do you have, or more specifically what kind of memories do you have? Do you have just one type or two or three or what's going on?

The first microcomputers just had RAM: you literally had to toggle in machine code to get some sort of bootloader before you could even start to do anything.

Some have no RAM, zero, everything is in flash, though it does have several flip flops to save a value or 64.

Some have flash and RAM and some EEPROM too, and the RAM and flash share the same address space, meaning your instructions can come sometimes from RAM and sometimes from flash... same with data, can come from either/or.

I will state categorically statements such as:
Rich (BB code):
uint8_t num = 10;    // Initialized variable
when compiled with a C type of compiler will create program statements that set the number 10 into some sort of storage, probably via c constant but actually by any means convenient. Typically they do this just before the first "v" in
Rich (BB code):
void main (void)
2. What does it mean to say that some memory type is 'executable'? I've come across many posts across the internet which say things like 'so-and-so processor can execute out of RAM' and 'smaller controllers execute out of Flash'.
Again, depends on architecture. "Harvard" types keep data and program memory separate. In "von Neumann" architecture they are mixed. Wiki these terms, read till they make sense.

PICs are Harvard, PCs are Newman.

Doesn't everything just execute out of the CPU? If we're talking about the source of the instructions and data to execute - isn't Flash memory the only source as it is the only part which we can program (and hence the only part which isn't empty) on reset?
Nothing executes "out of the CPU," instructions come from somewhere else and are executed INSIDE the CPU.

I once had a computer where the initial 8K was a ROM memory that held the operating system, and the 58K above that was RAM for programs. It was a Commodore 64 and one of the most popular models ever by cash voting of the general public.
 

Markd77

Joined Sep 7, 2009
2,806
I think on some very fast microcontrollers, maybe ARM, the flash hasn't got fast enough read speeds to run code at full speed, so you can choose to transfer some or all code to RAM and run less critical parts from flash. There's not much point on slower chips, the flash is fast enough.
 

takao21203

Joined Apr 28, 2012
3,702
I think on some very fast microcontrollers, maybe ARM, the flash hasn't got fast enough read speeds to run code at full speed, so you can choose to transfer some or all code to RAM and run less critical parts from flash. There's not much point on slower chips, the flash is fast enough.
Interesting answer but worded like you never actually used such controllers or even did read the datasheet.

Yes it is correct, fast 32bit controllers do have a cache.

You can't just "transfer some or all code to the RAM".
 

kubeek

Joined Sep 20, 2005
5,794
You can't just "transfer some or all code to the RAM".
Yes you can, you can load all flash memory into ram and then jump to start executing from there. That is on some processors that support it, like stm32f407. Of course has to be compiled in such way that it expects the code in those places.
 

takao21203

Joined Apr 28, 2012
3,702
Yes you can, you can load all flash memory into ram and then jump to start executing from there. That is on some processors that support it, like stm32f407. Of course has to be compiled in such way that it expects the code in those places.
You need a RTOS with thread loading funcitonality or how do you specify it in the compiler?

Some PICs can do it too.

The RAM is always much smaller than the FLASH.

just saying there is no such thing as a trivial compiler switch and voila, all your code gets loaded into RAM or even just some code.
 

kubeek

Joined Sep 20, 2005
5,794
I think this is specified in the linker script. Yes the embeedded ram is quite small, but for larger projects you often use external ram.
 

takao21203

Joined Apr 28, 2012
3,702
I think this is specified in the linker script. Yes the embeedded ram is quite small, but for larger projects you often use external ram.
I'd wonder how a linker script can transfer the code from the FLASH into the RAM, as well patch the offsets.

Now you talk about external RAM.

Thinking is good. I think only a RTOS has such functionality. The memory management on larger MCUs is not trivial.
 

Thread Starter

ActivePower

Joined Mar 15, 2012
155
I think this is specified in the linker script. Yes the embedded ram is quite small, but for larger projects you often use external ram.
This is a part of what has been bugging me. Since you specify what parts can be located in what address space, you can theoretically put everything (code, constants and modifiable data) into Flash (provided it has R/W privileges). Apart from speed considerations, why need RAM at all? Same goes for Flash, apart from the fact that you can't exactly 'store' anything in RAM for long. I believe Ernie's answer backs up my understanding.

The C startup scripts I've seen (for ARM, mostly) usually store initialized globals in the Flash and copy them to RAM on starting up, thus allocating space in both the places for the load and the final relocation address - which had me confused as to why we were doing it instead of just using Flash for the entire code and data?

My understanding is still a little fragile in this matter - I am reading up on it. All the answers have helped quite a bit so far. Thanks.
 

kubeek

Joined Sep 20, 2005
5,794
I'd wonder how a linker script can transfer the code from the FLASH into the RAM, as well patch the offsets.
Linker script doesn´t transfer code, it only tells linker to link the pointers to addresses located in RAM, insted of addresses that reside in flash. The startup code then moves the data from flash to RAM, and then finally makes a jump to the first instruction that is now present in RAM. From there on every instruction is executed from RAM (unless you fall back to bootloader or something along those lines).

The major reason here is that the flash is slow and thus requires slow clock, so instead the programmer can choose to have a bit of delay when the mcu boots till it copies the code, and after that run the main clock much higher than it would be possible when executing instructions from flash.
 
Top