El mundo de los hidrocarburos no trata a todos los metros cuadrados por igual. Las normas (NEC 500 en América, ATEX en Europa) dividen el espacio físico en Zonas (o Divisiones):
¿Cómo metes electrónica a la Zona 1 o Zona 0 sin volar la estación? Tienes dos caminos:
1. A prueba de explosión (Ex d): Asumes que el gas entrará a tu gabinete y que tu relé generará una chispa. El gas explotará adentro. Pero construyes un gabinete de aluminio o hierro fundido de 1 pulgada de grosor que contiene la explosión y no deja salir el fuego. Es pesado, costoso y requiere tornillos especiales.
2. Seguridad Intrínseca (Ex i): Asumes que el gas está presente, pero diseñas la electrónica para que la energía disponible (voltaje y corriente máxima) sea tan baja que es físicamente imposible que genere una chispa lo suficientemente caliente para encender el gas. Para lograr esto, se instalan Barreras Zener entre tu STM32 y el sensor que va a la zona peligrosa.
Paso 1: Componentes "UL Listed".
No puedes soldar una barrera Zener armada por ti mismo y pasar la certificación. Debes comprar Barreras de Seguridad Intrínseca ya certificadas (ej. marca Pepperl+Fuchs o MTL) e instalarlas en el riel DIN de tu gabinete. Todo el cableado de Zona Segura debe ser gris o negro, y todo el cableado que sale de las barreras hacia la Zona Explosiva debe ser de color AZUL CLARO (Estándar global para circuitos Ex i).
Paso 2: Distancias de Fuga (Creepage & Clearance).
En tu PCB, las pistas de 110V AC no pueden estar a 1 milímetro de las pistas de 3.3V del STM32. Las agencias certificadoras exigen distancias físicas mínimas. El Clearance es la distancia a través del aire; el Creepage es la distancia a través de la superficie de la PCB. A menudo, el Arquitecto debe pedir a la fábrica de PCBs que rasure canales vacíos (slots) en la placa para aumentar la distancia dieléctrica.
En el software comercial estándar, si un rayo cósmico voltea un bit en la RAM (Bit Flip) cambiando la variable valve_open de 0 a 1, la válvula se abre y tira gas. Para certificaciones industriales (como IEC 61508 / SIL), una variable crítica NUNCA debe existir sola. Se debe declarar una variable redundante invertida lógicamente.
/**
* @file safety_sil_redundancy.c
* @brief Implementación de Redundancia de Memoria para Variables Críticas (ATEX/SIL Prep)
*/
#include "stm32f4xx_hal.h"
#include <stdbool.h>
#include <stdio.h>
extern void System_Enter_Lockdown(const char* reason_code);
// =========================================================================
// VARIABLES CRÍTICAS REDUNDANTES
// =========================================================================
// En lugar de una sola bandera, usamos dos. La segunda almacena el
// complemento a uno bit a bit (Bitwise NOT).
volatile uint32_t secure_valve_state = 0x00000000; // Estado real
volatile uint32_t secure_valve_state_inv = 0xFFFFFFFF; // Estado invertido obligatorio
// Macro de verificación de integridad
#define CHECK_VAR_INTEGRITY(var, inv_var) ((var) == ~(inv_var))
// =========================================================================
// RUTINA DE ACTUACIÓN SEGURA
// =========================================================================
/**
* @brief Cambia el estado de la electroválvula asegurando la integridad de RAM.
* @param open_valve: true para despachar, false para cortar.
*/
void SIL_Safe_Valve_Control(bool open_valve) {
// 1. Validar la integridad de la memoria ANTES de hacer un cambio
if (!CHECK_VAR_INTEGRITY(secure_valve_state, secure_valve_state_inv)) {
// Un rayo electromagnético o EMI corrompió la RAM. La variable original
// no coincide con su imagen invertida.
printf("[CRIT] SIL ERROR: Corrupción de RAM en variable crítica.\r\n");
// Forzamos hardware a modo seguro inmediatamente
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
System_Enter_Lockdown("E-100_RAM_CORRUPTION");
return;
}
// 2. Ejecutar la acción
if (open_valve) {
secure_valve_state = 0x5A5A5A5A; // Patrón de "Abierto" en lugar de simple '1'
secure_valve_state_inv = ~0x5A5A5A5A;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
} else {
secure_valve_state = 0x00000000;
secure_valve_state_inv = 0xFFFFFFFF;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}
}
// =========================================================================
// TAREA DE VIGILANCIA EN BACKGROUND (Safety Task)
// =========================================================================
/**
* @brief Se ejecuta constantemente en el bucle principal o tarea FreeRTOS.
* Vigila si los punteros a funciones o variables clave fueron corrompidos.
*/
void SIL_Background_Audit_Task(void) {
if (!CHECK_VAR_INTEGRITY(secure_valve_state, secure_valve_state_inv)) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); // Failsafe
System_Enter_Lockdown("E-100_RAM_CORRUPTION");
}
// Aquí también se revisan los Stack Pointers y el PC (Program Counter)
// para asegurar que el procesador no saltó a memoria basura.
}
Objetivo del día: Compliance Internacional y Robustez de Software Safety-Critical.
Construir un producto que la ley te permita exportar requiere pensar más allá de la simple funcionalidad. Si tu Despachador va a operar en el frío de Canadá bajo la norma CSA, o en puertos europeos bajo la directiva ATEX, debes demostrarle a un auditor externo que es matemáticamente imposible que tu máquina explote, incluso si todos sus componentes fallan al mismo tiempo.
Hoy cruzaste la frontera del software de propósito general hacia el **Software de Misión Crítica**. Al programar variables redundantes invertidas en C (`secure_valve_state_inv`), proteges tu máquina contra los "Bit Flips" causados por radiación ionizante (rayos cósmicos) o ruido eléctrico masivo (EMI) que logren evadir la barrera de tu gabinete. Combinando este firmware paranoico con **Barreras Zener de Seguridad Intrínseca** para los sensores del exterior, has diseñado una máquina que encapsula la energía peligrosa en la caja y garantiza que la zona donde interactúa el ser humano está eléctricamente castrada para evitar igniciones. Has elevado tu proyecto de una Tesis local a un producto de Categoría Mundial.