Wenn ein Bluetooth-Modul im Feld Verbindungen verliert, im Sleep-Modus 3 mA ueber Spezifikation verbraucht oder bei der Zertifizierung auf dem 2. Kanal des 40-Kanal-DTM-Sweeps scheitert, ist der Unterschied zwischen einer einstuendigen Reparatur und einer zweiwoechigen Sackgasse, ob Sie das Modul waehrend der Entwicklung richtig instrumentiert haben. Dieser Artikel behandelt die physischen Debug-Schnittstellen, Echtzeit-Tracing-Methoden, RF-Verifizierungspfade und Post-Mortem-Tools, die ab dem ersten Schaltplan-Tag eingeplant werden sollten — nicht nach dem ersten Feldfehler nachgeruestet.

## 1. Debug-Schnittstellenuebersicht: JTAG vs SWD vs cJTAG

Die meisten modernen BLE-SoCs (nRF52/53, CC2640, ESP32-C3/H2, DA1469x, BGMxx) exponieren entweder ein volles 5-Pin-JTAG (TCK, TMS, TDI, TDO, nTRST) oder das ARM-spezifische 2-Pin-SWD (SWCLK, SWDIO) plus nRESET. Die folgende Tabelle fasst die Kompromisse fuer das BLE-Moduldesign zusammen:

| Parameter | JTAG (5-Pin) | SWD (2-Pin + RESET) | cJTAG (2-Pin) |
|———–|————-|———————|—————-|
| Pin-Anzahl | 5 (oder 4 ohne nTRST) | 2-3 | 2 |
| Max. Takt | 10-50 MHz | 1-50 MHz | bis 50 MHz |
| Trace-Unterstuetzung | ETM (4-Pin-Trace-Bus) | ITM (SWO, 1-Pin) | ITM (SWO) |
| Flash-Download-Geschw. (256 KB) | ~8-12 s | ~6-10 s | ~6-10 s |
| Kabellaengenbegrenzung | ~15 cm (ungepuffert) | ~30 cm (ungepuffert) | ~20 cm |
| SoC-Unterstuetzung | Universell (ARM + RISC-V) | Nur ARM Cortex-M | ARM Cortex-M33/55 |
| Typische Stromaufnahme (aktives Debug) | 2-5 mA | 1-3 mA | 1-3 mA |

Fuer BLE-Module, bei denen die PCB-Flaeche in Quadratmillimetern gemessen wird, ist SWD die Standardwahl. Die nRF52/53-Serie erlaubt SWD sogar auf denselben Pins wie GPIO P0.00/P0.01 waehrend der Entwicklung. Diese werden auf einen 0,05-Zoll-Raster-Mikro-Header (Samtec FTSH-105 oder aequivalent) gefuehrt und entweder fuer die Entwicklung bestueckt oder als nackte PCB-Pads fuer die Produktion belassen. Der Nur-Pad-Ansatz ist vorzuziehen, da ein bestueckter Header auf einem Produktionsmodul unautorisierten Zugriff einlaedt.

### SWD-Signalintegritaetsueberlegungen

SWDIO ist bidirektional und Open-Drain mit Pull-up (typisch 10 kΩ intern, 4,7 kΩ extern). Der Pull-up-Wert ist wichtiger, als die meisten Ingenieure erwarten:

| Pull-up | SWDIO-Anstiegszeit (tr) | Max. SWCLK | Hinweise |
|———|———————|———–|——-|
| 100 kΩ | 220 ns | 1 MHz | Grenzwertig — gelegentlicher Sync-Verlust |
| 47 kΩ | 104 ns | 4 MHz | OK fuer kurze Kabel (<15 cm) | | 10 kΩ | 22 ns | 25 MHz | Zuverlaessig fuer die meisten Setups | | 4,7 kΩ | 10 ns | 50 MHz | Bevorzugt fuer J-Link bei hoher Geschwindigkeit | | 1 kΩ | 2,2 ns | >50 MHz | Uebertrieben, verschwendet 3,3 mA bei Low |

Die Formel ist einfach RC-Verzoegerung: tr ≈ 2.2 × R × C, wobei C die Gesamt-Leiterbahn- + Tastkopfkapazitaet ist (typisch 10-20 pF bei einem Modul mit 15 cm Flachbandkabel). Wenn Sie intermitierende „SWD DP read failed“-Fehler auf Ihrem J-Link sehen, sollten Sie zuerst pruefen, ob der externe Pull-up fehlt und der interne 10 kΩ gegen ein langes Kabel kaempft.

## 2. UART-Debug-Konsole: Design fuer reales Debugging

Eine UART-Debug-Konsole ist die wertvollste Debug-Schnittstelle in Produktionsfirmware, wird aber routinemaessig schlecht implementiert. Die haeufigsten Fehler:

1. **Baudrate zu hoch fuer die BLE-Stack-Prioritaet.** Bei 1 Mbps UART mit 16-Byte-FIFO wird der Interrupt alle 128 μs ausgeloest. Wenn der BLE-Stack Interrupts waehrend 150 μs der Verbindungsereignis-Vorbereitung sperrt, gehen Zeichen verloren. Loesung: 460800 bps oder 921600 bps mit DMA-TX und Ringpuffer fuer RX verwenden.

2. **printf blockiert die Hauptschleife.** Ein blockierendes `printf`, das 200 Bytes bei 115200 bps schreibt, dauert 17,4 ms — laenger als ein 7,5 ms BLE-Verbindungsintervall. Verwenden Sie einen lockfreien Ringpuffer mit DMA-Flush im Idle:

„`c
// Lockfreier UART-Debug-Ringpuffer (einzelner Produzent, einzelner Konsument)
#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; // Puffer voll, Zeichen verwerfen dbg_buf[dbg_head] = tmp[i]; dbg_head = next; } // DMA-Flush ausloesen, wenn TX idle if (!(UART0->STAT & UART_STAT_TXBUSY)) {
uart_dma_flush();
}
}
„`

3. **Keine Log-Level-Filterung.** Ein Produktionsmodul, das VERBOSE-Level-Logs bei 460800 bps waehrend eines Verbindungsereignisses ausgibt, verursacht Timing-Jitter. Implementieren Sie Kompilierzeit- und Laufzeit-Filterung:

| Level | Kompilier-Flag | Runtime | Typische Verwendung |
|——-|————-|———|————-|
| ERROR | `DBG_ERROR` | Immer an | Hard Faults, Assert-Fehler |
| WARN | `DBG_WARN` | Immer an | Wiederversuche, degradierte Leistung |
| INFO | `DBG_INFO` | Konfigurierbar | Verbindung/Trennung, Zustaendsaenderungen |
| DEBUG | `DBG_DEBUG` | Off in Produktion | Pro-Event-Timing, Paket-Dumps |
| VERBOSE | `DBG_VERBOSE` | Off in Produktion | Pro-Slot-Scheduling, RSSI pro Event |

4. **Keine Binaer-Crash-Dump-Faehigkeit.** Wenn das Modul einen Hard Fault hat, ist UART Ihre einzige Lebensader. Reservieren Sie einen 1 KB Crash-Dump-Handler, der die gestapelten Register (R0-R3, R12, LR, PC, xPSR) und die ersten 16 Worte des Stacks vor dem Watchdog-Reset ausgibt:

„`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); // Auf Watchdog warten } ``` ### UART-Pin-Auswahl bei BLE-Modulen Vermeiden Sie P0.00/P0.01 (fuer SWD oder 32-kHz-Kristall reserviert), P0.02/P0.03 (oft ADC oder Analog) und alle Pins, die vom BLE-Stack fuer Radio-Timing verwendet werden. Sichere UART-Pins bei haeufigen SoCs: | SoC | Sicheres TX | Sicheres RX | Vermeiden | |-----|---------|---------|-------| | 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. Echtzeit-Tracing: RTT vs ITM/SWO vs ETM printf-basiertes UART-Debug ist fuer niederfrequente Ereignisse geeignet, aber die BLE-Stack-Timing-Analyse erfordert Submikrosekunden-Aufloesung. Drei Optionen mit unterschiedlichen Kompromissen: ### Segger RTT (Real-Time Transfer) RTT verwendet einen Ringpuffer im Ziel-RAM, den der Debugger ueber SWD mit hoher Geschwindigkeit abfragt. Es erfordert null Ziel-CPU-Zeit pro Log-Eintrag (der Debugger liest RAM direkt), was es ideal fuer timing-kritischen Code macht: | Metrik | UART @ 460800 | RTT | ITM/SWO @ 2 MHz | |--------|---------------|-----|-----------------| | CPU-Zeit pro 100-Zeichen-Log | ~2,2 ms | ~5 us | ~50 us | | Durchsatz | 46 KB/s | ~500 KB/s | ~200 KB/s | | Latenz (Log → Debugger) | 2,2 ms | ~10 us | ~25 us | | Benoetigte Pins | 2 (TX/RX) | 0 (nutzt SWD) | 1 (SWO) + SWD | | Puffer im RAM | 0 | 1-4 KB | 0 (Hardware-FIFO) | | Debugger-Unterstuetzung | Beliebiges Terminal | Nur J-Link | J-Link, ST-Link, CMSIS-DAP | RTTs Hauptvorteil ist, dass es ueber die vorhandene SWD-Schnittstelle ohne zusaetzliche Pins funktioniert. Die Hauptbeschraenkung ist, dass es einen Segger J-Link erfordert. Fuer Entwicklung ist das akzeptabel; fuer Felddiagnose haben Sie wahrscheinlich keinen J-Link. RTT unterstuetzt auch bidirektionale Kommunikation — der Debugger kann Befehle in das Ziel injizieren, ohne einen UART-Pin zu verwenden: ```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();
}
}
}
„`

### ITM/SWO-Tracing

ITM (Instrumentation Trace Macrocell) ist ein ARM Cortex-M3/4/7/33-Feature, das 32 Stimulus-Ports fuer anwendungslevel-Tracing plus Zeitstempelung und Exception-Tracing bietet. Der SWO-Pin (Serial Wire Output) traegt ITM-Daten als Ein-Draht-UART bis zur CPU-Taktgeschwindigkeit:

„`c
// ITM-Stimulus-Port 0 fuer Debug-Nachrichten
#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); // Warten bis Port bereit
ITM_Port8(0) = *s++;
}
}
„`

SWO kann in zwei Modi konfiguriert werden:

| Modus | SWO-Baudrate | Taktquelle | Vorteile | Nachteile |
|——|———|————-|——|——|
| UART-Modus | 2-50 MHz | HCLK / Prescaler | Funktioniert mit jeder SWO-faehigen Sonde | Baud muss exakt passen |
| Manchester-Modus | Bis CPU-Takt | HCLK direkt | Selbsttaktend, keine Baud-Anpassung | Nur J-Link, nicht ST-Link |

Fuer BLE-Timing-Analyse eignet sich ITM hervorragend fuer Pro-Event-Zeitstempel-Logging. Die ITM-Hardware stempelt jeden Schreibvorgang mit einem Zaehler mit 1-Zyklus-Aufloesung, sodass Sie Verbindungsereignis-Timing ohne CPU-Overhead messen koennen:

„`c
// Verbindungsereignis-Timing auf ITM-Port 1 protokollieren
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 oder SystemView koennen diese Ereignisse auf einer Zeitachse mit nanosekunden-genuen Zeitstempeln anzeigen.

### ETM (Embedded Trace Macrocell)

ETM bietet vollstaendiges Instruktionsebene-Tracing ueber einen 4-Bit-parallelen Trace-Bus. Es ist auf Cortex-M7 (und einigen M4) verfuegbar, erfordert aber 4-7 zusaetzliche Pins. Fuer BLE-Modul-Arbeiten ist ETM selten gerechtfertigt — die Pin-Kosten sind zu hoch und Instruktionsebene-Tracing produziert zu viele Daten, um fuer Protokollebene-Debugging nuetzlich zu sein.

## 4. Logikanalysator-Techniken fuer BLE-Timing

Ein Logikanalysator ist unabdingbar fuer das Debuggen von BLE-Timing-Problemen, die fuer softwarebasierte Instrumentierung unsichtbar sind. Die wichtigsten Anwendungsfälle:

### 4.1 BLE-Stack-Ereignisverifizierung

Die meisten BLE-Stacks exponieren ein „Radio-Event“- oder „Timer-Compare“-GPIO, das am Anfang und Ende jeder Radioaktivitaet schaltet. Auf nRF52 ist dies `RADIO_SHORTS` oder `TIMER0`-Compare; auf ESP32 das `BT_CONTROLLER`-Event-Signal. Konfigurieren eines Debug-GPIOs zum Schalten bei Radio-Events erlaubt die Messung von:

| Messung | Methode | Was es offenbart |
|————-|——–|—————–|
| Verbindungsereignis-Start-Jitter | Radio-GPIO zu GPIO-PPS-Offset messen | Kristallgenauigkeit, Sleep-Timer-Drift |
| Verbindungsereignis-Dauer | Pulsbreite des Radio-GPIO | Payload-Groesse vs. Intervall-Mismatch |
| Scan-Window-Timing | Pulsbreite des Scan-GPIO | Tatsaechlicher Scan vs. konfigurierter Scan |
| Advertising-Intervall-Genauigkeit | Periodenmessung | Drift, Randomisierungskorrektheit |
| Inter-Event-Luecke | Zeit zwischen fallender und naechster steigender Flanke | Stack-Overhead, Verarbeitungszeit |

### 4.2 Protokolldekodierung mit SWIRE/HCI-Sniffing

Die meisten BLE-Module routen HCI-Traffic zwischen Host und Controller intern, aber einige exponieren ihn auf einer UART- oder SPI-Schnittstelle. Das Sniffen dieses Traffics mit einem Logikanalysator-Protokolldecoder ist der schnellste Weg, um Host-Controller-Interaktionsprobleme zu debuggen:

– **UART HCI**: Saleae Logic 2 enthaelt einen HCI-UART-Decoder, der Command Complete, Command Status, ACL-Daten und Events parst.
– **SPI HCI**: Einige Module (CC26xx mit externem Host) verwenden 4-Draht-SPI fuer HCI.
– **Proprietaer**: Nordics proprietaeres SWIRE ist ein Ein-Draht-Bidirektional-Protokoll.

### 4.3 Leistungsprofilerstellung mit Logikanalysator + Oszilloskop

Das haeufigste BLE-Debug-Szenario: Das Modul verbraucht mehr Strom als erwartet. Verbinden Sie einen Logikanalysator mit Schluessel-GPIOs alongside einer Strommessung (Shunt-Widerstand + Oszilloskop oder Power Profiler Kit), um Software-Events mit Stromspitzen zu korrelieren:

| GPIO-Signal | Was im Stromprofil zu suchen ist |
|————-|————————————-|
| Radio aktiv | 4-15 mA-Spitze, sollte 1-5 ms sein |
| CPU aktiv | 2-8 mA, sollte zwischen Events auf <10 uA fallen | | Flash loeschen/schreiben | 8-15 mA-Spitze, 20-50 ms pro Seite | | UART TX | 1-3 mA fuer die Dauer der Uebertragung | | ADC-Sample | 0,5-1,5 mA, kurze Spitzen bei Samplerate | | Externe Sensor-Lesung (I2C/SPI) | 1-5 mA je nach Sensor | Ein haeufiger Befund: Das `app_timer`-Modul des BLE-Stacks auf nRF52 feuert einen Software-Timer 200 μs vor dem Radio-Event und weckt die CPU fuer 1,5 ms zur Vorbereitung. Wenn die Anwendung ebenfalls einen Timer zur gleichen Zeit geplant hat, bleibt die CPU laenger wach und addiert 2-4 mA mittleren Strom. ## 5. RF-Debug: Direct Test Mode (DTM) DTM ist die standardisierte (BT 4.2+ Vol 6, Part F) Methode zum Testen des BLE-Radios ohne den vollstaendigen Stack. Es ermoeglicht: 1. Senden eines konstanten Traegers (CW) bei spezifischer Frequenz und Leistung 2. Senden eines modulierten Signals mit PRBS9/PRBS15-Payload 3. Empfangen und Zaehlen von Paketen mit konfigurierbaren Parametern 4. Messen der Paketfehlerrate (PER) vs. RSSI ### DTM-Zugriffsmethoden | Methode | Schnittstelle | Befehle | Typische Verwendung | |--------|-----------|----------|-------------| | 2-Draht-UART | RX/TX-Pins | HCI herstellerspezifisch | Produktionstest, Zertifizierung | | 3-Draht-UART | RX/TX/RTS | Wie 2-Draht | Flusssteuerung fuer Hochratentests | | HCI ueber USB | USB | HCI-Befehle | USB-Dongle-Test | | Proprietaer | SWD/JTAG | SoC-spezifisch | SoC-Level-Debug (keine Firmware) | ### DTM-Befehlsstruktur (2-Draht-UART) DTM verwendet ein einfaches 16-Bit-Befehlswort bei 19200 bps (8N1): | Bit | Feld | Wert | Beschreibung | |-----|-------|-------|-------------| | 15 | Typ | 0 | Pakettyp | | 14-6 | Laenge | 0-37 | Anzahl Bytes im Paket (RX) oder TX-Laenge | | 5-2 | RF-Kanal | 0-39 | BLE-Kanal 0-39 (2402-2480 MHz) | | 1-0 | Testtyp | 0-3 | 0=PRBS9 TX, 1=PRBS15 TX, 2=PRBS9 RX, 3=CW TX | Beispiel: PRBS9 auf Kanal 19 (2440 MHz) senden, 32 Bytes: - Befehlswort = 0b0_00001000_010011_00 = 0x044C - Als 2 Bytes senden: 0x4C, 0x04 (Little-Endian) ```c // DTM-Testsequenz fuer RF-Verifizierung void dtm_verify_rf(void) { // 1. TX PRBS9 auf Kanal 19, 32 Bytes dtm_send(0x044C); delay_ms(100); dtm_send(0x0000); // Test beenden, Event lesen // 2. RX-Test auf Kanal 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 fuer Zertifizierungs-Pre-Compliance Bevor Sie ein Modul an ein Zertifizierungslabor senden, verifizieren Sie, dass folgende DTM-Tests bestanden werden: | Test | DTM-Befehl | Bestehenskriterium | Benoetigte Ausruestung | |------|------------|---------------|------------------| | TX-Leistung (alle 40 Kan.) | CW TX pro Kanal | ±2 dB der Spezifikation | Spektrumanalysator oder Leistungsmesser | | Modulationscharakteristika | PRBS15 TX | Δf1avg = 225-275 kHz, Δf2avg/Δf1avg ≥ 0.8 | Spektrumanalysator + Firmware | | Traegerfrequenz-Offset | CW TX | ±50 kHz vom Nennwert | Spektrumanalysator (Zaehlermodus) | | In-Band-Emissionen | PRBS9 TX, 1 Kan. | < -20 dBm am Nachbar kanal | Spektrumanalysator | | 20-dB-Bandbreite | PRBS15 TX | < 2,0 MHz | Spektrumanalysator (RBW 100 kHz) | | PER-Empfindlichkeit | RX-Test | < 30,8% PER bei -93 dBm (LE 1M) | Signalgenerator + DTM RX | | PER-Maximal-Eingang | RX-Test | < 30,8% PER bei -20 dBm | Signalgenerator + DTM RX | | Co-Channel-Unterdrueckung | RX + Stoerer | < 30,8% PER bei gewuenscht/Stoerer = +3 dB | 2 Signalgeneratoren | ## 6. Debug-GPIO-Strategie: Von Entwicklung zu Produktion Ein gut entworfenes BLE-Modul sollte 2-4 GPIOs speziell fuer Debugging reservieren, deren Funktion zwischen Entwicklungs- und Produktions-Builds wechselt: ### Debug-GPIO-Zuweisungsbeispiel (nRF52832-Modul) | GPIO | Entwicklungsfunktion | Produktionsfunktion | Hinweise | |------|---------------------|--------------------|----| | P0.31 | Radio-Event-Toggle | Unbenutzt (Eingang, Pull-Down) | Toggle bei Radio-Start/Stopp | | P0.30 | Timer-Event-Toggle | Unbenutzt (Eingang, Pull-Down) | Toggle bei App-Timer-Feuer | | P0.29 | BLE-Zustandsmaschine-Zustand | Unbenutzt (Eingang, Pull-Down) | 3-Bit-Zustandscode (2 GPIOs) | | P0.28 | BLE-Zustandsmaschine-Zustand | Unbenutzt (Eingang, Pull-Down) | 3-Bit-Zustandscode (2 GPIOs) | Die Zustandsmaschinen-GPIOs kodieren den aktuellen BLE-Zustand als Binaerwert: | Zustandscode | Bedeutung | Typische Dauer | |-----------|---------|-----------------| | 000 | IDLE/Sleep | 90-99% der Zeit | | 001 | Advertising-Vorbereitung | 50-100 us | | 010 | Advertising-TX | 80-376 us | | 011 | Advertising-RX (Scan-Response) | 100-200 us | | 100 | Verbindungs-Vorbereitung | 100-200 us | | 101 | Verbindungsereignis-TX | 80-200 us | | 110 | Verbindungsereignis-RX | 100-300 us | | 111 | Flash/Verarbeitung | Variabel | Dies gibt Ihnen eine Echtzeit-Zustandsmaschinen-Ansicht auf einem Logikanalysator ohne Software-Overhead — die GPIO-Schreibvorgaenge erfolgen im Interrupt-Kontext und dauern jeweils 2-3 Zyklen. ### Produktions-Debug-Pin-Strapping In der Produktion koennen Sie sich oft keine bestueckten Debug-Header leisten. Eine haeufige Strategie ist die Verwendung von Pruefpads, die ueber Pogo-Pin-Fixture zuganglich sind: | Pad | Signal | Pogo-Pin-Durchmesser | Hinweise | |-----|--------|-------------------|-------| | 1 | SWDIO | 0,68 mm | 0,05"-Raster, 2x5-Muster | | 2 | SWCLK | 0,68 mm | | | 3 | GND | 0,68 mm | 2x GND-Pads | | 4 | VDD | 0,68 mm | Target-Power-Sense | | 5 | nRESET | 0,68 mm | Optional | | 6 | UART TX | 0,68 mm | Produktionskonsole | | 7 | UART RX | 0,68 mm | Produktionskonsole | | 8 | RF_OUT | 0,68 mm | Leitungsgebundener Test (ohne Antenne) | Bei Modulen mit integrierter Antenne erfordern RF-Tests entweder einen RF-Stecker (U.FL oder aehnlich) waehrend der Entwicklung oder eine Koppelungs-Vorrichtung (TEM-Zelle oder Nahfeldsonde) in der Produktion. Der Koppelungsansatz addiert ±3-5 dB Unsicherheit, was fuer Go/No-Go-Produktionstests akzeptabel ist, aber nicht fuer die Zertifizierung. ## 7. Crash-Dump und Post-Mortem-Analyse Wenn ein BLE-Modul im Feld abstuerzt, sind die bisher besprochenen Debug-Schnittstellen nicht verfuegbar. Das Modul benoetigt einen in sich geschlossenen Crash-Dump-Mechanismus, der einen Reset ueberlebt: ### 7.1 Retained-RAM-Crash-Dump (ohne Reset) ARM Cortex-M behaelt RAM ueber einen Soft-Reset (NVIC_SystemReset). Durch Platzieren einer Magic Number an einer bekannten RAM-Adresse kann der Bootloader einen Absturz erkennen und den gespeicherten Kontext ausgeben: ```c // In bekanntem RAM-Abschnitt platzieren, der Soft-Reset ueberlebt #define CRASH_MAGIC_ADDR 0x20007FF0 // Letzte 16 Bytes 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; // Im Bootloader (vor Haupt-App): 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; // Loeschen, damit nicht erneut ausgegeben wird
}
„`

### 7.2 Flash-basiertes Crash-Log

Fuer Module, die die Stromversorgung verlieren koennen, bevor der Crash-Dump abgerufen wird, speichern Sie Crash-Daten auf einer dedizierten Flash-Seite. Verwenden Sie ein zirkulaeres Log mit einem Eintrag pro Absturz:

| Feld | Groesse | Beschreibung |
|——-|——|————-|
| Magic | 4 B | 0xDEAD5F70 |
| Reset-Ursache | 4 B | RCU-Reset-Register |
| Gestapelte Register | 32 B | R0-R3, R12, LR, PC, xPSR |
| CFSR/HFSR/BFAR | 12 B | Fault-Status-Register |
| Uptime | 4 B | ms seit Boot |
| Verbindungs-Handle | 2 B | Aktives Handle (0xFFFF = keins) |
| BLE-Zustand | 1 B | Zustand bei Absturz |
| Reserviert | 1 B | Ausrichtung |
| CRC16 | 2 B | Integritaetspruefung |
| **Total** | **62 B** | Passt in eine Flash-Schreibeinheit |

Mit einer 4-KB-Flash-Seite koennen Sie 65 Crash-Eintraege speichern. In der Praxis reichen 10-20 Eintraege.

### 7.3 Watchdog-Timeout-Analyse

Der frustrierendste Absturztyp: Der Watchdog feuert, aber es gibt keinen HardFault, sodass der Crash-Dump leer ist. Zur Diagnose von Watchdog-Timeouts:

1. **Timer-ISR-Snapshot**: In der Watchdog-Feed-Funktion den aktuellen Call-Stack (LR-Wert) an einer Retained-RAM-Stelle speichern.

2. **Periodisches Heartbeat-Log**: Schreiben Sie alle 30 Sekunden einen mit Zeitstempel versehenen Heartbeat auf Flash.

3. **Watchdog-Vorwarnung**: Konfigurieren Sie den Watchdog so, dass er 500 ms vor dem tatsaechlichen Reset einen Fruehwarn-Interrupt ausloest:

„`c
void WDT_IRQHandler(void) {
// Fruehwarnung — 500ms vor 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. Debug-Sicherheit: Lock Bits, Secure Debug und Produktions-Hardening

Debug-Schnittstellen sind ein Sicherheitsrisiko. Ein bestueckter SWD-Header auf einem Produktionsmodul bedeutet, dass jeder mit einer 10-Dollar-CMSIS-DAP-Sonde Ihre Firmware lesen, Schluessel extrahieren und Ihr Modul klonen kann. Defense-in-Depth-Ansatz:

### 8.1 Lock-Bit-Level

| Schutzlevel | Mechanismus | Was blockiert wird | Wiederherstellung |
|—————–|———–|—————|———-|
| Level 0 (offen) | Keiner | Nichts | N/A |
| Level 1 (Flash gesperrt) | APPROTECT-Register | SWD-Lesen/Schreiben von Flash/RAM | Voll-Loeschen zum Entsperren |
| Level 2 (permanent) | Fuse/OTP-Bit | Alle Debug-Zugriffe, permanent | Keine — irreversibel |

Fuer nRF52 aktiviert `UICR.APPROTECT = 0xFFFFFF00` Level 1. Die Debug-Sonde kann verbinden, aber Flash nicht lesen — nur Voll-Loeschen. Level 2 ist auf einigen SoCs verfuegbar (ESP32-C3 efuse brennen, STM32 RDP Level 2) und deaktiviert Debug-Zugriff permanent.

### 8.2 Secure Debug (authentifiziertes Debuggen)

Einige SoCs (nRF5340, CC2640R2 mit Secure Bootloader) unterstuetzen authentifiziertes Debuggen, bei dem die Debug-Sonde eine kryptografische Challenge-Response praesentieren muss:

„`c
// nRF5340 Network Core: Secure-Debug-Challenge
typedef struct {
uint8_t challenge[16]; // Zufaellige Nonce vom Target
uint8_t signature[64]; // ECDSA-P256-Signatur vom Debug-Zertifikat
uint32_t cert_id; // Welches Debug-Zertifikat verwenden
} secure_debug_auth_t;
„`

Dies ermoeglicht Debug-Zugriff im Feld (fuer autorisiertes Servicepersonal), ohne die Modulsicherheit permanent zu kompromittieren.

### 8.3 Produktions-Debug-Strategie

| Phase | APPROTECT | UART-Konsole | Debug-GPIOs | DTM |
|——|———–|————-|————-|—–|
| Bring-up (EVT) | Off | On, 460800 | Alle bestueckt | Ueber SWD |
| Verifizierung (DVT) | Off | On, 115200 | Alle bestueckt | Ueber SWD |
| Pilot (PVT) | Level 1 | On, 115200 (Pruefpad) | Nur 2 Signal-Pads | Ueber Fixture |
| Massenproduktion | Level 1 | Off (Pruefpad fuer Fehler) | Keine | Nur Fixture |
| Feld-Rueckgabe | Level 1 | Rework zum Aktivieren | Rework | Rework |

Schlussprinzip: Jede nicht in der Produktion benoetigte Schnittstelle sollte entweder unbestueckt (Header), deaktiviert (UART via Kompilier-Flag) oder geschuetzt (SWD via APPROTECT) sein.

## 9. Haeufige Debug-Architekturfehler

| Fehler | Auswirkung | Korrektur |
|———|——–|—–|
| Kein SWD-Pull-up auf SWDIO | Intermittierende Sondenverbindung, zufaelliges „DP read failed“ | Externen 4,7-10 kΩ Pull-up hinzufuegen |
| UART TX auf gleichem Pin wie BLE-Stack-DCX | Verkorrupte Radio-Konfiguration, zufaellige Verbindungsabbrueche | UART auf sicheren Pin verschieben |
| RTT-Puffer in nicht-retained RAM | RTT-Daten nach Sleep/Wake verloren | RTT-Puffer in Retained-RAM-Abschnitt |
| printf in Radio-ISR | 2+ ms ISR-Latenz, Paketverlust | RTT verwenden oder auf Idle-Task verschieben |
| Kein Crash-Dump in Retained RAM | Keine Diagnosedaten nach Reset | Crash-Dump aus Abschnitt 7.1 implementieren |
| Debug-GPIOs in Produktion aktiv | Zusaetzlicher Strom, 50-200 uA pro floatendem Eingang | In Produktions-Build als Pull-Down-Eingang konfigurieren |
| DTM nicht ohne vollstaendiges Firmware-Flash zugaenglich | RF-Test ohne App-Loeschung nicht moeglich | Bootloader prueft DTM-Pin-Strap beim Boot |
| APPROTECT in Versand-Firmware nicht gesetzt | Firmware mit 10-Dollar-Sonde extrahierbar | UICR.APPROTECT im Produktions-Flash-Skript setzen |
| UART-Baud zu hoch fuer BLE-Stack | Zeichenverlust waehrend Verbindungsereignissen | DMA-TX verwenden oder auf 115200 mit 16-Byte-FIFO beschraenken |
| Keine Watchdog-Vorwarnung-ISR | WDT-Timeouts nicht diagnostizierbar | WDT-Fruehwarn-Interrupt 500ms vor Reset aktivieren |

## 10. Debug-Schnittstellen-Checkliste fuer neues Moduldesign

Bevor Sie ein BLE-Modul-PCB fertigen, verifizieren Sie:

– [ ] SWD-Pads (SWDIO, SWCLK, nRESET, VDD, GND) als 0,05″-Mikro-Header oder Pruefpads zugaenglich
– [ ] SWDIO hat 4,7-10 kΩ externen Pull-up (nicht auf internen vertrauen)
– [ ] UART TX/RX auf sicheren Pins (kein Konflikt mit Kristall, NFC, BLE-Stack)
– [ ] UART DMA-TX konfiguriert, Ringpuffer RX
– [ ] Kompilierzeit-Log-Level-Flags (DBG_ERROR/WARN/INFO/DEBUG/VERBOSE)
– [ ] 2-4 Debug-GPIOs zugewiesen, via Kompilier-Flag konfigurierbar
– [ ] HardFault-Handler gibt gestapelte Register auf Retained RAM + UART aus
– [ ] Crash-Dump-Magic-Number in Retained RAM, Bootloader prueft beim Boot
– [ ] Flash-Crash-Log (zirkulaer, 10-20 Eintraege)
– [ ] Watchdog-Vorwarnung-ISR mit Stack-Snapshot
– [ ] DTM ueber 2-Draht-UART zugaenglich (Pruefpads in Produktion)
– [ ] RF-Testpad oder U.FL-Stecker fuer leitungsgebundene DTM-Tests
– [ ] APPROTECT-Einstellung im Produktions-Flash-Skript
– [ ] Produktions-Firmware kompiliert nur mit DBG_INFO (kein DEBUG/VERBOSE)
– [ ] Debug-GPIOs als Pull-Down-Eingang in Produktions-Build konfiguriert

## Zusammenfassung

Debug-Schnittstellen-Design ist kein Nachgedanke — es ist eine erstklassige Engineering-Disziplin, die bestimmt, wie schnell Sie Feldfehler diagnostizieren, Zertifizierungen bestehen und Firmware iterieren koennen. Die Investition ist bescheiden: 2-4 zusaetzliche GPIOs, eine 5-Pad-SWD-Flaeche, ein Retained-RAM-Crash-Dump-Handler und ein DTM-Boot-Modus. Die Rendkehr misst sich in Wochen, die beim Bring-up gespart werden, und Tausenden von Dollar, die durch Vermeidung von Feldrueckgabe-Raterei gespart werden. Bei Ihrem naechsten Bluetooth-Modul-Design sollten Sie diese Schnittstellen ab dem Schaltplan-Review budgetieren, nicht ab dem ersten Fehlerbericht.