En el código de metrología del Día 236 dividíamos los pulsos entre un factor fijo (400.0F). Eso sirve para prototipos. En la industria, el desgaste mecánico de los rodamientos de la turbina o la densidad del lote específico de Gas LP alteran los pulsos generados por litro. El K-Factor (Factor de Calibración) es un número flotante que se guarda en la memoria no volátil (EEPROM) y se actualiza anualmente tras un proceso de calibración con un recipiente probador certificado (Serafín).
Fórmula Metrológica Base: Volumen_Crudo = Pulsos_Hardware / K_Factor_EEPROM
La OIML exige que sea imposible alterar el parámetro de calibración de un dispensador en operación comercial. Para que el técnico pueda cambiar el K-Factor a, digamos, 398.25, debe ocurrir una secuencia auditable:
MODO_CALIBRACION. El STM32 desbloquea la escritura del sector de EEPROM que contiene el K-Factor.Esta hibridación donde el Software no confía en sí mismo, sino en un estado de Hardware verificado, es la base de las certificaciones antifraude.
El Almacenamiento en EEPROM (Casting de Floats): En MISRA-C, guardar variables de tipo float en bruto dentro de una memoria (Byte a Byte) se considera riesgoso debido a la "Representación de Punto Flotante IEEE-754", la cual puede variar entre arquitecturas o corromperse con un solo Bit-Flip y generar un número "NaN" (Not a Number) o infinito. La práctica industrial es multiplicar el factor por 1,000 y guardarlo como un entero (uint32_t). Ej: 398.25 se guarda como el entero 398250. Al arrancar, el STM32 lo extrae y lo divide entre 1000.0F.
Ejercicio 1: El Gestor de Permisos de Metrología (Hardware Interlock). Escribiremos la función de configuración del K-Factor. Debe comprobar estrictamente el Pin Físico e incluir una validación de límites (Bounds Checking) para evitar que un operario digite un factor de 0.0 y provoque un error de "División por Cero" en el RTOS.
/**
* @file metrologia_oiml.c
* @brief Gestión del Factor de Calibración con Sello de Hardware (MISRA-C / OIML R117)
*/
#include "stm32f401xe.h"
#include <stdint.h>
#include <stdbool.h>
// =========================================================================
// DEFINICIONES DE HARDWARE Y METROLOGÍA
// =========================================================================
#define PORT_CALIBRACION GPIOB
#define PIN_JUMPER_METROLOGICO GPIO_PIN_12
// Límites físicos tolerables de la turbina (Evita errores de dedo)
#define K_FACTOR_MIN_VALIDO (300000U) // Equivale a 300.000 Pulsos/Litro
#define K_FACTOR_MAX_VALIDO (500000U) // Equivale a 500.000 Pulsos/Litro
// Variable de RAM usada por el RTOS para matemáticas veloces
static float32_t k_factor_operativo_ram = 400.000F; // Valor de fábrica seguro
// Extern API EEPROM (Desarrollada en el Día 252)
extern bool EEPROM_I2C_Leer_KFactor(uint32_t* buffer_int);
extern bool EEPROM_I2C_Escribir_KFactor(uint32_t nuevo_factor_int);
// =========================================================================
// INICIALIZACIÓN (Llamada en el BOOT de la máquina)
// =========================================================================
void Metrologia_Cargar_Parametros_EEPROM(void) {
uint32_t k_factor_eeprom_int = 0U;
if (EEPROM_I2C_Leer_KFactor(&k_factor_eeprom_int)) {
// Bounds checking de seguridad ante corrupción de memoria
if ((k_factor_eeprom_int >= K_FACTOR_MIN_VALIDO) &&
(k_factor_eeprom_int <= K_FACTOR_MAX_VALIDO)) {
// Transformación segura de Entero a Float (Dividimos entre 1000)
k_factor_operativo_ram = (float32_t)k_factor_eeprom_int / 1000.0F;
} else {
// Log_Error("EEPROM K-Factor Corrupto. Usando valor Failsafe.");
}
}
}
// =========================================================================
// FUNCIÓN CRÍTICA DE AJUSTE (Llamada por la Interfaz UART/Teclado/MQTT)
// =========================================================================
/**
* @brief Intenta actualizar el Factor de Calibración de la máquina.
* OIML REQUIREMENT: El hardware debe estar desellado.
* @param nuevo_k_factor_int: Factor ingresado por el inspector (Multiplicado x1000)
* @retval bool: TRUE si se aplicó y guardó. FALSE si el hardware bloqueó el acceso o valor ilógico.
*/
bool Metrologia_Actualizar_KFactor(uint32_t nuevo_k_factor_int) {
// 1. HARDWARE INTERLOCK VERIFICATION
// Configuramos el pin con Pull-Up. Si el jumper no está, lee HIGH (Bloqueado).
// Si el inspector puso el jumper (cerrando circuito a GND), lee LOW (Habilitado).
GPIO_PinState estado_jumper = HAL_GPIO_ReadPin(PORT_CALIBRACION, PIN_JUMPER_METROLOGICO);
if (estado_jumper == GPIO_PIN_SET) { // Alta Impedancia = 3.3V
// ACCESO DENEGADO POR HARDWARE. Sello intacto.
// Auditar_Intento_Violacion_Seguridad();
return false;
}
// 2. BOUNDS CHECKING (Evitar división por cero o calibraciones absurdas)
if ((nuevo_k_factor_int < K_FACTOR_MIN_VALIDO) ||
(nuevo_k_factor_int > K_FACTOR_MAX_VALIDO)) {
return false; // Valor fuera del margen de la turbina
}
// 3. APLICACIÓN DE ESTADO DE FORMA ATÓMICA
// Escribimos a la memoria no volátil
if (EEPROM_I2C_Escribir_KFactor(nuevo_k_factor_int)) {
// Actualizamos la variable RAM que usa el RTOS
// Es necesario detener temporalmente interrupciones para evitar Data Race
// con la Tarea de Metrología si estaba leyendo el float a la mitad.
taskENTER_CRITICAL();
k_factor_operativo_ram = (float32_t)nuevo_k_factor_int / 1000.0F;
taskEXIT_CRITICAL();
// Auditar_Calibracion_Exitosa();
return true;
}
return false; // Falla de I2C/Hardware
}
Objetivo del día: Certificación de Metrología Legal, Cumplimiento Gubernamental y Antifraude (Anti-Tampering).
El mejor diseño electrónico del mundo no tiene ningún valor comercial si no puede pasar una certificación estatal. PROFECO en México, la EPA en Estados Unidos y la OIML a nivel mundial persiguen implacablemente el "Fraude Volumétrico". Un operador malicioso con acceso a internet podría hackear tu interfaz MQTT, cambiar el factor de la turbina para cobrar 100 litros entregando solo 90, y luego regresar el factor a la normalidad antes de que llegue una inspección.
Al implementar un **Interlock Físico/Lógico mediante un GPIO (Sello Metrológico)**, erradicaste permanentemente los vectores de ataque puramente digitales. No importa cuántos servidores se vulneren, el chip STM32 negará rotundamente la reescritura de la memoria EEPROM a menos que detecte un puente físico de cobre a tierra en su pin de calibración. Dado que este pin físico estará resguardado detrás de una placa de acrílico sellada con alambre y plomo del gobierno, cualquier intento de calibración secreta requerirá destruir un sello estatal, lo cual constituye un delito penal rastreable a simple vista. Tu firmware ha convertido la física del hardware en una garantía jurídica auditable.
float) no se almacenan crudos en la memoria secundaria para evitar corrupciones de mantisa. Se escalan a un número entero (ej. multiplicando por 1000) y se validan con Bounds Checking (límites máximos y mínimos absolutos) antes de cualquier conversión para prevenir un pánico lógico como una división por cero.