DÍA 262 DE 365

Fase 5: Diseño Industrial y Proyecto Final

📖 Teoría a Estudiar

El Concepto Dual Bank (Banco Dual)

En procesadores avanzados, existen dos particiones idénticas de Flash (Bank 1 y Bank 2). Puedes decirle al hardware que invierta los bancos y arranque desde el otro con un solo comando. El STM32F401RE no tiene Hardware Dual Bank, pero simulamos una Arquitectura Híbrida Activa/Pasiva utilizando la Tarjeta SD (Día 260) o la memoria Flash externa del ESP32 como nuestro "Banco Pasivo de Respaldo".

El flujo inquebrantable de una instalación segura es el siguiente:

  1. El Respaldo (Backup): Antes de que el Bootloader borre la Aplicación Activa (Sector 4), la copia entera hacia un archivo en la SD llamado firmware_old.bin.
  2. La Instalación: El Bootloader inyecta el firmware_new.bin en el Sector 4.
  3. La Cuarentena (Testing): El Bootloader graba en la EEPROM una bandera: FOTA_ESTADO = TESTING, y cede el control a la nueva aplicación.
  4. La Validación (Self-Test): La nueva aplicación arranca, verifica que el sensor de presión responde y que logró conectarse a AWS. Si todo está perfecto, ella misma sobrescribe la EEPROM a FOTA_ESTADO = VALIDATED.

El Watchdog: El Verdugo Incorruptible

¿Qué obliga a la nueva aplicación a validarse? El Independent Watchdog (IWDG). Lo configuraremos para morder (Resetear el CPU) a los 30 segundos. Si la nueva aplicación tiene un bug y se congela antes de marcar la EEPROM como VALIDATED, el Watchdog reiniciará el hardware. El Bootloader despertará, verá TESTING en la EEPROM, sabrá que la nueva App fracasó y copiará el firmware_old.bin de regreso, salvando la máquina.

MÁQUINA DE ESTADOS FOTA: SELF-TEST Y ZERO-BRICK ROLLBACK VALIDATED Operación Normal Nuevo .bin descargado PENDING_INSTALL Reinicio al Bootloader 1. Backup a SD 2. Flash Nuevo .bin TESTING Boot de Nueva App ÉXITO (SELF-TEST OK) App se conecta a AWS y cambia su propio flag a VALIDATED FALLO (BRICK / PANIC) App entra en bucle infinito o falla Self-Test. Watchdog a 30s RESET DE HARDWARE! ROLLBACK_REQ Bootloader despierta RESTAURACIÓN Flash de backup.bin Estado -> VALIDATED

⚙️ Ejercicios Prácticos

El Árbitro Imparcial (Watchdog): Cuando activas el Independent Watchdog (IWDG), se ejecuta en un oscilador de silicio totalmente separado (LSI - Low Speed Internal a 32kHz). Es imposible detenerlo por software una vez encendido. Si el RTOS no ejecuta la función HAL_IWDG_Refresh() (también conocida como "Patear al perro") antes de que expire el contador, el hardware jala la línea de RESET físicamente.

Ejercicio 1: Lógica de Autoconservación. Escribiremos dos fragmentos de código complementarios. Primero, la máquina de decisiones que va dentro del Bootloader. Segundo, la rutina de Validación (*Self-Test*) que se ejecuta en el RTOS de la nueva Aplicación.


/**
 * @file fota_state_machine.c
 * @brief Orquestador Dual Bank Activo/Pasivo con soporte Anti-Brick (MISRA-C)
 */

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

// =========================================================================
// DEFINICIONES DE ESTADOS EN EEPROM
// =========================================================================
#define FOTA_STATE_VALIDATED    (0x01U)
#define FOTA_STATE_PENDING      (0x02U)
#define FOTA_STATE_TESTING      (0x03U)

// Variables y APIs externas (De Días anteriores)
extern uint8_t EEPROM_Leer_Estado_FOTA(void);
extern void EEPROM_Escribir_Estado_FOTA(uint8_t estado);
extern bool IAP_Copiar_Archivo_SD_a_Flash(const char* filename);
extern void Bootloader_Jump_To_Application(void);

// =========================================================================
// PARTE A: EJECUTADO EXCLUSIVAMENTE POR EL BOOTLOADER
// =========================================================================
void Bootloader_Gestor_DualBank(void) {
    
    uint8_t estado_fota = EEPROM_Leer_Estado_FOTA();
    
    switch (estado_fota) {
        
        case FOTA_STATE_VALIDATED:
            // Todo está perfecto. Arracar la aplicación activa normal.
            Bootloader_Jump_To_Application();
            break;
            
        case FOTA_STATE_PENDING:
            // Hay una actualización lista en la SD descargada por la App antigua.
            
            // 1. Respaldar la versión que funciona actualmente.
            // IAP_Respaldar_Flash_a_SD("firmware_backup.bin");
            
            // 2. Quemar el nuevo archivo en la Flash Activa.
            if (IAP_Copiar_Archivo_SD_a_Flash("firmware_new.bin")) {
                // 3. Entramos en Cuarentena
                EEPROM_Escribir_Estado_FOTA(FOTA_STATE_TESTING);
                NVIC_SystemReset(); // Reinicio físico para bootear en Testing
            } else {
                // El flasheo falló (Ej. SD corrupta). Abortar y volver a estado Validado.
                EEPROM_Escribir_Estado_FOTA(FOTA_STATE_VALIDATED);
                Bootloader_Jump_To_Application();
            }
            break;
            
        case FOTA_STATE_TESTING:
            // ¡ALARMA ROJA! 
            // Si el Bootloader despierta y ve este estado, significa que la App
            // arrancó pero NO PUDO validarse a sí misma. Murió por Watchdog o HardFault.
            
            // 1. Ejecutar ROLLBACK Inmediato
            // IAP_Copiar_Archivo_SD_a_Flash("firmware_backup.bin");
            
            // 2. Restaurar estado de paz
            EEPROM_Escribir_Estado_FOTA(FOTA_STATE_VALIDATED);
            
            // 3. Notificar a la nube del fallo (Opcional, mediante log en SD)
            // FatFs_Escribir_Log("Rollback ejecutado por Falla Crítica en Self-Test");
            
            Bootloader_Jump_To_Application();
            break;
            
        default:
            // Estado de fábrica o EEPROM virgen
            Bootloader_Jump_To_Application();
            break;
    }
}

// =========================================================================
// PARTE B: EJECUTADO EXCLUSIVAMENTE POR LA APLICACIÓN (NUEVA)
// =========================================================================
/**
 * @brief Rutina Self-Test que corre dentro del RTOS de la nueva aplicación
 *        durante los primeros 30 segundos de vida.
 */
void Task_App_Validation_SelfTest(void *argument) {
    
    // Asumimos que el Hardware IWDG está configurado a 30 segundos.
    
    // 1. Verificación de Sensores Base
    bool sensores_ok = Metrologia_Autodiagnostico_PT100();
    bool memoria_ok = EEPROM_I2C_Test();
    
    // 2. Verificación de Conectividad Cloud
    bool nube_ok = AWS_IoT_Probar_Conexion_MQTT();
    
    if (sensores_ok && memoria_ok && nube_ok) {
        
        // ¡LA APLICACIÓN ESTÁ SANA Y OPERATIVA!
        // Leemos si estábamos en cuarentena
        if (EEPROM_Leer_Estado_FOTA() == FOTA_STATE_TESTING) {
            
            // EL MOMENTO DE LA VERDAD: Escribimos Validado.
            // A partir de esta línea de código, la actualización es permanente.
            EEPROM_Escribir_Estado_FOTA(FOTA_STATE_VALIDATED);
            
            // LCD_Mostrar("ACTUALIZACIÓN EXITOSA");
        }
    } else {
        // Falló el Self-Test (Ej. el nuevo código rompió la rutina SPI del Módem).
        // Acción: No hacemos NADA. No pateamos al perro guardián.
        // En unos segundos, el IWDG reiniciará la placa y el Bootloader nos ejecutará el Rollback.
        
        while(1) {
            // Esperando la muerte redentora del Watchdog...
        }
    }
    
    for(;;) {
        // Ciclo normal de vida de la tarea (Patear Watchdog regular)
        // HAL_IWDG_Refresh(&hiwdg);
        osDelay(pdMS_TO_TICKS(1000U));
    }
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: SRE (Site Reliability Engineering) en el Borde y Actualizaciones Inmutables.

En el software web tradicional, si despliegas una mala actualización, el servidor se cae, el usuario ve un Error 500, le das "Revertir" en AWS y cinco minutos después todo vuelve a la normalidad. En el hardware industrial, si despliegas una mala actualización y el procesador pierde la capacidad de hablar por internet, has creado una **Flota de Ladrillos Silenciosos** (A Silent Brick Fleet). Tendrías que enviar humanos en camionetas por todo el continente para conectarse con cables a cada máquina.

Al fusionar la tenacidad del Independent Watchdog de silicio con la Máquina de Estados de FOTA (Testing/Validated), has construido un sistema que se auto-audita. Le has dado a tu Despachador de Gas LP el poder de decir: *"Mi nuevo cerebro no sabe leer la presión del tanque; me niego a operar bajo esta condición, suicidaré mi ejecución actual y regresaré al cerebro de ayer"*. Esta resiliencia absoluta es la que permite a gigantes como Tesla o SpaceX actualizar vehículos críticos sin miedo. Tu hardware ahora se repara a sí mismo.

📝 Resumen del Día