DÍA 014 DE 365

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

📖 Teoría Explícita: La Prohibición de `string.h` y el Peligro de `strcpy`

1. El Costo de Inclusión

Cada vez que escribes #include <string.h>, introduces una dependencia externa a tu código. El compilador enlazará bibliotecas genéricas diseñadas para computadoras de escritorio. En un microcontrolador que busca determinismo y tiempos de respuesta ultra-bajos, cada ciclo de reloj cuenta. Las funciones estándar a menudo no están optimizadas para la arquitectura específica (ej. Cortex-M) a menos que uses compiladores propietarios muy costosos.

2. Buffer Overflow: El Asesino Silencioso

La clásica función strcpy(destino, origen) es el vector de vulnerabilidad número uno en la historia de la programación en C. Funciona así: copia bytes de la dirección "origen" a la dirección "destino" hasta que encuentra un '\0'. ¿Qué pasa si el búfer de destino tiene espacio para 10 caracteres, pero la palabra de origen tiene 20? strcpy no pregunta. Simplemente sobrescribirá los 10 bytes siguientes en tu RAM, destruyendo las variables metrológicas o el estado de tus válvulas de gas.

3. La Solución MISRA C: Límites Estrictos

En lugar de strcpy, la industria exige funciones delimitadas (bounded functions). Nosotros escribiremos Copiar_Cadena_Segura. Esta función recibe un tercer parámetro vital: el tamaño máximo del búfer de destino. Si la copia alcanza este límite, se detiene forzosamente y cierra la cadena con un '\0', salvando a tu hardware del desastre.

PREVENCIÓN DE BUFFER OVERFLOW: strcpy VS custom_strncpy origen[8] 'E' 'R' 'R' 'O' 'R' '\0' destino_seguro[4] Metrología! volumen 'E' 'R' 'R' '\0' El custom_strncpy inyecta '\0' en el índice [3] forzosamente. Un strcpy normal habría destruido la variable 'volumen'.

⚙️ Ejercicios Prácticos: Escribiendo tu `custom_strncpy`

Ejercicio 1: Copiado Defensivo. En lugar de confiar en librerías mágicas, utilizaremos aritmética de punteros y validaciones explícitas para mover bytes del arreglo de origen al arreglo destino, exigiendo siempre el parámetro del límite de memoria disponible.


#include <stdint.h>

/**
 * @brief  Copia una cadena de texto de forma 100% segura y Bare-Metal.
 * @param  destino    Puntero al arreglo RAM donde se pegará el texto.
 * @param  origen     Puntero a la constante de texto a copiar.
 * @param  limite_max El tamaño TOTAL del búfer destino.
 * @return La cantidad de bytes copiados (útil para mover el cursor).
 */
uint16_t Copiar_Cadena_Segura(char *destino, const char *origen, uint16_t limite_max) {
    uint16_t i = 0;
    
    // 1. VALIDACIÓN CONTRA HARD FAULTS
    // Si algún puntero es NULL (0x00) o el límite es 0, abortamos.
    if (destino == 0x00 || origen == 0x00 || limite_max == 0) {
        return 0;
    }

    // 2. EL BUCLE DE COPIA DEFENSIVO
    // Avanzamos byte por byte MIENTRAS:
    // a) No hayamos encontrado el terminador nulo del origen.
    // b) No hayamos alcanzado nuestro límite físico (dejando 1 byte para el \0 final).
    while (origen[i] != '\0' && i < (limite_max - 1)) {
        destino[i] = origen[i];
        i++;
    }
    
    // 3. LA RED DE SEGURIDAD
    // Importante: No importa si el origen era más largo que el destino.
    // Nosotros forzosamente cerramos la puerta con un nulo para evitar 
    // lecturas fuera de rango en la UART o el Display.
    destino[i] = '\0';
    
    // Retornamos cuántos bytes realmente escribimos (sin contar el nulo)
    return i; 
}

// =====================================================================
// APLICACIÓN EN EL DESPACHADOR LP
// =====================================================================
// Búfer global protegido para ensamblar alertas para la pantalla
char buffer_alertas[16]; 

void Notificar_Estado_Sistema(uint8_t codigo_error) {
    
    // En lugar de sprintf o strcpy, usamos nuestra función blindada.
    // Le pasamos el tamaño exacto usando 'sizeof'.
    if (codigo_error == 1) {
        Copiar_Cadena_Segura(buffer_alertas, "FUGA DETECTADA", sizeof(buffer_alertas));
    } else {
        Copiar_Cadena_Segura(buffer_alertas, "SISTEMA OK", sizeof(buffer_alertas));
    }
    
    // Aquí el 'buffer_alertas' está listo para enviarse al ESP32 por UART
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Hito Logrado: Erradicación de la librería estándar de C y protección contra vulnerabilidades de Buffer Overflow.

Al reescribir esta función desde cero, te acabas de graduar del nivel "Programador" al nivel "Arquitecto de Silicio". Ya no eres rehén del código que alguien más escribió en la librería <string.h>. Ahora sabes exactamente cuántos ciclos de reloj toma copiar un texto y, sobre todo, garantizas que una falla mecánica (que genere un texto malformado desde el ESP32) jamás pueda corromper el cálculo metrológico del volumen del gas, porque tu función tiene un techo de cristal irrompible: limite_max.

📝 Resumen del Día