DÍA 044 DE 365

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

📖 Teoría a Estudiar: Doble Buffer (Ping-Pong)

En el desarrollo en C puro (bare-metal) sin sistemas operativos de tiempo real, la recepción asíncrona de datos es uno de los mayores desafíos. Si recibes una ráfaga de datos por UART y tu procesador tarda en procesarlos, los nuevos bytes sobrescribirán a los viejos, perdiendo información crítica. La solución es el Buffer Ping-Pong.

¿Cómo funciona la arquitectura Ping-Pong?

En lugar de tener un solo arreglo de memoria, creamos dos. Mientras el hardware (por interrupción o DMA) escribe datos nuevos en el Buffer Ping de forma invisible en segundo plano, la CPU tiene total libertad y tiempo para analizar, procesar y despachar los datos que ya están completos en el Buffer Pong. Cuando el Ping se llena, los roles se intercambian instantáneamente mediante punteros de memoria, sin mover un solo byte físicamente.

ARQUITECTURA PING-PONG (C PURO) UART Rx (ISR) CPU (Main) Buffer A [Ping] Buffer B [Pong] Escribiendo Procesando SWAP DE PUNTEROS (O(1)) temp = ptr_rx; ptr_rx = ptr_main; ptr_main = temp;

⚙️ Ejercicios Prácticos

Ejercicio: Implementa en C una estructura de doble buffer utilizando manipulación de punteros. El objetivo es evitar funciones pesadas que bloqueen la CPU y no usar bucles de copia de datos, gestionando el intercambio de buffers con el costo computacional mínimo.


#include <stdint.h>
#include <stdbool.h>

#define BUFFER_SIZE 64

// 1. Asignación estática de la memoria (evita fragmentación y uso de malloc)
uint8_t buffer_A[BUFFER_SIZE];
uint8_t buffer_B[BUFFER_SIZE];

// 2. Punteros maestros de control
uint8_t* ptr_rx = buffer_A;     // Hardware (UART/ISR) escribe aquí
uint8_t* ptr_procesamiento = buffer_B; // Súper bucle lee de aquí

volatile bool datos_listos = false;

// --- SIMULACIÓN: Rutina de Servicio de Interrupción (ISR) de UART ---
void UART_Rx_ISR(uint8_t byte_recibido) {
    static uint8_t indice = 0;
    
    // Almacenamos el byte directamente por puntero
    ptr_rx[indice] = byte_recibido;
    indice++;
    
    // Si el buffer de recepción se llenó o se detecta fin de trama
    if (indice >= BUFFER_SIZE || byte_recibido == '\n') {
        indice = 0;
        datos_listos = true; // Levantamos la bandera para el Súper Bucle
    }
}

// --- SÚPER BUCLE ---
int main(void) {
    while(1) {
        // Ejecución no bloqueante
        if (datos_listos) {
            
            // 3. SWAP (INTERCAMBIO) DE PUNTEROS
            // Tomamos una sección crítica ultra-corta
            // No copiamos arreglos, solo intercambiamos direcciones de memoria (costo CPU: casi 0)
            uint8_t* ptr_temp = ptr_rx;
            ptr_rx = ptr_procesamiento;
            ptr_procesamiento = ptr_temp;
            
            datos_listos = false;
            
            // 4. Procesamiento
            // Ahora CPU puede parsear 'ptr_procesamiento' con calma
            // Mientras tanto, la próxima interrupción UART ya escribirá en el nuevo 'ptr_rx'
            // procesar_trama_sin_sprintf(ptr_procesamiento);
        }
        
        // El resto del código de control industrial sigue corriendo sin congelarse
    }
    return 0;
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Aplicación del día: Recepción estable del MOBAGAS Módulo Wi-Fi v.01.

Al diseñar la comunicación UART entre la unidad CPU principal (Kinetis/STM32) y tu módulo MOBAGAS Wi-Fi, habrás notado que enviar múltiples registros de eventos o servicios a la EEPROM puede provocar congelamientos si la transmisión es continua. El procesador interrumpe la lectura de las electroválvulas para escuchar a la red, lo que es inaceptable en un equipo industrial de gas LP.

Al implementar el sistema Ping-Pong en el firmware, la UART depositará los bytes del módulo Wi-Fi (como comandos de inicio de ruta) en el buffer activo. El control de las válvulas de gas sigue ejecutándose en su ciclo. Solo cuando la trama Wi-Fi completa se recibe en el Ping, los punteros se intercambian. El Despachador ahora procesa el comando en el Pong, mientras el módulo Wi-Fi es libre de empezar a transmitir la siguiente trama sin provocar ningún cuelgue de CPU.

📝 Resumen del Día

❓ Cuestionario de Autoevaluación

1. ¿Qué sucedería si usaras un solo buffer en un sistema sin bloqueos mientras recibes una trama de datos muy larga?
Respuesta: Se generaría una condición de carrera o sobrescritura de datos. El procesador intentaría leer y parsear la información del buffer al mismo tiempo que la interrupción de hardware inyecta nuevos bytes. El resultado serían cadenas de caracteres corruptas o datos fragmentados en tu sistema.

2. ¿Por qué el intercambio (swap) de punteros se considera una operación $O(1)$?
Respuesta: Porque el tiempo que tarda la CPU en ejecutar el intercambio es constante, independientemente del tamaño del buffer. Ya sea que el buffer tenga 64 bytes o 2048 bytes, intercambiar punteros solo requiere cambiar el valor de 3 variables en la memoria RAM, a diferencia de una función de copiado que tardaría más entre más grande fuera el arreglo.