Introduction to RTOS Part 4 - Memory Management | Digi-Key Electronics

Introduction to RTOS Part 4 - Memory Management | Digi-Key Electronics

Gestión de Memoria en RTOS

Introducción a la gestión de memoria

  • La gestión de memoria es crucial al escribir código para un RTOS, ya que entender dónde se almacena cada dato ayuda a prevenir desbordamientos de pila y fugas de memoria.

Asignación estática y dinámica

  • Al iniciar un programa, se asigna una sección de memoria para variables globales y estáticas, conocida como memoria estática. Esta no puede ser utilizada por otras partes del programa.
  • Las variables locales dentro de una función se almacenan en la pila (stack), que opera bajo el principio LIFO (último en entrar, primero en salir). Esto facilita la gestión durante llamadas a funciones anidadas.

Crecimiento automático de la pila

  • La pila puede crecer automáticamente según sea necesario, reservando espacio adicional desde la memoria libre. Variables locales y argumentos son almacenados aquí.
  • Existe otra área llamada heap (montículo), que también puede crecer durante la ejecución del programa. Su disposición exacta puede variar entre arquitecturas y compiladores.

Asignación dinámica con el heap

  • El heap se utiliza para asignaciones dinámicas donde el programador indica explícitamente cuánto espacio necesita mediante funciones como malloc.
  • Es importante liberar cualquier memoria asignada dinámicamente al finalizar su uso; si no se hace, puede causar fugas de memoria difíciles de rastrear.

Problemas potenciales con el heap

  • Si tanto el heap como la pila crecen sin límites, pueden sobrescribirse mutuamente, lo cual genera comportamientos indefinidos.
  • En FreeRTOS, cuando se crea una nueva tarea, esta recibe una parte del heap dividida entre un bloque de control (TCB) y su propia pila.

Control sobre tareas en FreeRTOS

  • Al crear tareas con xTaskCreate, especificamos cuánto heap reservar para cada tarea. No reservar suficiente espacio puede llevar a sobrescribir áreas críticas.
  • FreeRTOS permite asignar memoria estática para tareas y objetos del kernel en versiones más recientes; esto es útil en aplicaciones críticas donde las fugas podrían ser catastróficas.

Estrategias para evitar fragmentación del heap

  • Al realizar múltiples asignaciones y liberaciones en el heap, este podría fragmentarse rápidamente. FreeRTOS ofrece diferentes esquemas de gestión del heap para mitigar este problema.
  • Heap 4 es preferido por permitir unir áreas fragmentadas del heap; mientras que Heap 3 envuelve las funciones malloc y free para hacerlas seguras ante hilos.

Consideraciones finales sobre el esquema del esp32

  • El esp32 tiene varios tipos diferentes de RAM lo que complica aún más su esquema específico de asignación del heap.

Manejo de Memoria en FreeRTOS

Creación y Gestión de Tareas

  • Se inicia un ejemplo donde se crea una tarea que almacena números en un arreglo y luego imprime uno de esos números. Se eliminan las tareas de configuración y bucle para asegurar que solo haya una tarea en ejecución.
  • Se utiliza un arreglo grande (cien elementos), lo que consume 400 bytes. La tarea tiene asignado un kilobyte de pila, pero el overhead es de aproximadamente 768 bytes.

Desbordamiento del Buffer

  • Si se excede la memoria asignada a la pila, el procesador se reinicia. Esto indica que ha ocurrido un desbordamiento del buffer.
  • El "stack canary" es una medida de seguridad implementada por el sistema operativo para prevenir desbordamientos; verifica valores conocidos al final de la pila.

Ajustes en el Tamaño de Pila

  • Para evitar errores, se debe calcular correctamente la memoria necesaria para la tarea, considerando tanto el overhead como las variables locales. Se sugiere aumentar el tamaño de la pila a 1500 bytes.
  • Utilizar uxTaskGetStackHighWaterMark del API FreeRTOS permite monitorear cuántos bytes quedan disponibles en la pila.

Monitoreo del Heap

  • Con vPortGetHeapSize, se puede observar la cantidad total de memoria heap disponible antes y después de usar malloc.
  • En FreeRTOS, es recomendable usar pvPortMalloc ya que malloc no es seguro para hilos. Es importante simular uso con un retraso para evitar optimizaciones del compilador.

Manejo Seguro de Memoria Dinámica

  • Al intentar asignar memoria sin suficiente espacio contiguo, se genera un mensaje indicando falta de heap. Es crucial verificar si malloc o pvPortMalloc retornan null.
  • Debe liberarse adecuadamente la memoria dinámica utilizando funciones específicas como vPortFree, asegurando así que no haya fugas durante las iteraciones.

Desafío Propuesto

  • Se propone crear dos tareas: una escucha entradas desde el monitor serial y almacena mensajes en heap; otra imprime los mensajes recibidos y libera esa memoria.
Video description

Memory management is important in a multi-threaded environment, as threads (or tasks) can quickly consume all of the allocated memory, causing bizarre effects such as overwritten memory locations or random processor resets. The solution to the challenge in the video can be found here: https://www.digikey.com/en/maker/projects/introduction-to-rtos-solution-to-part-4-memory-management/6d4dfcaa1ff84f57a2098da8e6401d9c In this video, we look at various ways to allocate memory to a task and how to monitor memory usage in FreeRTOS. Most C programs rely on 3 different types of memory. Static memory is set aside prior to program execution and used for things like static variables, constants, and global variables. Stack is allowed to grow dynamically and consists of local variables declared at the function level. Finally, heap may also grow dynamically and must be specifically allocated and deallocated by the programmer (e.g. using the malloc() and free() functions, respectively). Whenever we create a new task in FreeRTOS, we must assign it a set amount of stack memory to use out of the global, available heap. Note that each task also requires another section of heap for the Task Control Block (TCB), which stores various attributes about the task, such as its state and priority. We demonstrate ways to monitor the stack in each thread as well as the total amount of heap available to the system. We also show what happens when you overrun the stack or heap! Product Links: https://www.digikey.com/en/products/detail/adafruit-industries-llc/3405/7244967 Related Videos: Introduction to RTOS Part 1 - What is a Real-Time Operating System (RTOS)? - https://youtu.be/F321087yYy4​ Introduction to RTOS Part 2 - Getting Started with FreeRTOS - https://youtu.be/JIr7Xm_riRs​ Introduction to RTOS Part 3 - Task Scheduling - https://youtu.be/95yUbClyf3E​ Introduction to RTOS Part 4 - Memory Management - https://youtu.be/Qske3yZRW5I​ Introduction to RTOS Part 5 - Queue - https://youtu.be/pHJ3lxOoWeI​ Introduction to RTOS Part 6 - Mutex - https://youtu.be/I55auRpbiTs​ Introduction to RTOS Part 7 - https://youtu.be/5JcMtbA9QEE​ Introduction to RTOS Part 8 - https://youtu.be/b1f1Iex0Tso Introduction to RTOS Part 9 - https://youtu.be/qsflCf6ahXU Introduction to RTOS Part 10 - https://youtu.be/hRsWi4HIENc Introduction to RTOS Part 11 - https://youtu.be/C2xKhxROmhA Introduction to RTOS Part 12 - https://youtu.be/LPSHUcH5aQc Related Project Links: https://www.digikey.com/en/maker/projects/introduction-to-rtos-solution-to-part-4-memory-management/6d4dfcaa1ff84f57a2098da8e6401d9c Related Articles: https://www.digikey.com/en/maker/videos/shawn-hymel/getting-started-with-stm32-and-nucleo-part-3-how-to-run-multiple-threads-with-cmsis-rtos-interface Learn more: Maker.io - https://www.digikey.com/en/maker Digi-Key’s Blog – TheCircuit https://www.digikey.com/en/blog Connect with Digi-Key on Facebook https://www.facebook.com/digikey.electronics/ And follow us on Twitter https://twitter.com/digikey