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:
firmware_old.bin.firmware_new.bin en el Sector 4.FOTA_ESTADO = TESTING, y cede el control a la nueva aplicación.FOTA_ESTADO = VALIDATED.¿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.
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));
}
}
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.
VALIDATED.TESTING. Esto desencadena el protocolo de Rollback Automático, que reescribe la Flash con la versión de seguridad, devolviendo la máquina a un estado 100% operativo sin intervención humana.