DÍA 027 DE 365

Fase 1: Fundamentos de C y Lógica de Software

📖 Teoría Explícita: El Modificador `const` y el Linker

1. La Tragedia del Código de Arranque (C Startup)

Cuando un programa en C arranca (antes de llegar al main()), un pequeño script ensamblador copia todas tus variables globales inicializadas desde la Flash a la SRAM. Si declaras char msg[] = "FALLA VALVULA";, este texto existe físicamente en la memoria Flash (porque ahí se graba el firmware), pero el procesador lo copiará byte por byte a la RAM para que puedas usarlo. ¡Acabas de gastar 14 bytes de Flash Y 14 bytes de RAM!

2. `const` y la sección `.rodata`

En el mundo de los microcontroladores ARM Cortex y MC9S08, al usar const char msg[] = "FALLA VALVULA";, ocurre magia a nivel de compilación. El enlazador (Linker) coloca esa variable en una sección de memoria llamada .rodata (Read-Only Data). El procesador sabrá que no debe copiarla a la RAM durante el arranque. Cuando la leas, el núcleo apuntará directamente a la dirección en la memoria Flash. ¡Consumo de SRAM = 0 bytes!

3. Tablas de Configuración (Look-Up Tables)

El gas LP cambia su densidad según la temperatura. Calcular esta curva con coma flotante es letal para el procesador (como vimos en el Día 17). La solución industrial es pre-calcular esta curva en Excel, exportarla como un arreglo gigante de enteros, y guardarla en Flash usando const. Así, la compensación de temperatura se vuelve un simple acceso a un índice de un arreglo (que toma 1 ciclo de reloj).

UBICACIÓN DE MEMORIA: ARRAY VS CONST ARRAY MEMORIA FLASH (ROM) Amplia (ej. 128 KB) MEMORIA SRAM (RAM) Escasa (ej. 16 KB) int array[3] = {1,2,3}; COPIA en .data (Consume RAM) Boot C const int tabla[3] = {1,2,3}; SRAM LIBRE NO SE COPIA Lectura Directa (Bus de Flash)

⚙️ Ejercicios Prácticos: Tablas de Configuración

Ejercicio 1: Construiremos las tablas maestras de nuestro Despachador de Gas LP. Guardaremos los textos del menú y la matriz de compensación de temperatura directamente en la Flash, blindándolas con const.


#include <stdint.h>

// =====================================================================
// 1. MENSAJES DE SISTEMA (.rodata / FLASH)
// =====================================================================
// Al usar un arreglo de punteros a cadenas constantes, garantizamos 
// que ningún texto consumirá memoria RAM. Es ideal para pantallas LCD.
const char* const HMI_MENSAJES_ERROR[] = {
    "SISTEMA OK",         // Índice 0
    "FALLA VALVULA 1",    // Índice 1
    "PRESION EXCESIVA",   // Índice 2
    "FALLA FLUJOMETRO",   // Índice 3
    "CORTE EMERGENCIA"    // Índice 4
};

// =====================================================================
// 2. TABLA DE CALIBRACIÓN (LOOK-UP TABLE)
// =====================================================================
// El Gas LP se expande con el calor. En lugar de procesar una fórmula
// logarítmica con floats, pre-calculamos factores de compensación en PC.
// Un factor de 1000 = Multiplicar por 1.000.
// Asumimos un índice de temperatura de 0 a 10 grados para el ejemplo.

const uint16_t TABLA_COMPENSACION_TEMPERATURA[11] = {
    1015, // 0 °C
    1012, // 1 °C
    1009, // 2 °C
    1006, // 3 °C
    1003, // 4 °C
    1000, // 5 °C (Referencia Ideal)
    997,  // 6 °C
    994,  // 7 °C
    991,  // 8 °C
    988,  // 9 °C
    985   // 10 °C
};

// =====================================================================
// 3. USO EFICIENTE EN EL DESPACHADOR
// =====================================================================
extern void UART_Transmitir_String(const char* txt); // Función que exige puntero constante

uint32_t Compensar_Volumen_Por_Temperatura(uint32_t volumen_medido_ml, uint8_t temperatura_actual_c) {
    
    // Si la temperatura se sale de la tabla, devolvemos el volumen original
    // para evitar un Out-of-Bounds que causaría un Hard Fault leyendo basura en Flash.
    if (temperatura_actual_c > 10) {
        UART_Transmitir_String(HMI_MENSAJES_ERROR[2]); // Avisar "PRESION EXCESIVA" (O Temp)
        return volumen_medido_ml; 
    }
    
    // La lectura de esta tabla toma 1 ciclo de reloj (Load from ROM)
    uint16_t factor = TABLA_COMPENSACION_TEMPERATURA[temperatura_actual_c];
    
    // Matemática pura de punto fijo: Cero floats, Cero latencia (Día 17)
    uint32_t volumen_compensado = (volumen_medido_ml * factor) / 1000;
    
    return volumen_compensado;
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Liberación de Memoria SRAM y Look-Up Tables.

Tu Despachador de Gas industrial necesita ser exacto a cualquier temperatura ambiente. Al implementar Look-Up Tables (Tablas de Búsqueda) blindadas con const, has eliminado por completo la necesidad del hardware de hacer cálculos matemáticos pesados en tiempo real. Ahora, el STM32 o Kinetis simplemente cruza el índice de la temperatura con la memoria Flash, obtiene la respuesta y corrige el volumen inyectado al instante. Toda tu memoria RAM ha quedado liberada y lista para ser usada exclusivamente en cosas que sí cambian: la Base de Datos de Turnos, los búferes del UART y el Búfer Circular del histórico de tickets.

📝 Resumen del Día