Un RTOS es un sistema operativo diseñado para responder a eventos dentro de tiempos conocidos, algo fundamental cuando programamos sistemas embebidos que no pueden quedarse “pensando” indefinidamente.
Iniciamos un nuevo curso en la web, y este es uno de los que más ganas tenía de traer. Vamos a hablar de FreeRTOS y de sistemas operativos en tiempo real.
Si vienes del mundo de Arduino, es muy probable que estés acostumbrado a programar dentro de setup() y loop(). Es la forma estándar, sencilla y funciona de maravilla para parpadear un LED o leer un sensor.
Pero, a medida que nuestros proyectos crecen, empezamos a encontrarnos con problemas. Queremos leer un sensor cada 100ms, controlar un motor paso a paso, atender peticiones WiFi y actualizar una pantalla, todo “a la vez”.
En ese punto la programación secuencial clásica empieza a hacer aguas y un RTOS se convierte en una herramienta muy útil.
En este curso usaremos principalmente ESP32, ya que utiliza FreeRTOS de forma nativa en su SDK, aunque los conceptos son aplicables a cualquier microcontrolador compatible.
El paradigma del “Super Loop”
Antes de entender la solución, analicemos el problema. La arquitectura clásica de un firmware simple es el Bucle Infinito o “Super Loop”.
void setup() {
// Inicialización
}
void loop() {
leerSensores();
procesarDatos();
actualizarPantalla();
moverMotores();
}Esto es programación secuencial. El procesador ejecuta la primera instrucción, luego la segunda, y así sucesivamente.
El problema del bloqueo
El problema surge cuando una de esas funciones tarda mucho tiempo. Por ejemplo, imagina que usamos la infame función delay():
void loop() {
digitalWrite(LED, HIGH);
delay(1000); // <--- El procesador se queda AQUÍ bloqueado
digitalWrite(LED, LOW);
delay(1000);
leerBoton(); // <--- Si pulsas el botón durante el delay, el sistema NO se entera
}Mientras el procesador está contando milisegundos en el delay(), no puede hacer nada más. Si llega un dato por el puerto serie, si el usuario pulsa un botón o si hay una emergencia, el microcontrolador está “sordo”.
Podemos mejorar esto usando millis() y máquinas de estados (como hemos visto muchas veces en el blog), pero el código se vuelve complejo, difícil de leer y de mantener a medida que añadimos funcionalidades.
¿Qué es un RTOS?
Un RTOS (Real-Time Operating System) es un sistema operativo diseñado para gestionar los recursos del hardware (CPU y memoria) con tiempos de respuesta predecibles y acotables.
A diferencia de sistemas operativos de propósito general (como Windows o Linux), donde el objetivo es el rendimiento global (throughput), en un RTOS el objetivo principal es el determinismo y la latencia.
Esto nos permite diseñar el sistema para que, si ocurre un evento crítico, reaccione dentro de un plazo conocido. Pero ojo: usar un RTOS no garantiza por sí solo que cumplamos ese plazo. También necesitamos asignar bien las prioridades, evitar bloqueos largos y analizar el peor caso.
Multitarea y el Planificador (Scheduler)
La gracia de un RTOS está en su capacidad para simular multitarea.
Aunque tengamos un solo núcleo en el procesador, el RTOS nos permite dividir nuestro código en pequeñas unidades independientes llamadas Tareas (Tasks).
El componente encargado de gestionar esto es el Scheduler (Planificador). El Scheduler detiene una tarea, guarda su estado, carga el estado de la siguiente tarea y la ejecuta.
Esto ocurre tan rápido (cientos o miles de veces por segundo) que nos da la ilusión de que todo se ejecuta simultáneamente.
Multitarea Apropiativa (Preemptive)
FreeRTOS utiliza normalmente un modelo de multitarea apropiativa. Esto significa que el Scheduler puede interrumpir (apropiarse de) la tarea que se está ejecutando en cualquier momento para dar paso a otra tarea de mayor prioridad.
Imagina este escenario:
- Tenemos una tarea
TareaPantalladibujando gráficos (prioridad baja). - Llega una interrupción de un sensor crítico y desbloquea
TareaSensormediante una API segura para ISR. - El Scheduler pausa inmediatamente la
TareaPantalla. - Ejecuta la
TareaSensor(prioridad alta). - Al terminar, reanuda
TareaPantallaexactamente donde se quedó.
Esto es algo que con un “Super Loop” es extremadamente difícil de conseguir de forma limpia.
Diferencias: Super Loop vs RTOS
Para visualizarlo mejor, veamos una comparativa directa:
| Característica | Super Loop (Bare Metal) | RTOS (FreeRTOS) |
|---|---|---|
| Estructura | Un bucle while(1) gigante | Múltiples Tasks independientes |
| Gestión de tiempo | Esperas que detienen el flujo o lógica manual con millis() | Esperas que bloquean solo la tarea actual |
| Complejidad | La coordinación se enreda al crecer | Las responsabilidades se separan en tareas |
| Respuesta | Depende de la duración del bucle | Depende de prioridades, bloqueos e interrupciones |
| Uso de CPU | Puede desperdiciar CPU con espera activa | La CPU puede entrar en Idle si no hay trabajo |
¿Por qué usar FreeRTOS?
Llegados a este punto, puedes pensar: “Bueno, pero yo con millis() me apaño bien”. Y es cierto para proyectos pequeños. Pero usar un RTOS ofrece ventajas importantes:
- Modularidad: Cada parte del programa (WiFi, sensores, motor) puede tener su propia tarea y una responsabilidad clara.
- Mantenibilidad: Es mucho más fácil añadir una nueva funcionalidad sin romper las anteriores. Simplemente creas una nueva Tarea.
- Gestión de tiempos: Podemos decir “ejecuta esto cada 100ms exactos”, y el RTOS se encarga.
- Uso eficiente de Drivers: En el caso del ESP32, el WiFi y el Bluetooth corren sobre FreeRTOS. Si usas ESP32, ¡ya estás usando FreeRTOS aunque no lo sepas!
Inconvenientes (no todo es gratis)
Como en toda ingeniería, hay un compromiso (trade-off).
- Consumo de recursos: El RTOS necesita memoria RAM para gestionar las tareas (cada tarea necesita su propia pila o Stack) y consume ciclos de CPU para el cambio de contexto.
- Complejidad de depuración: Surgen nuevos tipos de errores, como condiciones de carrera (Race Conditions), bloqueos mutuos (Deadlocks) o desbordamientos de pila (Stack Overflow).
Pero no te preocupes, porque precisamente para aprender a evitar esos problemas hemos creado este curso.