Cuando un modulo Bluetooth pierde conexiones en el campo, consume 3 mA por encima de la especificacion en reposo, o falla la certificacion en el segundo canal del barrido DTM de 40 canales, la diferencia entre una solucion de un dia y un laberinto de dos semanas es si instrumento el modulo correctamente durante el desarrollo. Este articulo cubre las interfaces fisicas de depuracion, metodos de trazado en tiempo real, rutas de verificacion RF y herramientas de post-mortem que deben disenarse desde el primer dia del esquematico, no anadirse despues del primer fallo en campo.

## 1. Panorama de Interfaces de Depuracion: JTAG vs SWD vs cJTAG

La mayoria de los SoC BLE modernos (nRF52/53, CC2640, ESP32-C3/H2, DA1469x, BGMxx) exponen un JTAG completo de 5 pines (TCK, TMS, TDI, TDO, nTRST) o el SWD de 2 pines especifico de ARM (SWCLK, SWDIO) mas nRESET. La tabla siguiente resume las compensaciones para el diseno de modulos BLE:

| Parametro | JTAG (5 pines) | SWD (2 pines + RESET) | cJTAG (2 pines) |
|———–|————-|———————|—————-|
| Numero de pines | 5 (o 4 sin nTRST) | 2-3 | 2 |
| Reloj maximo | 10-50 MHz | 1-50 MHz | hasta 50 MHz |
| Soporte de traza | ETM (bus traza 4 pines) | ITM (SWO, 1 pin) | ITM (SWO) |
| Velocidad descarga flash (256 KB) | ~8-12 s | ~6-10 s | ~6-10 s |
| Limite longitud cable | ~15 cm (sin buffer) | ~30 cm (sin buffer) | ~20 cm |
| Soporte SoC | Universal (ARM + RISC-V) | ARM Cortex-M solo | ARM Cortex-M33/55 |
| Corriente tipica (depuracion activa) | 2-5 mA | 1-3 mA | 1-3 mA |

Para modulos BLE donde el area de PCB se mide en milimetros cuadrados, SWD es la opcion por defecto. La serie nRF52/53 incluso permite SWD en los mismos pines que GPIO P0.00/P0.01 durante el desarrollo. Se enrutan a un micro-header de paso 0.05 pulgadas (Samtec FTSH-105 o equivalente) y se puebla para desarrollo o se deja como pads de PCB desnudos para produccion. El enfoque de solo pads es preferible porque un header poblado en un modulo de produccion invita acceso no autorizado.

### Consideraciones de Integridad de Senal SWD

SWDIO es bidireccional y drenaje abierto con pull-up (tipicamente 10 kΩ interno, 4.7 kΩ externo). El valor del pull-up importa mas de lo que la mayoria de ingenieros espera:

| Pull-up | Tiempo subida SWDIO (tr) | SWCLK max | Notas |
|———|———————|———–|——-|
| 100 kΩ | 220 ns | 1 MHz | Marginal — perdida de sincronia ocasional |
| 47 kΩ | 104 ns | 4 MHz | OK para cables cortos (<15 cm) | | 10 kΩ | 22 ns | 25 MHz | Fiable para la mayoria de configuraciones | | 4.7 kΩ | 10 ns | 50 MHz | Preferido para J-Link a alta velocidad | | 1 kΩ | 2.2 ns | >50 MHz | Excesivo, desperdicia 3.3 mA en bajo |

La formula es simplemente retardo RC: tr ≈ 2.2 × R × C, donde C es la capacitancia total de traza + sonda (tipicamente 10-20 pF en un modulo con cable plano de 15 cm). Si ve errores intermitentes «SWD DP read failed» en su J-Link, lo primero que debe verificar es si falta el pull-up externo y el interno de 10 kΩ esta luchando contra un cable largo.

## 2. Consola de Depuracion UART: Diseno para Depuracion del Mundo Real

Una consola de depuracion UART es la interfaz de depuracion mas valiosa en firmware de produccion, pero se implementa rutinariamente de forma deficiente. Los errores comunes:

1. **Baud rate demasiado alto para la prioridad de la pila BLE.** A 1 Mbps UART con FIFO de 16 bytes, la interrupcion se dispara cada 128 μs. Si la pila BLE mantiene interrupciones durante 150 μs en la preparacion del evento de conexion, se pierden caracteres. Solucion: usar 460800 bps o 921600 bps con DMA TX y buffer circular para RX.

2. **printf bloqueando el bucle principal.** Un `printf` bloqueante que escribe 200 bytes a 115200 bps tarda 17.4 ms — mas que un intervalo de conexion BLE de 7.5 ms. Use un buffer circular libre de bloqueos con descarga DMA en idle:

«`c
// Buffer circular UART libre de bloqueos (productor unico, consumidor unico)
#define DBG_BUF_SIZE 2048
static volatile uint16_t dbg_head = 0, dbg_tail = 0;
static char dbg_buf[DBG_BUF_SIZE];

void dbg_printf(const char *fmt, …) {
va_list ap;
va_start(ap, fmt);
char tmp[256];
int len = vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
for (int i = 0; i < len; i++) { uint16_t next = (dbg_head + 1) & (DBG_BUF_SIZE - 1); if (next == dbg_tail) break; // buffer lleno, descartar caracter dbg_buf[dbg_head] = tmp[i]; dbg_head = next; } // Trigger descarga DMA si TX idle if (!(UART0->STAT & UART_STAT_TXBUSY)) {
uart_dma_flush();
}
}
«`

3. **Sin filtrado de nivel de log.** Un modulo de produccion emitiendo logs de nivel VERBOSE a 460800 bps durante un evento de conexion causara jitter de temporizacion. Implemente filtrado en tiempo de compilacion y ejecucion:

| Nivel | Flag compilacion | Runtime | Uso tipico |
|——-|————-|———|————-|
| ERROR | `DBG_ERROR` | Siempre activo | Hard faults, fallos de asercion |
| WARN | `DBG_WARN` | Siempre activo | Reintentos, rendimiento degradado |
| INFO | `DBG_INFO` | Configurable | Conexion/desconexion, cambios de estado |
| DEBUG | `DBG_DEBUG` | Off en produccion | Temporizacion por evento, volcados de paquete |
| VERBOSE | `DBG_VERBOSE` | Off en produccion | Planificacion por slot, RSSI por evento |

4. **Sin capacidad de volcado de fallos binario.** Cuando el modulo tiene un hard fault, UART es su unico salvavidas. Pre-asigne un manejador de volcado de fallos de 1 KB que vuelque los registros apilados (R0-R3, R12, LR, PC, xPSR) y las primeras 16 palabras de la pila antes del reset del watchdog:

«`c
void HardFault_Handler(void) {
uint32_t *stk;
__asm volatile(«tst lr, #4
»
«ite eq
»
«mrseq %0, msp
»
«mrsne %0, psp
» : «=r»(stk));
dbg_printf(»
*** HARD FAULT ***
«);
dbg_printf(«R0: 0x%08X R1: 0x%08X R2: 0x%08X R3: 0x%08X
«,
stk[0], stk[1], stk[2], stk[3]);
dbg_printf(«R12: 0x%08X LR: 0x%08X PC: 0x%08X PSR: 0x%08X
«,
stk[4], stk[5], stk[6], stk[7]);
dbg_printf(«BFAR: 0x%08X CFSR: 0x%08X HFSR: 0x%08X
«,
SCB->BFAR, SCB->CFSR, SCB->HFSR);
for (int i = 0; i < 16; i++) { dbg_printf("SP+%02d: 0x%08X ", i*4, stk[i]); } while(1); // Esperar watchdog } ``` ### Seleccion de Pines UART en Modulos BLE Evite P0.00/P0.01 (reservados para SWD o cristal de 32 kHz), P0.02/P0.03 (a menudo ADC o analogico), y cualquier pin usado por la pila BLE para temporizacion de radio. Pines UART seguros en SoC comunes: | SoC | TX seguro | RX seguro | Evitar | |-----|---------|---------|-------| | nRF52832 | P0.06 | P0.08 | P0.00/01 (XL1/XL2), P0.09 (NFC) | | nRF52840 | P1.08 | P1.10 | P0.00/01, P0.09/10 (NFC), P0.24-25 (USB) | | ESP32-C3 | GPIO2 | GPIO3 | GPIO0 (boot), GPIO2 (strapping) | | CC2640R2 | DIO2 | DIO3 | DIO0-1 (boot), DIO7-8 (JTAG) | | DA1469x | P0_06 | P0_07 | P0_00 (XTAL32M), P0_01-03 (SWD) | ## 3. Trazado en Tiempo Real: RTT vs ITM/SWO vs ETM La depuracion UART basada en printf es buena para eventos de baja frecuencia, pero el analisis de temporizacion de la pila BLE requiere resolucion sub-microsegundo. Existen tres opciones, cada una con diferentes compensaciones: ### Segger RTT (Real-Time Transfer) RTT usa un buffer circular en RAM del objetivo que el depurador sondea via SWD a alta velocidad. Requiere tiempo cero de CPU por entrada de log (el depurador lee RAM directamente), haciendolo ideal para codigo sensible al tiempo: | Metrica | UART @ 460800 | RTT | ITM/SWO @ 2 MHz | |--------|---------------|-----|-----------------| | Tiempo CPU por log 100 caracteres | ~2.2 ms | ~5 us | ~50 us | | Throughput | 46 KB/s | ~500 KB/s | ~200 KB/s | | Latencia (log → depurador) | 2.2 ms | ~10 us | ~25 us | | Pines requeridos | 2 (TX/RX) | 0 (usa SWD) | 1 (SWO) + SWD | | Buffer en RAM | 0 | 1-4 KB | 0 (FIFO hardware) | | Soporte depurador | Cualquier terminal | Solo J-Link | J-Link, ST-Link, CMSIS-DAP | La principal ventaja de RTT es que funciona a traves de la interfaz SWD existente sin pines adicionales. Su principal limitacion es que requiere un Segger J-Link. Para desarrollo, esto es aceptable; para depuracion en campo, probablemente no tenga un J-Link. RTT tambien soporta comunicacion bidireccional — el depurador puede inyectar comandos en el objetivo sin usar un pin UART: ```c #include "SEGGER_RTT.h" void rtt_command_loop(void) { char cmd[64]; int len = SEGGER_RTT_Read(0, cmd, sizeof(cmd) - 1); if (len > 0) {
cmd[len] = ‘’;
if (strcmp(cmd, «stats») == 0) {
print_ble_stats();
} else if (strcmp(cmd, «scan») == 0) {
start_debug_scan(100);
} else if (strcmp(cmd, «conn») == 0) {
print_connection_info();
}
}
}
«`

### Trazado ITM/SWO

ITM (Instrumentation Trace Macrocell) es una caracteristica de ARM Cortex-M3/4/7/33 que proporciona 32 puertos de estimulo para trazado a nivel de aplicacion, mas estampas de tiempo y trazado de excepciones. El pin SWO (Serial Wire Output) transporta datos ITM como UART de un solo hilo hasta la velocidad del reloj de CPU:

«`c
// Puerto de estimulo ITM 0 para mensajes de depuracion
#define ITM_Port8(n) (*((volatile uint8_t *)(0xE0000000 + 4*n)))
#define ITM_Port32(n) (*((volatile uint32_t *)(0xE0000000 + 4*n)))

void itm_printf(char *s) {
while (*s) {
while (ITM_Port8(0) == 0); // esperar puerto listo
ITM_Port8(0) = *s++;
}
}
«`

SWO se puede configurar en dos modos:

| Modo | Baud SWO | Fuente reloj | Pros | Contras |
|——|———|————-|——|——|
| Modo UART | 2-50 MHz | HCLK / prescaler | Funciona con cualquier sonda SWO | Debe coincidir baud exactamente |
| Modo Manchester | Hasta reloj CPU | HCLK directo | Auto-reloj, sin coincidencia baud | Solo J-Link, no ST-Link |

Para analisis de temporizacion BLE, ITM destaca en registrar estampas de tiempo por evento. El hardware ITM estampa cada escritura con un contador de resolucion de 1 ciclo, por lo que puede medir temporizacion de eventos de conexion sin sobrecarga de CPU:

«`c
// Registrar temporizacion de evento de conexion en puerto ITM 1
void on_conn_event(uint16_t handle, int8_t rssi, uint32_t elapsed_us) {
ITM_Port32(1) = handle;
ITM_Port32(1) = (uint32_t)rssi;
ITM_Port32(1) = elapsed_us;
}
«`

J-Link SWO Viewer o SystemView pueden mostrar estos eventos en una linea de tiempo con estampas precisas en nanosegundos.

### ETM (Embedded Trace Macrocell)

ETM proporciona trazado completo a nivel de instruccion via un bus de traza paralelo de 4 bits. Esta disponible en Cortex-M7 (y algunos M4) pero requiere 4-7 pines adicionales. Para trabajo con modulos BLE, ETM rara vez se justifica — el coste de pines es demasiado alto y el trazado a nivel de instruccion produce demasiados datos para ser util en depuracion a nivel de protocolo. Es ocasionalmente util para analisis de fallos de cache en modulos de doble nucleo (nRF5340).

## 4. Tecnicas de Analizador Logico para Temporizacion BLE

Un analizador logico es indispensable para depurar problemas de temporizacion BLE que son invisibles a la instrumentacion basada en software. Los casos de uso clave:

### 4.1 Verificacion de Eventos de Pila BLE

La mayoria de pilas BLE exponen un GPIO de «evento de radio» o «comparador de timer» que se conmuta al inicio y fin de cada actividad de radio. Configurar un GPIO de depuracion para conmutar en eventos de radio permite medir:

| Medicion | Metodo | Que revela |
|————-|——–|—————–|
| Jitter de inicio de evento de conexion | Medir offset radio-GPIO a GPIO-PPS | Precision de cristal, deriva de timer de sleep |
| Duracion de evento de conexion | Ancho de pulso de radio-GPIO | Mismatch tamano payload vs intervalo |
| Temporizacion de ventana de scan | Ancho de pulso de scan-GPIO | Scan real vs scan configurado |
| Precision de intervalo de advertising | Medicion de periodo | Deriva, correccion de aleatorizacion |
| Brecha entre eventos | Tiempo entre flanco de bajada y siguiente subida | Overhead de pila, tiempo de procesamiento |

### 4.2 Decodificacion de Protocolo con Sniffing SWIRE/HCI

La mayoria de modulos BLE enrutan el trafico HCI entre host y controlador internamente, pero algunos lo exponen en una interfaz UART o SPI. Sniffar este trafico con un decodificador de protocolo de analizador logico es la forma mas rapida de depurar problemas de interaccion host-controlador:

– **UART HCI**: Saleae Logic 2 incluye un decodificador HCI UART que analiza comandos completos, estado de comando, datos ACL y eventos.
– **SPI HCI**: Algunos modulos (CC26xx con host externo) usan SPI de 4 hilos para HCI.
– **Propietario**: SWIRE propietario de Nordic es un protocolo bidireccional de un solo hilo.

### 4.3 Perfilado de Energia con Analizador Logico + Osciloscopio

El escenario de depuracion BLE mas comun: el modulo consume mas corriente de lo esperado. Conecte un analizador logico a GPIOs clave junto con una medicion de corriente (resistencia shunt + osciloscopio o Power Profiler Kit) para correlacionar eventos de software con picos de corriente:

| Senal GPIO | Que buscar en perfil de corriente |
|————-|————————————-|
| Radio activa | Pico de 4-15 mA, deberia ser 1-5 ms |
| CPU activa | 2-8 mA, deberia bajar a <10 uA entre eventos | | Borrado/escritura flash | Pico de 8-15 mA durando 20-50 ms por pagina | | UART TX | 1-3 mA durante la transmision | | Muestra ADC | 0.5-1.5 mA, picos cortos a la frecuencia de muestreo | | Lectura sensor externo (I2C/SPI) | 1-5 mA segun sensor | Un hallazgo comun: el modulo `app_timer` de la pila BLE en nRF52 dispara un timer de software 200 us antes del evento de radio, despertando la CPU durante 1.5 ms para prepararse. Si la aplicacion tambien tiene un timer programado al mismo tiempo, la CPU permanece despierta mas tiempo, anadiendo 2-4 mA de corriente media. ## 5. Depuracion RF: Modo de Prueba Directa (DTM) DTM es el metodo estandarizado (BT 4.2+ Vol 6, Part F) para probar la radio BLE sin pasar por la pila completa. Permite: 1. Transmitir portadora constante (CW) a frecuencia y potencia especificas 2. Transmitir senal modulada con payload PRBS9/PRBS15 3. Recibir y contar paquetes con parametros configurables 4. Medir tasa de error de paquete (PER) vs RSSI ### Metodos de Acceso DTM | Metodo | Interfaz | Comandos | Uso tipico | |--------|-----------|----------|-------------| | UART 2 hilos | Pines RX/TX | HCI especifico de fabricante | Prueba de produccion, certificacion | | UART 3 hilos | RX/TX/RTS | Igual que 2 hilos | Control de flujo para pruebas de alta velocidad | | HCI sobre USB | USB | Comandos HCI | Prueba de dongle USB | | Propietario fabricante | SWD/JTAG | Especifico de SoC | Depuracion a nivel de SoC (sin firmware) | ### Estructura de Comando DTM (UART 2 hilos) DTM usa una palabra de comando de 16 bits simple a 19200 bps (8N1): | Bit | Campo | Valor | Descripcion | |-----|-------|-------|-------------| | 15 | Tipo | 0 | Tipo de paquete | | 14-6 | Longitud | 0-37 | Numero de bytes en paquete (RX) o longitud a TX | | 5-2 | Canal RF | 0-39 | Canal BLE 0-39 (2402-2480 MHz) | | 1-0 | Tipo prueba | 0-3 | 0=PRBS9 TX, 1=PRBS15 TX, 2=PRBS9 RX, 3=CW TX | Ejemplo: transmitir PRBS9 en canal 19 (2440 MHz), 32 bytes: - Palabra de comando = 0b0_00001000_010011_00 = 0x044C - Enviar como 2 bytes: 0x4C, 0x04 (little-endian) ```c // Secuencia de prueba DTM para verificacion RF void dtm_verify_rf(void) { // 1. TX PRBS9 en canal 19, 32 bytes dtm_send(0x044C); delay_ms(100); dtm_send(0x0000); // Terminar prueba, leer evento // 2. Prueba RX en canal 19 dtm_send(0x044E); delay_ms(500); dtm_send(0x0000); uint16_t event = dtm_read_event(); uint16_t pkt_count = event & 0x7FFF; dbg_printf("DTM RX: %d packets in 500ms ", pkt_count); } ``` ### DTM para Pre-cumplimiento de Certificacion Antes de enviar un modulo a un laboratorio de certificacion, verifique que las siguientes pruebas DTM pasan: | Prueba | Comando DTM | Criterio de aprobacion | Equipamiento necesario | |------|------------|---------------|------------------| | Potencia TX (40 ch) | CW TX por canal | ±2 dB de spec | Analizador de espectro o medidor de potencia | | Caracteristicas de modulacion | PRBS15 TX | Δf1avg = 225-275 kHz, Δf2avg/Δf1avg ≥ 0.8 | Analizador de espectro + firmware | | Offset de frecuencia portadora | CW TX | ±50 kHz del nominal | Analizador de espectro (modo contador) | | Emisiones en banda | PRBS9 TX, 1 ch | < -20 dBm en canal adyacente | Analizador de espectro | | Ancho de banda 20 dB | PRBS15 TX | < 2.0 MHz | Analizador de espectro (RBW 100 kHz) | | Sensibilidad PER | Prueba RX | < 30.8% PER a -93 dBm (LE 1M) | Generador de senal + DTM RX | | PER maxima entrada | Prueba RX | < 30.8% PER a -20 dBm | Generador de senal + DTM RX | | Rechazo co-canal | RX + interferente | < 30.8% PER con deseado/interferente = +3 dB | 2 generadores de senal | ## 6. Estrategia de GPIO de Depuracion: de Desarrollo a Produccion Un modulo BLE bien diseniado deberia asignar 2-4 GPIOs especificamente para depuracion, con su funcion cambiando entre builds de desarrollo y produccion: ### Ejemplo de Asignacion de GPIO de Depuracion (modulo nRF52832) | GPIO | Funcion desarrollo | Funcion produccion | Notas | |------|---------------------|--------------------|----| | P0.31 | Toggle evento radio | Sin uso (entrada, pull-down) | Toggle en inicio/parada radio | | P0.30 | Toggle evento timer | Sin uso (entrada, pull-down) | Toggle en disparo app timer | | P0.29 | Estado maquina BLE | Sin uso (entrada, pull-down) | Codigo estado 3 bits (2 GPIOs) | | P0.28 | Estado maquina BLE | Sin uso (entrada, pull-down) | Codigo estado 3 bits (2 GPIOs) | Los GPIOs de maquina de estados codifican el estado BLE actual como valor binario: | Codigo estado | Significado | Duracion tipica | |-----------|---------|-----------------| | 000 | IDLE/sleep | 90-99% del tiempo | | 001 | Prep advertising | 50-100 us | | 010 | TX advertising | 80-376 us | | 011 | RX advertising (scan response) | 100-200 us | | 100 | Prep conexion | 100-200 us | | 101 | TX evento conexion | 80-200 us | | 110 | RX evento conexion | 100-300 us | | 111 | Flash/procesamiento | Variable | Esto le da una vista de maquina de estados en tiempo real en un analizador logico sin sobrecarga de software — las escrituras GPIO ocurren en contexto de interrupcion y toman 2-3 cicos cada una. ### Strapping de Pines de Depuracion en Produccion En produccion, a menudo no puede permitir headers de depuracion poblados. Una estrategia comun es usar pads de prueba accesibles via fixture de pogo-pin: | Pad | Senal | Diametro pogo pin | Notas | |-----|--------|-------------------|-------| | 1 | SWDIO | 0.68 mm | Patron 0.05", 2x5 | | 2 | SWCLK | 0.68 mm | | | 3 | GND | 0.68 mm | 2x pads GND | | 4 | VDD | 0.68 mm | Deteccion alimentacion | | 5 | nRESET | 0.68 mm | Opcional | | 6 | UART TX | 0.68 mm | Consola produccion | | 7 | UART RX | 0.68 mm | Consola produccion | | 8 | RF_OUT | 0.68 mm | Prueba conducida (sin antena) | Para modulos con antena integrada, las pruebas RF requieren un conector RF (U.FL o similar) durante desarrollo o un fixture de acoplamiento (celula TEM o sonda de campo cercano) en produccion. El enfoque de acoplamiento anade ±3-5 dB de incertidumbre, aceptable para pruebas go/no-go de produccion pero no para certificacion. ## 7. Volcado de Fallos y Analisis Post-Mortem Cuando un modulo BLE falla en el campo, las interfaces de depuracion discutidas hasta ahora no estan disponibles. El modulo necesita un mecanismo de volcado de fallos autocontenido que sobreviva a un reset: ### 7.1 Volcado de Fallos en RAM Retenida (sin reset) ARM Cortex-M retiene RAM a traves de un reset suave (NVIC_SystemReset). Colocando un numero magico en una direccion RAM conocida, el bootloader puede detectar un fallo y volcar el contexto guardado: ```c // Colocar en seccion RAM conocida que sobrevive reset suave #define CRASH_MAGIC_ADDR 0x20007FF0 // Ultimos 16 bytes de RAM #define CRASH_MAGIC 0xDEAD5F70 typedef struct { uint32_t magic; uint32_t r0, r1, r2, r3, r12, lr, pc, psr; uint32_t cfsr, hfsr, bfar; uint32_t uptime_ms; uint16_t conn_handle; uint8_t ble_state; uint8_t reserved; } crash_dump_t; // En bootloader (antes de app principal): crash_dump_t *cd = (crash_dump_t *)CRASH_MAGIC_ADDR; if (cd->magic == CRASH_MAGIC) {
uart_dump_crash(cd);
flash_store_crash(cd);
cd->magic = 0; // Limpiar para no re-volcar
}
«`

### 7.2 Registro de Fallos Basado en Flash

Para modulos que pueden perder alimentacion antes de recuperar el volcado, almacene datos de fallo en una pagina flash dedicada. Use un registro circular con una entrada por fallo:

| Campo | Tamano | Descripcion |
|——-|——|————-|
| Magic | 4 B | 0xDEAD5F70 |
| Causa reset | 4 B | Registro reset RCU |
| Registros apilados | 32 B | R0-R3, R12, LR, PC, xPSR |
| CFSR/HFSR/BFAR | 12 B | Registros de estado de fallo |
| Uptime | 4 B | ms desde arranque |
| Handle conexion | 2 B | Handle activo (0xFFFF = ninguno) |
| Estado BLE | 1 B | Estado en fallo |
| Reservado | 1 B | Alineacion |
| CRC16 | 2 B | Control de integridad |
| **Total** | **62 B** | Cabe en una unidad de escritura flash |

Con una pagina flash de 4 KB, puede almacenar 65 entradas de fallo. En la practica, 10-20 entradas son suficientes.

### 7.3 Analisis de Timeout de Watchdog

El tipo de fallo mas frustrante: el watchdog se dispara pero no hay HardFault, por lo que el volcado esta vacio. Para diagnosticar timeouts de watchdog:

1. **Instantanea ISR del timer**: En la funcion de alimentacion del watchdog, guarde la pila de llamadas actual (valor LR) en una ubicacion de RAM retenida.

2. **Registro de heartbeat periodico**: Escriba un heartbeat con estampa de tiempo a flash cada 30 segundos.

3. **Pre-aviso del watchdog**: Configure el watchdog para disparar una interrupcion de aviso temprano 500 ms antes del reset real:

«`c
void WDT_IRQHandler(void) {
// Aviso temprano — 500ms antes del reset
uint32_t *sp;
__asm volatile(«mrs %0, psp» : «=r»(sp));
crash_dump_t *cd = (crash_dump_t *)CRASH_MAGIC_ADDR;
cd->magic = CRASH_MAGIC;
cd->pc = sp[6];
cd->lr = sp[5];
cd->cfsr = SCB->CFSR;
cd->uptime_ms = system_uptime();
cd->ble_state = ble_get_state();
while(1);
}
«`

## 8. Seguridad de Depuracion: Lock Bits, Debug Seguro y Endurecimiento de Produccion

Las interfaces de depuracion son un pasivo de seguridad. Un header SWD poblado en un modulo de produccion significa que cualquiera con una sonda CMSIS-DAP de $10 puede leer su firmware, extraer claves y clonar su modulo. Enfoque de defensa en profundidad:

### 8.1 Niveles de Lock Bit

| Nivel proteccion | Mecanismo | Que bloquea | Recuperacion |
|—————–|———–|—————|———-|
| Nivel 0 (abierto) | Ninguno | Nada | N/A |
| Nivel 1 (flash bloqueado) | Registro APPROTECT | Lectura/escritura flash/RAM via SWD | Borrado completo para desbloquear |
| Nivel 2 (permanente) | Fuse/OTP bit | Todo acceso debug, permanentemente | Ninguno — irreversible |

Para nRF52, el registro `APPROTECT` en `UICR.APPROTECT = 0xFFFFFF00` habilita Nivel 1. La sonda debug puede conectar pero no leer flash — solo borrar todo. Nivel 2 esta disponible en algunos SoC (ESP32-C3 quemar efuses, STM32 RDP Nivel 2) y deshabilita el acceso debug permanentemente.

### 8.2 Debug Seguro (Debug Autenticado)

Algunos SoC (nRF5340, CC2640R2 con bootloader seguro) soportan debug autenticado, donde la sonda debe presentar un desafio-respuesta criptografico:

«`c
// nRF5340 nucleo de red: desafio de debug seguro
typedef struct {
uint8_t challenge[16]; // Nonce aleatorio del objetivo
uint8_t signature[64]; // Firma ECDSA-P256 del certificado debug
uint32_t cert_id; // Que certificado de debug usar
} secure_debug_auth_t;
«`

Esto permite acceso debug en campo (para personal de servicio autorizado) sin comprometer permanentemente la seguridad del modulo.

### 8.3 Estrategia de Debug de Produccion

| Fase | APPROTECT | Consola UART | GPIOs debug | DTM |
|——|———–|————-|————-|—–|
| Bring-up (EVT) | Off | On, 460800 | Todos poblados | Via SWD |
| Verificacion (DVT) | Off | On, 115200 | Todos poblados | Via SWD |
| Piloto (PVT) | Nivel 1 | On, 115200 (pad prueba) | 2 pads senal solo | Via fixture |
| Produccion masiva | Nivel 1 | Off (pad para fallos) | Ninguno | Solo fixture |
| Devolucion campo | Nivel 1 | Rework para habilitar | Rework | Rework |

Principio clave: cada interfaz no necesitada en produccion debe ser despooblada (headers), deshabilitada (UART via flag compilacion), o protegida (SWD via APPROTECT).

## 9. Errores Comunes de Arquitectura de Depuracion

| Error | Impacto | Solucion |
|———|——–|—–|
| Sin pull-up SWD en SWDIO | Conexion intermitente, «DP read failed» aleatorio | Anadir pull-up externo 4.7-10 kΩ |
| UART TX en mismo pin que DCX pila BLE | Config radio corrupta, caidas aleatorias | Mover UART a pin seguro |
| Buffer RTT en RAM no retenida | Datos RTT perdidos tras sleep/wake | Colocar buffer en seccion retenida |
| printf en ISR de radio | Latencia ISR 2+ ms, paquetes perdidos | Usar RTT o diferir a tarea idle |
| Sin volcado en RAM retenida | Sin datos diagnosticos post-reset | Implementar volcado seccion 7.1 |
| GPIOs debug activos en produccion | Corriente extra, 50-200 uA por entrada flotante | Config como entrada pull-down en build produccion |
| DTM no accesible sin flashear firmware completo | No puede probar RF sin borrar app | Bootloader comprueba strap DTM en arranque |
| APPROTECT no configurado en firmware de envio | Firmware extraible con sonda $10 | Configurar UICR.APPROTECT en script flash |
| Baud UART demasiado alto para pila BLE | Perdida caracteres durante eventos conexion | Usar DMA TX o limitar a 115200 con FIFO 16 bytes |
| Sin ISR de pre-aviso watchdog | No puede diagnosticar timeouts WDT | Habilitar interrupcion aviso temprano 500ms antes |

## 10. Checklist de Interfaces de Depuracion para Nuevo Diseno de Modulo

Antes de fabricar un PCB de modulo BLE, verifique:

– [ ] Pads SWD (SWDIO, SWCLK, nRESET, VDD, GND) accesibles como micro-header 0.05″ o pads prueba
– [ ] SWDIO tiene pull-up externo 4.7-10 kΩ (no confiar en interno)
– [ ] UART TX/RX en pines seguros (sin conflicto con cristal, NFC, pila BLE)
– [ ] DMA TX UART configurado, buffer circular RX
– [ ] Flags de nivel de log en compilacion (DBG_ERROR/WARN/INFO/DEBUG/VERBOSE)
– [ ] 2-4 GPIOs debug asignados, configurables via flag compilacion
– [ ] Manejador HardFault vuelca registros a RAM retenida + UART
– [ ] Numero magico de volcado en RAM retenida, bootloader comprueba en arranque
– [ ] Registro de fallos flash (circular, 10-20 entradas)
– [ ] ISR de pre-aviso watchdog con instantanea de pila
– [ ] DTM accesible via UART 2 hilos (pads prueba en produccion)
– [ ] Pad RF o conector U.FL para pruebas DTM conducidas
– [ ] Configuracion APPROTECT en script flash de produccion
– [ ] Firmware produccion compila con solo DBG_INFO (sin DEBUG/VERBOSE)
– [ ] GPIOs debug configurados como entrada pull-down en build produccion

## Resumen

El diseno de interfaces de depuracion no es una ocurrencia tardia — es una disciplina de ingenieria de primera clase que determina la rapidez con la que puede diagnosticar fallos de campo, aprobar certificaciones e iterar firmware. La inversion es modesta: 2-4 GPIOs adicionales, huella SWD de 5 pads, manejador de volcado en RAM retenida y modo boot DTM. El retorno se mide en semanas ahorradas durante bring-up y miles de dolares ahorrados evitando conjeturas en devoluciones de campo. En su próximo diseno de modulo Bluetooth, presupueste estas interfaces desde la revision del esquematico, no desde el primer informe de fallo.