DÍA 233 DE 365

Fase 4: FreeRTOS y Conectividad IoT

📖 Teoría a Estudiar

El Ecosistema LwIP (Lightweight IP)

Una tarjeta de red no sabe qué es una página web ni qué es un JSON. Solo recibe voltajes y los convierte a bytes puros (0s y 1s). Para que esos bytes cobren sentido y se conviertan en conexiones a internet, se requiere un software que entienda el Modelo OSI (Direcciones MAC, IPs, Puertos TCP/UDP).

En las computadoras, Windows y Linux tienen sus propios Stacks TCP/IP masivos de gigabytes. Para los microcontroladores, el Instituto Sueco de Informática creó LwIP, una pila TCP/IP completa escrita en C diseñada para funcionar con apenas ~40 Kilobytes de memoria RAM. Es el estándar de oro de la industria embebida (ESP-IDF, FreeRTOS y CubeMX lo usan internamente).

Pila Nativa vs Descarga de Red (Network Offloading)

La decisión arquitectónica más crítica en un diseño IoT es: ¿DÓNDE corre LwIP?

ARQUITECTURAS DE PILA: NATIVO (LWIP) VS DESCARGA (OFFLOADING) PILA NATIVA (Cuello de Botella de RAM) STM32 (96 KB RAM) Metrología Gas LP 10 KB RAM LwIP Stack (TCP/IP) - 30 KB RAM Sockets, Buffers, ARP MbedTLS (Cripto) - 45 KB RAM Cálculo de Certificados Módulo Dummy (Solo capa MAC/PHY) Ej. ESP32 en modo SLIP SPI (Lento) ¡PELIGRO! Quedan 11 KB Imposible descargar FOTA NETWORK OFFLOADING (Óptimo IoT) STM32 (96 KB RAM) Metrología Gas LP 10 KB RAM Protocolo Binario 1 KB RAM RAM LIBRE: 85 KB Suficiente para Búferes FOTA Paginado (Día 219) Coprocesador (ESP32 / Módem LTE) LwIP Stack (TCP/IP) Corre nativo a 240MHz MbedTLS / Sec Hardware Acellerated UART TX Estructura C

⚙️ Análisis de Código

¿Qué nos estamos ahorrando? Aunque no compilaremos LwIP nativo en nuestro STM32F401, como Mentor es mi deber mostrarte cómo luciría el código si hubiéramos elegido el camino equivocado. Observa la cantidad de estructuras y memoria que exige inicializar un Socket TCP nativo versus nuestro enfoque de Offloading por UART.


/**
 * @file network_architectures.c
 * @brief Comparativa Teórica: LwIP Nativo vs Offloading Binario
 */

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

// =========================================================================
// ESCENARIO 1: LWIP NATIVO EN EL STM32 (El camino de dolor)
// (Ejemplo pseudocódigo de inicialización con librerías nativas LwIP)
// =========================================================================
/*
#include "lwip/opt.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/sockets.h"

// Variables Masivas Globales (Robando memoria RAM al STM32)
struct netif gnetif;
ip4_addr_t ipaddr, netmask, gw;

void STM32_Native_LwIP_Init(void) {
    // 1. Inicializar la pesada pila de software TCP/IP
    lwip_init();

    // 2. Definir direcciones IP estáticas o iniciar DHCP
    IP4_ADDR(&ipaddr, 192, 168, 1, 10);
    IP4_ADDR(&netmask, 255, 255, 255, 0);
    IP4_ADDR(&gw, 192, 168, 1, 1);

    // 3. Añadir la interfaz de red (requiere drivers MAC de bajo nivel)
    netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);
    netif_set_default(&gnetif);
    netif_set_up(&gnetif);

    // 4. Crear un Socket POSIX complejo
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(8883);
    dest_addr.sin_addr.s_addr = inet_addr("54.23.10.2"); // AWS IP

    // 5. Inyectar MbedTLS (El golpe final a la RAM...)
    // mbedtls_ssl_init(&ssl);
    // mbedtls_ssl_setup(&ssl, &conf);
    // mbedtls_ssl_set_hostname(&ssl, "aws.com");
}
*/


// =========================================================================
// ESCENARIO 2: NUESTRO ENFOQUE - NETWORK OFFLOADING (Hardware Coprocessor)
// =========================================================================
// El STM32 no sabe qué es una IP, ni un Socket, ni TLS. 
// Simplemente empaqueta la variable física y la delega.

#include "protocolo_iot.h" // Nuestra trama binaria (21 bytes)
extern void UART_Transmit(uint8_t* data, uint16_t length);

void STM32_Offloaded_Send_Venta(uint32_t folio, float litros) {
    
    // 1. Instanciar la pequeña estructura en memoria local (Stack)
    Trama_Binaria_t trama;
    trama.header.sync_word = FRAME_SYNC_WORD;
    trama.header.comando   = CMD_ENVIAR_VENTA;
    trama.header.longitud  = sizeof(Payload_Venta_t);
    
    trama.payload.venta.folio_ticket = folio;
    trama.payload.venta.litros_gas   = litros;
    
    // 2. Calcular Checksum para proteger el viaje por el cable
    trama.crc8 = Calcular_CRC8((uint8_t*)&trama, sizeof(Trama_Header_t) + trama.header.longitud);

    // 3. Disparar al Coprocesador (El ESP32 o el BG95 harán todo el trabajo sucio de LwIP)
    // Costo de CPU: Casi nulo (Usamos DMA).
    // Costo de RAM: 21 Bytes.
    UART_Transmit((uint8_t*)&trama, sizeof(Trama_Binaria_t));
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Justificación Arquitectónica de Desacoplamiento (Decoupling) y Economía de Memoria.

Al documentar tu proyecto de Tesis, el jurado te hará una pregunta trampa: "¿Por qué utilizaste dos microcontroladores (STM32 + ESP32/Módem) si existen chips como el ESP32 que pueden hacer la metrología y el WiFi al mismo tiempo, o chips ST con Ethernet integrado?"

Tu respuesta debe basarse en el **Presupuesto de Memoria (Memory Budget) y la Certificación de Normas**. Si usas un solo chip para la Metrología (calcular con alta precisión el volumen del gas basándose en el sensor físico) y simultáneamente ejecutas la pila LwIP y MbedTLS nativas, la RAM se satura y el RTOS pierde determinismo. Un ataque cibernético DDoS (saturación de red) en tu IP pública pondría a la pila LwIP a trabajar al 100%, congelando los cálculos de la válvula de gas, resultando en robos de combustible o sobrellenados peligrosos.

Al elegir el diseño de **TCP/IP Offloading (Pila Externa)**, has creado un "Air-Gap" funcional. El STM32 es el rey de la física de fluidos; dedica sus 96KB de RAM exclusivamente al Gas LP, la seguridad del hardware y la arquitectura Dual-Bank FOTA. Si la red celular colapsa o el LwIP del Módem se cuelga por un error de pila, el STM32 no se ve afectado en lo más mínimo, garantizando que el usuario en la estación de servicio pueda seguir cargando gas con total seguridad. Esa es la definición de un diseño "Mission-Critical".

📝 Resumen del Día