I'd like to know what is the difference between RAM ( data memory ) and the stack memory in PIC micro controllers if both of them is volatile( not sure about stack ) and the stack is temporary memory?
Electronic – RAM and stack memory
microchipmicrocontrollermicroprocessorpic
Related Solutions
Everything is done in "sections". Where a section goes depends on its use. What gets put into a section, again, depends on its use.
In general you get two "data" sections - .data and .rodata. .data is stored in RAM and is read-write. .rodata is stored in Flash and is read-only.
Things that are "const" generally end up in .rodata. Literals (string, numeric, etc) also end up in .rodata.
For instance, these would normally be stored in Flash:
const char *foo = "foo";
const int bar = 234;
"baz" (string literal)
These will be stored in RAM:
char foo[10];
int bar;
But then of course, it can be more MCU specific, especially when you get into Harvard (split RAM / Flash address spaces) architecture, where accessing data stored in Flash can be more of a special task and not done as normal variables. For instance, the const char *foo="foo";
would be copied into RAM for easy access during the initialization of the program.
When you allocate a variable of any size within a function, such as:
void func() {
char mybuf[100];
}
the variable will be allocated as part of the stack (or an emulated stack-like system using static variables on MCUs with a limited hardware stack, such as low-end 8-bit PICs). As soon as you return from the function all the stack space is reclaimed.
However, if you allocate it using malloc():
void func() {
char *mybuf = malloc(100);
}
it will be allocated on the heap, and it is your responsibility to reclaim that space using free().
The register
keyword, as in:
int register foo;
will, if a register can be allocated, store the data purely within that allocated register. It will never touch RAM, and consequently it will run faster. However, if a register cannot be allocated (they're all in use in the code) then the register keyword will be ignored and the variable allocated in RAM as per normal. One thing to note:
char register *foo;
That will only hold the pointer to the data in a register, not the data itself. The data itself will still be in RAM.
In general, though, the use of the register
keyword is frowned upon since the compiler's optimizer usually does a better job, and using register
can in fact cause other parts of your code to not be optimized as well and end up more complex than they would otherwise be.
It depends on the architecture -- there are two schools of thought on this, going back to the 1940's.
One is called Harvard architecture, and means that the addresses for flash program code, RAM storage, and I/O are all in separate address spaces. That means there can be an address 0x100 for program, 0x100 for RAM, and 0x100 for I/O and they are all different.
The second type is called Von Neumann architecture, in which flash program code and RAM are in the same address space. I/O may also be in the same address space, if it is "memory-mapped", or separate if it uses I/O port addressing.
Most microprocessors like the 0x86 in your desktop have a Von Neumann architecture. Both program code and data are stored together in the same RAM. There is also a separate read-only memory (ROM) that holds a bit of code that is executed when the processor first boots up, to load the OS (Windows, Linux, etc) off of the hard drive and into RAM. This ROM is also in the same address space, typically at the very high end.
Most, but not all microcontrollers on the other hand use use Harvard architecture. 8 or 16-bit microcontrollers typically have up to 64K of flash program memory, and several thousands bytes of RAM. (Flash may be extended beyond 64K using various paging schemes -- but the actual addresses are still 16-bit and stay in the same address space). I/O is addressed via internal I/O register addresses.
An exception to this, among others, are Freescale microcontrollers like the MC9S08 etc. which put flash program addresses, RAM, and memory-mapped I/O all in the same address space.
Note in this diagram, memory is shown with address 0x0000 at the top, and 0xFFFF (64K-1) at the bottom. The low-order memory-mapped I/O addresses 0x0000 through 0x007F are allocated first, followed by RAM at 0x0080 to 0x17FF. This is done so low addressed I/O and low addressed RAM (0x0080-0xFF) can use special instructions that target the first 256 bytes of the 64K address space -- those address below 0x00FF which only need one byte for the address field (known as "page 0 addressing").
The RAM segment is followed by more memory-mapped I/O, then more RAM, and then the first block of flash starting at 0x2180. This is interrupted by 2K of EEPROM at 0x3C00, and then the rest of the program space up to 0xFFFF is flash. There is a paging window at 0x8000 through 0xBFFF to provide for an additional 32K of flash.
In a Von Neumann machine, if you try to allocate at address 0x300, then that address will point to either RAM, or flash, but not both. So there is no conflict.
In a Harvard architecture machine, address 0x300 could be either RAM or flash. So how is that differentiated? This is C-compiler specific, so it will be different for different microcontrollers. But by default, all references to memory addresses will be for RAM. However if a variable is preceded by the C keyword const, then that data is put into flash. (And of course all other constants, such as strings, are automatically put into flash by the compiler.)
If a program wants to read flash memory directly, it typically has to call a vendor supplied function and/or writing to a set of special registers to do so. For example, on the Microchip PIC16F microcontrollers, it takes 13 machine instructions just to read one program word (14 bits) out of flash. And this is certainly the case if a program wants to write to flash, since the MCU has to go through several steps to erase and then reprogram the bytes in flash that are to be changed.
For microcontrollers, memory protection is generally available only for flash memory -- and this protection simply means neither a program or external programmer can modify the flash area while protection is on. This is usually done in pages, so some of the flash can be protected (e.g. a boot area) and the rest left unprotected so it can be updated in the field FOTA (firmware over the air). Many microcontrollers also have the ability to make the flash memory unreadable by an external programmer after the microcontroller has been programmed. This is to prevent a competitor from trying to read the binary program out of a company's products.
Microprocessors, like the 0x86, have much more complicated protection schemes, tied into their virtual address schemes, and at a basic level divide the RAM into kernel and user spaces. (Remember, they are 99.99% RAM, and hardly any ROM). Kernel space is where the core of the operating system lives, along with most device drivers. Application programs are in the user space. A memory protection fault occurs if a user program tries to execute a privileged kernel instruction, or access hardware directly.
Related Topic
- Electronic – Can GPIO connectors be used for the same purposes as PIC i/o ports
- Banked and non banked memory
- Electronic – Is a boot-loader needed to dump the flash memory to RAM? Why
- Electronic – the significance of “microcontroller based on microprocessor”
- Electronic – the difference between EEPROM Data Memory and RAM
Best Answer
All RAM memory requires a constant current to hold its state. That is, as soon as you turn the power off, all of your RAM memory vanishes. Thus, RAM is volatile.
The stack is a specific area of RAM memory used to store temporary variables during program execution. Each function call "pushes" data to the stack. The data is "popped" when the function returns. Because the stack is stored in RAM, it too is volatile.