DÍA 181 DE 365

Fase 4: FreeRTOS y Conectividad IoT

📖 Teoría a Estudiar

El Problema Fundamental del Bucle Infinito

El código Bare-Metal que escribimos en la Fase 3 es estrictamente secuencial. Esto significa que la CPU procesa una tarea tras otra. Las interrupciones (ISRs) pueden robar la atención por unos microsegundos, pero al final, el procesador debe volver al Súper Bucle (Super Loop) y seguir la lista de pendientes.

La regla de oro del Súper Bucle es: Ninguna tarea debe bloquear la CPU. Si necesitas encender un actuador por 1 segundo, no puedes usar delay(1000), porque el sistema entero se congela. Tienes que usar la técnica de Polling no bloqueante: revisar la hora (SysTick), seguir haciendo otras cosas, y regresar a apagarlo cuando la hora correcta haya llegado.

El Caos del IoT (Latencia Impredecible)

Cuando te conectas a Internet, la latencia es anárquica. Le envías un comando a un chip WiFi (ESP32) para abrir un socket TCP hacia la nube. ¿Cuánto tardará la respuesta? Puede ser 10 ms, o si la red está saturada, pueden ser 3000 ms. Intentar programar esto de forma no bloqueante convierte tu código en una pesadilla insostenible de cientos de condicionales if/else. Tu código sufre de Jitter (Fluctuación): tareas críticas pierden sus plazos de tiempo (Deadlines) porque la CPU estaba ocupada atendiendo la burocracia de la red WiFi.

CRISIS DEL SUPER LOOP VS. PREEMPCIÓN (FreeRTOS) TIEMPO DE CPU (ms) → t = 0 t = 100 t = 200 (Deadline) t = 300 Bare-Metal (Secuencial) 1. Leer Sensores (Rapido) 2. Enviar Datos AWS (WiFi) La red tiene lag... CPU bloqueada esperando... Recibe 'HTTP 200 OK' 3. Cerrar Válvula ¡PÉRDIDA DE DEADLINE! El gas se derramó 160ms extra FreeRTOS (Preemptivo) Task 1: Sensores Task 2 (Baja Prioridad) Enviando AWS WiFi... FreeRTOS CONGELA la Tarea 2 Task 3 (Prioridad MÁX) Cerrar Válvula Exacto a t=200 Task 2 Se Reanuda Continúa esperando red...

⚙️ Ejercicios Prácticos

Ejercicio 1: Analizaremos cómo el nuevo requerimiento de IoT destruye la Máquina de Estados (FSM) que orquestamos en la fase anterior. El jefe pidió enviar un Ticket JSON mediante un módulo WiFi ESP32 conectado al puerto UART. Observa cómo el código secuencial colapsa por culpa del mundo real.

El Código que Destruye la Máquina (Anti-patrón Bloqueante)


/**
 * @file main_con_falla_iot.c
 * @brief Demostración de colapso de un Super Loop por latencia de Red WiFi.
 */

#include "stm32f401xe.h"
#include <stdbool.h>

// ... (Inclusiones omitidas)

// Función de red asíncrona - La pesadilla del Bare-Metal
bool ESP32_Enviar_HTTP_POST(const char* json_data) {
    // 1. Envía comando AT al chip WiFi
    UART_Enviar_Cadena("AT+HTTPPOST=...\r\n");
    
    // 2. PROBLEMA GRAVE: Retardo bloqueante esperando respuesta de AWS
    // En el mundo real, el WiFi puede tardar hasta 3 segundos en contestar.
    uint32_t timeout = 3000; 
    uint32_t start_time = Obtener_Milisegundos();
    
    // El procesador se queda girando aquí inútilmente
    while((Obtener_Milisegundos() - start_time) < timeout) {
        if (UART_Leer_Respuesta() == "200 OK") {
            return true; // ¡Se envió!
        }
    }
    return false; // Error de red
}

int main(void) {
    
    SystemState_t estado = SYS_STATE_IDLE;
    
    while(1) {
        
        // El Súper Bucle Clásico
        switch(estado) {
            
            case SYS_STATE_DISPENSING:
                if (Metro_LimiteVentaAlcanzado()) {
                    Valvula_SetApertura(0.0f); // ¡Cierra para no derramar!
                    estado = SYS_STATE_FINISHED;
                }
                break;
                
            case SYS_STATE_FINISHED:
                
                // NUEVO REQUERIMIENTO: Subir a la nube
                char* ticket = Crear_Ticket_JSON();
                
                // EL COLAPSO:
                // Al llamar a esta función, el STM32 se encierra en el while() de arriba
                // por 3 segundos. El Súper Bucle SE CONGELA POR COMPLETO. 
                // Si la válvula debía cerrarse por emergencia en este lapso, no lo hará.
                ESP32_Enviar_HTTP_POST(ticket);
                
                estado = SYS_STATE_IDLE;
                break;
                
            // ... otros estados ...
        }
    }
    return 0;
}
        

El Intento Fallido de Arreglarlo (Spaghetti de Estados)

El ingeniero inexperto intentará arreglar esto sin FreeRTOS agregando más y más "estados" a la FSM para no bloquear la máquina simulando multitarea. El resultado es un código espagueti incomprensible y propenso a errores catastróficos.


// INTENTO DE SOLUCIÓN SIN RTOS (Máquina de Estados de Red Anidada)
// El código se vuelve ilegible, frágil e insostenible a largo plazo.

case SYS_STATE_FINISHED:
    if (fase_wifi == INICIANDO) {
        UART_Enviar_Cadena("AT+HTTPPOST=...\r\n");
        timer_wifi = Obtener_Milisegundos();
        fase_wifi = ESPERANDO_RESPUESTA;
    }
    else if (fase_wifi == ESPERANDO_RESPUESTA) {
        // No bloqueamos, revisamos rápido y salimos del switch
        if (UART_Hay_Datos()) {
            if (UART_Leer_Respuesta() == "200 OK") {
                fase_wifi = COMPLETADO;
                estado = SYS_STATE_IDLE;
            }
        }
        else if ((Obtener_Milisegundos() - timer_wifi) > 3000) {
            // Manejo complejo de timeouts inter-ciclos
            fase_wifi = ERROR;
            estado = SYS_STATE_IDLE;
        }
    }
    break;
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Diagnóstico de Cuellos de Botella y Transición al IoT.

Hasta ayer, tu máquina era una joya electromecánica puramente local. Pero hoy, vivimos en la era de la Industria 4.0. Las gasolineras necesitan telemetría en vivo, gestión de flotillas en la nube (AWS/Azure) y reportes remotos. Al intentar introducir conectividad WiFi mediante un coprocesador ESP32 conectado al bus UART de tu STM32, hemos tropezado con la barrera de cristal del entorno Bare-Metal: El Bloqueo por Latencia de Red.

Si la CPU pasa milisegundos invaluables "esperando" que un servidor de la nube en el otro lado del mundo le responda que el recibo de venta fue guardado, fallará en cerrar la válvula de seguridad a tiempo si hay una emergencia, derramando Gas LP inflamable. Modificar la Máquina de Estados Finita (FSM) para manejar la red de forma asíncrona es matemáticamente posible, pero llevaría a miles de líneas de código "espagueti". La solución industrial definitiva es cambiar el motor del sistema operativo. Necesitamos un **RTOS (Real-Time Operating System)**, capaz de suspender la tarea de red de golpe para darle la CPU a las tareas críticas.

📝 Resumen del Día