Site icon ucdev

Stack, heap and memory management in microcontrollers

In this article I’ll do my best to explain as simply as possible how memory management in microcontrollers works, what are „stack” and „heap” areas, and what’s the difference between them. Let’s start with a general diagram presenting how „uC” RAM memory is divided into diffrent arreas:

Starting from the bottom, which is the beginning of the memory, there is a segment for the code – at least in case you want to put some part of your code into RAM memory. Most often you don’t need that, so the memory will start with the next segment, which is data. This fragment for „static allocation” so it means that it stores all the global and static variables. What is special about it is that its size was known at the compile time. Next we start with the „heap” area which is dynamically allocated by the programmer. It starts after the „data segment”, and keeps growing. Starting from the end of memory, there is a „stack”. The memory area is allocated automatically by the processor. It keeps growing down, in the opposite direction to the heap. As you can see, it is very important that there will be a free space between them, because both segments change dynamically at „runtime” and it is better when they never meet.

Before I start explaining how „stack” and „heap” areas work, let’s talk a little bit more about memory management. If you are looking for information about those terms, you probably already asked yourself this question: how memory management in microcontrollers works? From the previous chapter you already know that memory can be allocated statically, dynamically and automatically. Each of them refers to different areas of RAM memory.

So far we have covered a very important topic about memory management in microcontrollers, and understand now how it works, but what does the term „stack” actually means? Quoting definition from the Wikipedia:

In computer science, a stack is an abstract data type that serves as a collection of elements with two main operations: Push, which adds an element to the collection, and Pop, which removes the most recently added element. (…) The order in which an element added to or removed from a stack is described as last in, first out, referred to by the acronym LIFO.

https://en.wikipedia.org/wiki/Stack_(abstract_data_type)

To put it simply, stack is a data stored in the section that we describe as automatically allocated by a microcontroller by doing some „push” operation when adding new data to the stack and a „pop” operation for deleting data from the stack. We can imagine it as a stack of books. Every time we like to add a new book to the stack, we can only do it by adding it to the top ( „push” operation), and the stack keeps growing. We can’t remove the first book that is at the bottom, or even books in the middle of the stack. In order to remove some books, we need to start from the top of the stack, and remove them one by one. This is a LIFO buffer in nutshell, which is an acronym from „Last In First Out”

Every time a program goes into some function which calls another function and this function calls some other function etc., there are new „books” added to the stack. These „books” can be different types of data, as was mentioned before. For example, the return address from the function, registers copy of state before entering the function or local data created inside the executed function. Every time a function calls, another function stack grows because new data is added. To take some data from the stack, the whole function must be executed. Then, for example, local variables used by this function are not needed anymore so they can be removed from the stack. Keep this in mind when writing your own code: too much recurrence or uncontrolled recurrence might cause stack overflow. What is stack overflow ? Stack overflow is a situation where a stack grows too big so it runs out of free memory and starts overwriting dynamically allocated sections. If you want to find out more about stack memory management, watch Abelardo Padro video about it on YouTube. I highly recomended it.

There is one term left to explain in this article: „heap”. As it turns out, „stack” was the term for the data stored in an automatically allocated section. The same applies to the heap, but the difference is that this is a section dynamically allocated by a programmer. Dynamically, it means that during the runtime, but where and when depends on how the program was written. Every time a programmer uses functions like „malloc”, „alloc”, „calloc”, part of this section is used. A very important thing here to mention is that this memory won’t be freed automatically by the CPU when not needed. This is a programmer’s responsibility. Don’t forget about it, because this may cause very serious and hard to debug problems.

To sum up this topic, I would like to show you some graphics which show everything that was covered in this article in a very clear and compact way. Now I hope you won’t mistake a stack with a heap anymore. I’m also sure that knowledge learned today helps you avoid very serious problems caused by bad memory management.

Exit mobile version