Arduino · 26 March 2013 1

The microcontroller’s SRAM memory

I wrote in a previous article that the architecture commonly used in microcontrollers is the Harvard architecture, where the SRAM (Static Random Access Memory) that contains the program’s data is separated by the Flash memory in which the program itself is stored. But not everyone knows that the RAM (let’s omit the “S”) is divided into several data areas, some of whom are not well-known. Let’s see them together…

The picture below shows the RAM of an ATmega328P while the program stored into the Flash is running:

SRAM memory usage

The first thing to be noticed is the starting address. You see that it’s $100, hexadecimal for 256. That is because the first 255 memory locations are used by the microcontroller itself to memory map its internal registers (like those of the timers, those of the I/O ports etc….). So the available memory for the user program starts at $100: in the case of the ATmega328P, that has 2048 bytes of available SRAM, the memory starts at $100, or 256, and ends at $8FF, or 2303 (2303-256=2047).

The RAM is organized in some different areas, that have a name assigned by the compiler avr-gcc:

  • at the beginning we find the area named .data, that contains the static variables declared by the program.
  • Next is the .bss area, where the static variables that aren’t declared into the program are located.
  • The following area is the heap: the heap is a particular data structure that is used to manage the memory dynamically allocated. Everything that is created using malloc() goes into the heap, from which is removed with free().
  • The last area is the stack, located in the highest part of the RAM, that contains not only the return points for the jumps to the code’s subroutines but also the local variables and the system registers during the ISR (every time that an interrupt is raised, the corresponding interrupt service routine is called but, first, the CPU stores into the stack the current status of the registers to resume from the same the executon of the halted code when the ISR is finished).

The sum of the .data and .bss areas gives the amount of the memory statically used by your program, and it’s the value returned by avr-size. Instead, the heap and the stack are structures created during the execution of the program and cannot be predicted so the real free memory must be calculated at runtime (in both cases, please refer to my previous article).

The heap cannot overwrite the memory reserved to store the static variables because the area that contains the heap can only grow to the higher part of the RAM and the .data and .bss areas are located before the heap. Instead, the area of the stack expands to the lower part of the memory: there is the risk that if this collide with the heap, this one can overwrite the stack and vice-versa, because the CPU of the microcontroller does no check if this event happens. The results can be catastrophics because the overlapping brings to an immediate malfunction of the program, and an unexpected freeze of the microcontroller too.

So it’s important to remember, during the writing of a program, that we are working with microcontrollers with limited resources (the ATmega328P used on the Arduino UNO has 2 kB of RAM while our computers have quantities of memory measured in GB!!) and to adopt all of the techniques to reduce the waste of RAM:

  • on Arduino, the serial is managed using 2 buffers (one for the incoming and one for the outcoming datas) of 64 bytes each, so when we use the serial we reserve 128 bytes of RAM for that interface. So, use the serial only when it’s necessary, and remove it if your program doesn’t use it (i.e., remove it after debugging).
  • Use the proper data types in your programs. I.e., the use of an int to store the value of a pin is an error because this will never have an high value. It is better if you use a byte type: this one requires only 1 byte of RAM, while an int requires 2 bytes.
  • Any variable that is used in a program must be copied in RAM before it can be used! This is due to the Harvard architecture, that sepatates the memory where the program resides, the Flash, from the memory where the datas “live”, the SRAM. This is valid for strings too: if you use strings, i.e. working with an LCD display or by interacting with your program through the serial, the risk of a memory saturation is very high. Luckily, the IDE 1.0 introduced into the Arduino core the F() function that can read strings directly in Flash (this is permitted at runtime) without the necessity to copy them into RAM first. However, this function can only use predefined texts and cannot manage strings that are built at runtime., and olny with the Arduino functions Serial.print/ln and Lcd.print/ln (the first one is used to write to the serial, the second one is used to write on an LCD display through the integrated library LiquidCrystal). So, the following is a right use:
    Serial.println(F("Hello")); //this is lecit

    while the following is not:
    String temp = "Ciao";
    Serial.println(F(temp)); //this is NOT lecit
  • Please remember that the Flash is organized in words, or a couple of bytes. Let’s think about this: when you compile a sketch, you will never see the size of the program with a odd value, you will ever see an even value. Despite the 8-bits MCU, the memory has a 16-bits architecture. So, if your sketch would be 1353 bytes in size, it will occupy 1354 bytes in Flash. This is valid for your strings too that, as we already have said, they are stored in Flash inside your sketch but has to be copied into RAM during the execution of the program (unless you use the F() function mentioned above). So, when your string is transferred into the RAM, it will use the same amount of memory that was using into the Flash: “HELLO” (5 bytes long) will occupy 6 bytes, as many bytes as the string “BYEBYE” (6 bytes long).

Below you’ll find a sketch che you can use to get informations about the real-time RAM usage: the calculated free memory is the memory that is between the end of the heap and the beginning of the stack. The sketch also prints some informations about the addresses of the starting and ending points of all of the mentioned areas.

More info: link 1.

Know Your Sram
Know Your Sram
know_your_sram.ino
Version: 1.0
2.2 KiB
2347 Downloads
Details...