 Hello, in this part I will present some hints related to RAM memory usage reduction within Friartos-based application. Friartos uses a region of memory called heap, which is located in RAM. It is used to allocate memory for tasks, queues, semaphores, mutexes and any other operating system component. Friartos heap is different than the system heap defined at the compiler level. When Friartos requires RAM, instead of calling the standard malloc, it calls pvport malloc. When it needs to free-memory, it calls pvport-free instead of standard-free function. Friartos offers several heap management schemes that arrange in complexity and features. It includes five sample memory allocation implementations, which are described in the following link. We have a dedicated module within this training, which are describing them one by one. The total amount of available heap space is set by config.heap size, which is defined within core Friartos config.h file. The export get free heap size apa function returns the total amount of heap space that remains unallocated, allowing the total heap size setting to be optimized. The total amount of heap space that remains unallocated is also available within x3 bytes remaining variable for heap management schemes from 2 to 5. Let's focus a bit on task memory allocation. Each grid task, including the idle task, requires a task counterblock tcb and stack that are allocated on the heap. The tcb size in bytes depends on the options enabled within Friartos config.h file. With minimum configuration, the tcb size is 24 words. If config use task notifications is enabled, we should add 8 bytes to the tcb size. If config use trace facility is enabled, it's necessary to add 8 additional bytes to each tcb. And if config use mutexes is enabled, we should add 8 additional bytes to each tcb within the system. The task stack size is passed as an argument when we are creating the task. The task stack size is defined in words of 32 bits, not in bytes. And Friartos requires to allocate on the heap for each task the number of bytes, which is a sum of tcb size and the form multiplied by task stack size. Using minimal stack size, which is defined within Friartos config.h file, defines a minimum stack size that can be used in words. And for example, the idle task, once it's created, it is using exactly this stack size automatically. How we can fine-tune the stack size for the task? The necessary task stack size can be fine-tuned using the api ux task get stack high watermark as following. Use the initial large stack size allowing the task to run without any issue. For example, 4 kilobytes. Then api ux task get stack high watermark returns the minimum number of 3 bytes ever accounted in the stack of the task. We should monitor the return of this function within the task. Then we can calculate the new stack size as initial stack size minus the minimum stack 3 bytes. This method requires that the task has been run enough to enter the worst path in terms of the stack consumption. Semaphore's mutexes and queues also require memory allocation. In case of semaphore's and mutexes, we need only control block areas to store configuration and current state information. In case of queues, we need a memory to store the data transferred by the queue as well. Each semaphore declared by the user requires 88 bytes to be allocated on the heap. Each mutex declared by the user application requires 88 bytes as well, plus 8 bytes within tcb of each task. To save heap size, so RAM footprint, it is recommended to disable the define configues mutexes when mutexes are not used by the application. FreeR does requires to allocate on the heap for each message queue, so the queue, control block and queue storage area. The number of bytes is 76 plus a queue storage area. So the queue storage area in bytes is element size multiplied by the number of elements plus 16. An example of the queue which should transfer bytes and is 8 elements long, its RAM usage would be 76 plus 8 plus 16, which gave us 100 bytes. We can check it within stm32cube, a mix or stm32cube IDE, using FreeRtos heap usage calculator within FreeRtos configuration section. Software timers are important contributors in heap memory usage as well. The software timers are enabled, so configues timers is enabled within FreeRtos config.tg file. The scheduler creates automatically the timers service task when started. The timer service task is used to control and monitor internally all timers that user would create. The timers task parameters are set through the following defines. Config timer task priority, which is the priority of the timers service task and config timer task depth, which is the timers task stack size in words. The scheduler also creates automatically the message queue used to send commands to the timer service task, so timers to start, timers to stop, etc. The number of elements of this queue, so the number of messages that can be held are configurable through the defined config timer queue length. Let's calculate what is the RAM cost of software timers usage within application, which is using this dose. In safe heap size, it is recommended to disable the defined configues timers when timers are not used in the application. So the first thing we need to calculate this RAM usage is a timer service task in bytes. So it's tcb plus 4 multiplied by the config timer task depth. In case I will define it as 128 words, it will give us more or less 608 bytes. The second thing we need to add to this RAM consumption is a timers message queue, which is more or less 76 bytes plus a queue storage area. And for the storage area, which is let's say 4 elements, we will have more or less 140 bytes. So the third point, each timer created by the user by calling OSTimerCreate needs additional 48 bytes. In total, we will have more or less 800 bytes. So to use one software timer with its dedicated message queue and timer service task, we need more or less 800 bytes of RAM. Now let's have a look at some hints, which could help us to reduce RAM usage within a free ARTAS-based application. We will start from tasks. To optimize stack, a location of each task we need to use uxtask.getStackHighWaterMark function, which returns the minimum number of 3 bytes ever accounted in the task usage. The application stack overflow hook function is telling us whether the stack overflow is detected. And it is available when we activate the define config check for stack overflow. And we'll come back to this point with an advanced topics, when we will discuss about the hooks. To recover the minimum, minimize the stack size used by the main and other parts of the application, we should select properly the number of the tasks as well. And we should use the minimum number of priorities by minimizing the configmax priority settings of an free ARTAS config.h file. Configmax priorities defines the number of priorities available for the application tasks. And a number of tasks can share the same priority, we should remember about it. The scheduler allocates statically the ready list task list of size configmax priorities multiplied by the list entry structure. So each priority we will add, it is extending this structure within the memory allocated by the operating system. Some more hints which could help us to minimize RAMU switch within free ARTAS-based application. If the application doesn't use any software timers, then please disable the define control use timers. But please remember that timers and some of the structures of the timers are used by other components like event flags. If the application doesn't use any mutexes, then disable the define config use mutexes. You will save the tcb size of each task in the application. Then we should use the some functions to adjust the heap dimensioning by using export get free heap size function that returns the total amount of the heap space that remains unallocated and must be used after created all of the task message queues, semaphores and other objects in order to check the heap's consumption and eventually readjust the application defined total heap size. The total amount of heap space that remains unallocated is also available within x3 bytes remaining variable for heap management as schemes from 2 to 5. Thank you for watching this video.