DÍA 253 DE 365

Fase 5: Diseño Industrial y Proyecto Final

📖 Teoría a Estudiar

El Fenómeno Brown-out

Un Black-out es la ausencia total de energía (0 Voltios). Un Brown-out (Caída de tensión) es un evento transitorio donde la fuente de alimentación no puede sostener la demanda de corriente de la máquina, provocando que el voltaje caiga por debajo de las especificaciones del fabricante pero sin llegar a apagarse por completo.

El STM32F401 está certificado para operar entre 1.7V y 3.6V. Sin embargo, para operar el bus I2C (que guarda las ventas en la EEPROM externa) y el Flash interno a máxima velocidad, necesitas un mínimo estricto de 2.7 Voltios. Si el voltaje oscila en la Death Zone (ej. 2.4V), la CPU puede interpretar que sumar `100 + 50` da `8`, o peor: saltar a la rutina de formateo de memoria accidentalmente.

El Supervisor de Voltaje (BOR Interno y Hardware Externo)

Para prevenir esto, el silicio incorpora un circuito analógico totalmente aislado de la CPU lógica: El BOR (Brown-Out Reset). Su única misión es medir la tensión de entrada VDD. Si detecta que cae por debajo del Threshold (Umbral) programado, tira inmediatamente de la línea interna de RESET, congelando todos los transistores.

El BOR cuenta con un mecanismo de Histéresis. Esto significa que si se apaga a los 2.8V, no volverá a encender el procesador si el voltaje sube a 2.81V (lo que causaría reinicios infinitos). Esperará a que el voltaje "sane" y supere los 2.9V para liberarlo del coma.

FENÓMENO BROWN-OUT E HISTÉRESIS DE REINICIO (BOD/BOR) VDD Tiempo 3.3V 2.9V 2.8V 2.0V DEATH ZONE: CPU Inestable, RAM/EEPROM Corrupta BOR Rising (Recovery) BOR Falling (Trip) Falla de Red AC Intento de Arranque (Fluctuación) Sube 2.8V, ¡Pero la histéresis exige 2.9V! CPU RUN RESET Ejecutando RTOS COMA INDUCIDO (Protege RAM/Flash) Secuencia BOOT Analiza Desastre (Día 252)

⚙️ Ejercicios Prácticos

Configuración de Hardware: Option Bytes. En los microcontroladores de STMicroelectronics, la configuración del BOR no reside en la RAM volátil ni en un registro normal que se pierda al apagar el chip. Reside en la memoria acorazada de los Option Bytes (OB). El STM32 lee estos bytes a nivel físico en los primeros nanosegundos antes de encender el núcleo lógico (Cortex-M4).

Por defecto de fábrica, el BOR viene apagado (Nivel 0) o muy bajo (Nivel 1: ~2.0V) para ahorrar energía en relojes de pulsera o juguetes a batería. Nosotros desarrollaremos una Rutina de Autocuración (Self-Healing Hardware). El firmware de nuestro Despachador, al arrancar, auditará sus propios Option Bytes. Si detecta que no está en el máximo Nivel de Seguridad (BOR Level 3: ~2.8V a 2.9V), reprogramará físicamente su propio silicio y se reiniciará inmediatamente para aplicar el blindaje.

Ejercicio 1: Autopsia del Reinicio y Autocuración del Silicio (MISRA-C).


/**
 * @file hardware_watchdog_bor.c
 * @brief Gestión del Registro de Control de Reset (RCC_CSR) y Option Bytes BOR
 */

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

// =========================================================================
// 1. AUTOPSIA DEL REINICIO (Saber qué nos mató la última vez)
// =========================================================================
typedef enum {
    RESET_SOURCE_UNKNOWN    = 0U,
    RESET_SOURCE_POWER_ON   = 1U, // Conexión inicial de la batería/fuente
    RESET_SOURCE_BROWN_OUT  = 2U, // ¡Caída de tensión! (BOD Actuó)
    RESET_SOURCE_WATCHDOG   = 3U, // El RTOS se congeló y el perro guardián actuó
    RESET_SOURCE_PIN        = 4U  // Alguien presionó el botón físico de RESET
} ResetSource_t;

/**
 * @brief  Analiza el registro físico del reloj para deducir la causa del último reinicio.
 * @retval El origen clasificado de la muerte térmica o lógica anterior.
 */
ResetSource_t Analizar_Causa_Muerte(void) {
    
    ResetSource_t causa = RESET_SOURCE_UNKNOWN;
    
    // Leemos el Control/Status Register del RCC (Reset and Clock Control)
    uint32_t csr_flags = RCC->CSR;

    // Evaluamos de mayor prioridad de fallo a menor
    if ((csr_flags & RCC_CSR_BORRSTF) != 0U) {
        causa = RESET_SOURCE_BROWN_OUT;
    }
    else if ((csr_flags & RCC_CSR_IWDGRSTF) != 0U) {
        causa = RESET_SOURCE_WATCHDOG;
    }
    else if ((csr_flags & RCC_CSR_PORRSTF) != 0U) {
        causa = RESET_SOURCE_POWER_ON;
    }
    else if ((csr_flags & RCC_CSR_PINRSTF) != 0U) {
        causa = RESET_SOURCE_PIN;
    }
    
    // MISRA-C / Hardware Manual: Es obligatorio limpiar los flags de reset después de leerlos
    // para que no ensucien la autopsia del próximo apagón.
    RCC->CSR |= RCC_CSR_RMVF;
    
    return causa;
}

// =========================================================================
// 2. RUTINA DE AUTOCURACIÓN DE OPTION BYTES (SIL-3 HARDEN)
// =========================================================================
/**
 * @brief Asegura permanentemente que el hardware apague la CPU si el voltaje 
 *        cae por debajo de los 2.7V (BOR Level 3) necesarios para la memoria Flash.
 */
void Asegurar_Blindaje_BrownOut(void) {
    
    FLASH_OBProgramInitTypeDef OptionBytesConfig;
    
    // 1. Extraer la configuración actual inyectada en el silicio
    HAL_FLASHEx_OBGetConfig(&OptionBytesConfig);
    
    // 2. Verificar si somos vulnerables
    if (OptionBytesConfig.BORLevel != OB_BOR_LEVEL3) {
        
        // El hardware está desprotegido. Inicia proceso de modificación profunda.
        // ADVERTENCIA: Esta operación de la API de HAL es sumamente delicada.
        
        HAL_FLASH_Unlock();      // Quita el seguro a la memoria Flash
        HAL_FLASH_OB_Unlock();   // Quita el seguro a los Option Bytes
        
        // Configuramos la estructura deseada
        OptionBytesConfig.OptionType = OPTIONBYTE_BOR;
        OptionBytesConfig.BORLevel   = OB_BOR_LEVEL3; // Umbral estricto ~2.7V a 2.9V
        
        // Quema permanentemente la configuración en el chip
        if (HAL_FLASHEx_OBProgram(&OptionBytesConfig) == HAL_OK) {
            
            // Lanza la aplicación física de los Option Bytes.
            // Esta función genera internamente un System Reset obligatorio por Hardware.
            // El microcontrolador "morirá" aquí y renacerá ya blindado.
            HAL_FLASH_OB_Launch();
        }
        
        // En caso de que el Program fallara, bloqueamos de nuevo
        HAL_FLASH_OB_Lock();
        HAL_FLASH_Lock();
        
        // Disparar Alarma de Hardware_Corrupto
    }
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Hardware Self-Healing (Autocuración) y Prevención de Corrupción de Estado Sólido.

En el mundo real del mantenimiento industrial, tu placa (Mainboard) diseñada en KiCad será reemplazada eventualmente. Un técnico de servicio en otra ciudad comprará un procesador STM32F401 virgen, le cargará tu código fuente `.bin` mediante un cable USB y reemplazará la tarjeta quemada en el Despachador de Gas LP.

Ese técnico no sabe qué son los "Option Bytes", ni usará el software de ST para habilitar el Brown-Out Reset manualmente. Si no programas una autodefensa, esa nueva máquina estará desprotegida contra apagones y perderá la metrología en la primera tormenta eléctrica.

Al implementar la rutina de **Autocuración del BOR en el Firmware**, tu código se comporta como un organismo vivo. Al encenderse, el firmware inspecciona las defensas pasivas del silicio que lo hospeda. Si las defensas están caídas, el propio firmware abre las compuertas de la memoria Flash, sobreescribe las leyes fundamentales del procesador (OB_BOR_LEVEL3) y se reinicia a sí mismo para que los cambios surtan efecto. El técnico instalador ni siquiera se dará cuenta de lo que pasó, pero tú habrás garantizado a nivel de Director de Ingeniería que ninguna placa que corra tu código perecerá jamás por un coma eléctrico inducido.

📝 Resumen del Día