Lorsqu’un module Bluetooth perd des connexions sur le terrain, consomme 3 mA au-dessus des specs en veille, ou echoue la certification sur le 2eme canal du balayage DTM a 40 canaux, la difference entre une reparation d’un jour et une impasse de deux semaines depend de si vous avez correctement instrumente le module pendant le developpement. Cet article couvre les interfaces de debogage physiques, les methodes de tracage en temps reel, les voies de verification RF et les outils post-mortem qui devraient etre concus des le premier jour du schema — pas ajoutes apres la premiere panne sur le terrain.

## 1. Panorama des Interfaces de Debogage : JTAG vs SWD vs cJTAG

La plupart des SoC BLE modernes (nRF52/53, CC2640, ESP32-C3/H2, DA1469x, BGMxx) exposent soit un JTAG complet a 5 broches (TCK, TMS, TDI, TDO, nTRST) ou le SWD a 2 broches specifique ARM (SWCLK, SWDIO) plus nRESET. Le tableau ci-dessous resume les compromis pour la conception de modules BLE :

| Parametre | JTAG (5 broches) | SWD (2 broches + RESET) | cJTAG (2 broches) |
|———–|————-|———————|—————-|
| Nombre de broches | 5 (ou 4 sans nTRST) | 2-3 | 2 |
| Horloge max | 10-50 MHz | 1-50 MHz | jusqu’a 50 MHz |
| Support trace | ETM (bus trace 4 broches) | ITM (SWO, 1 broche) | ITM (SWO) |
| Vitesse download flash (256 KB) | ~8-12 s | ~6-10 s | ~6-10 s |
| Limite longueur fil | ~15 cm (sans tampon) | ~30 cm (sans tampon) | ~20 cm |
| Support SoC | Universel (ARM + RISC-V) | ARM Cortex-M seulement | ARM Cortex-M33/55 |
| Courant typique (debug actif) | 2-5 mA | 1-3 mA | 1-3 mA |

Pour les modules BLE ou la surface PCB se mesure en millimetres carres, SWD est le choix par defaut. La serie nRF52/53 permet meme SWD sur les memes broches que GPIO P0.00/P0.01 pendant le developpement. On les route vers un micro-connecteur au pas de 0,05 pouce (Samtec FTSH-105 ou equivalent) et on le peuple pour le developpement ou on le laisse comme pastilles PCB nues pour la production. L’approche pastilles-seules est preferable car un connecteur peuple sur un module de production invite un acces non autorise.

### Considerations d’Integrite de Signal SWD

SWDIO est bidirectionnel et open-drain avec pull-up (typiquement 10 kΩ interne, 4,7 kΩ externe). La valeur du pull-up importe plus que la plupart des ingenieurs ne le pensent :

| Pull-up | Temps de montee SWDIO (tr) | SWCLK max | Notes |
|———|———————|———–|——-|
| 100 kΩ | 220 ns | 1 MHz | Marginal — perte de synchro occasionnelle |
| 47 kΩ | 104 ns | 4 MHz | OK pour fils courts (<15 cm) | | 10 kΩ | 22 ns | 25 MHz | Fiable pour la plupart des configurations | | 4,7 kΩ | 10 ns | 50 MHz | Prefere pour J-Link a haute vitesse | | 1 kΩ | 2,2 ns | >50 MHz | Excessif, gaspille 3,3 mA a l’etat bas |

La formule est simplement un retard RC : tr ≈ 2.2 × R × C, ou C est la capacite totale trace + sonde (typiquement 10-20 pF sur un module avec un cable ruban de 15 cm). Si vous voyez des erreurs intermitentes « SWD DP read failed » sur votre J-Link, la premiere chose a verifier est si le pull-up externe est absent et le 10 kΩ interne lutte contre un long cable.

## 2. Console de Debogage UART : Conception pour le Debogage Reel

Une console de debogage UART est l’interface de debogage la plus precieuse en firmware de production, mais elle est systematiquement mal implantee. Les erreurs courantes :

1. **Debit baud trop eleve pour la priorite de la pile BLE.** A 1 Mbps UART avec FIFO de 16 octets, l’interruption se declenche toutes les 128 μs. Si la pile BLE maintient les interruptions pendant 150 μs lors de la preparation d’evenement de connexion, des caracteres sont perdus. Solution : utiliser 460800 bps ou 921600 bps avec DMA TX et tampon circulaire pour RX.

2. **printf bloquant la boucle principale.** Un `printf` bloquant qui ecrit 200 octets a 115200 bps prend 17,4 ms — plus long qu’un intervalle de connexion BLE de 7,5 ms. Utilisez un tampon circulaire sans verrou avec vidange DMA en idle :

« `c
// Tampon circulaire UART sans verrou (producteur unique, consommateur unique)
#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; // tampon plein, jeter caractere dbg_buf[dbg_head] = tmp[i]; dbg_head = next; } // Declencher vidange DMA si TX idle if (!(UART0->STAT & UART_STAT_TXBUSY)) {
uart_dma_flush();
}
}
« `

3. **Pas de filtrage de niveau de log.** Un module de production emettant des logs de niveau VERBOSE a 460800 bps pendant un evenement de connexion causera de la gigue de temporisation. Implementez un filtrage a la compilation et a l’execution :

| Niveau | Flag compilation | Runtime | Utilisation typique |
|——-|————-|———|————-|
| ERROR | `DBG_ERROR` | Toujours actif | Hard faults, echecs d’assertion |
| WARN | `DBG_WARN` | Toujours actif | Retentatives, performance degradee |
| INFO | `DBG_INFO` | Configurable | Connexion/deconnexion, changements d’etat |
| DEBUG | `DBG_DEBUG` | Off en production | Timing par evenement, dumps de paquets |
| VERBOSE | `DBG_VERBOSE` | Off en production | Planification par slot, RSSI par evenement |

4. **Pas de capacite de dump de crash binaire.** Quand le module a un hard fault, UART est votre seule bouee de sauvetage. Pre-allouez un gestionnaire de dump de crash de 1 KB qui dumpe les registres empiles (R0-R3, R12, LR, PC, xPSR) et les 16 premiers mots de la pile avant le reset du 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); // Attendre watchdog } ``` ### Selection de Broches UART sur Modules BLE Evitez P0.00/P0.01 (reservees pour SWD ou cristal 32 kHz), P0.02/P0.03 (souvent ADC ou analogique), et toute broche utilisee par la pile BLE pour le timing radio. Broches UART sures sur SoC courants : | SoC | TX sur | RX sur | Eviter | |-----|---------|---------|-------| | 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. Tracage en Temps Reel : RTT vs ITM/SWO vs ETM Le debogage UART base sur printf convient pour les evenements basse frequence, mais l'analyse de timing de pile BLE necessite une resolution sub-microseconde. Trois options existent, chacune avec des compromis differents : ### Segger RTT (Real-Time Transfer) RTT utilise un tampon circulaire en RAM cible que le debogueur interroge via SWD a haute vitesse. Il requiert zero temps CPU cible par entree de log (le debogueur lit la RAM directement), ce qui le rend ideal pour le code sensible au timing : | Metrique | UART @ 460800 | RTT | ITM/SWO @ 2 MHz | |--------|---------------|-----|-----------------| | Temps CPU par log 100 caracteres | ~2,2 ms | ~5 us | ~50 us | | Debit | 46 KB/s | ~500 KB/s | ~200 KB/s | | Latence (log → debogueur) | 2,2 ms | ~10 us | ~25 us | | Broches requises | 2 (TX/RX) | 0 (utilise SWD) | 1 (SWO) + SWD | | Tampon en RAM | 0 | 1-4 KB | 0 (FIFO materiel) | | Support debogueur | Quelconque terminal | J-Link seulement | J-Link, ST-Link, CMSIS-DAP | L'avantage principal de RTT est qu'il fonctionne via l'interface SWD existante sans broches supplementaires. Sa principale limitation est qu'il necessite un Segger J-Link. Pour le developpement, c'est acceptable ; pour le debogage sur le terrain, vous n'avez probablement pas de J-Link. RTT supporte egalement la communication bidirectionnelle — le debogueur peut injecter des commandes dans la cible sans utiliser de broche 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();
}
}
}
« `

### Tracage ITM/SWO

ITM (Instrumentation Trace Macrocell) est une fonctionnalite ARM Cortex-M3/4/7/33 qui fournit 32 ports de stimulus pour le tracage au niveau application, plus l’horodatage et le tracage d’exceptions. La broche SWO (Serial Wire Output) transporte les donnees ITM comme UART a un fil jusqu’a la vitesse d’horloge CPU :

« `c
// Port de stimulus ITM 0 pour messages de debogage
#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); // attendre port pret
ITM_Port8(0) = *s++;
}
}
« `

SWO peut etre configure dans deux modes :

| Mode | Baud SWO | Source horloge | Avantages | Inconvenients |
|——|———|————-|——|——|
| Mode UART | 2-50 MHz | HCLK / prescaler | Fonctionne avec toute sonde SWO | Baud doit correspondre exactement |
| Mode Manchester | Jusqu’a horloge CPU | HCLK direct | Auto-horloge, pas de correspondence baud | J-Link seulement, pas ST-Link |

Pour l’analyse de timing BLE, ITM excelle dans l’enregistrement d’horodatages par evenement. Le materiel ITM horodate chaque ecriture avec un compteur a resolution 1 cycle, donc vous pouvez mesurer le timing des evenements de connexion sans aucun surcout CPU :

« `c
// Enregistrer timing d’evenement de connexion sur port 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 ou SystemView peut afficher ces evenements sur une chronologie avec des horodatages precis a la nanoseconde.

### ETM (Embedded Trace Macrocell)

ETM fournit un tracage complet au niveau instruction via un bus de trace parallele 4 bits. Il est disponible sur Cortex-M7 (et certains M4) mais necessite 4-7 broches supplementaires. Pour le travail sur modules BLE, ETM est rarement justifie — le cout en broches est trop eleve et le tracage au niveau instruction produit trop de donnees pour etre utile au debogage au niveau protocole.

## 4. Techniques d’Analyseur Logique pour le Timing BLE

Un analyseur logique est indispensable pour deboguer des problemes de timing BLE invisibles a l’instrumentation basee sur logiciel. Les cas d’usage cles :

### 4.1 Verification d’Evenements de Pile BLE

La plupart des piles BLE exposent un GPIO « evenement radio » ou « comparateur timer » qui bascule au debut et a la fin de chaque activite radio. Sur nRF52, c’est `RADIO_SHORTS` ou `TIMER0` compare ; sur ESP32, le signal d’evenement `BT_CONTROLLER`. Configurer un GPIO de debogage pour basculer aux evenements radio permet de mesurer :

| Mesure | Methode | Ce que cela revele |
|————-|——–|—————–|
| Gigue de debut d’evenement de connexion | Mesurer offset radio-GPIO vers GPIO-PPS | Precision du cristal, derive du timer de veille |
| Duree d’evenement de connexion | Largeur d’impulsion du radio-GPIO | Mismatch taille payload vs intervalle |
| Timing de fenetre de scan | Largeur d’impulsion du scan-GPIO | Scan reel vs scan configure |
| Precision d’intervalle d’advertising | Mesure de periode | Derive, correction de randomisation |
| Intervalle entre evenements | Temps entre front descendant et prochain front montant | Overhead de pile, temps de traitement |

### 4.2 Decodage de Protocole avec Sniffing SWIRE/HCI

La plupart des modules BLE routent le trafic HCI entre host et controlleur en interne, mais certains l’exposent sur une interface UART ou SPI. Sniffer ce trafic avec un decodeur de protocole d’analyseur logique est le moyen le plus rapide de deboguer les problemes d’interaction host-controlleur :

– **UART HCI** : Saleae Logic 2 inclut un decodeur HCI UART qui analyse les commandes completes, statut de commande, donnees ACL et evenements.
– **SPI HCI** : Certains modules (CC26xx avec host externe) utilisent SPI 4 fils pour HCI.
– **Proprietaire** : SWIRE proprietaire de Nordic est un protocole bidirectionnel a un fil.

### 4.3 Profilage de Consommation avec Analyseur Logique + Oscilloscope

Le scenario de debogage BLE le plus courant : le module consomme plus de courant que prevu. Connectez un analyseur logique aux GPIO cles alongside d’une mesure de courant (resistance shunt + oscilloscope ou Power Profiler Kit) pour correlater les evenements logiciel avec les pics de courant :

| Signal GPIO | Ce a quoi chercher dans le profil de courant |
|————-|————————————-|
| Radio actif | Pic de 4-15 mA, devrait etre 1-5 ms |
| CPU actif | 2-8 mA, devrait descendre a <10 uA entre evenements | | Effacement/ecriture flash | Pic de 8-15 mA durant 20-50 ms par page | | UART TX | 1-3 mA pendant la duree de transmission | | Echantillon ADC | 0,5-1,5 mA, pics courts au taux d'echantillonnage | | Lecture capteur externe (I2C/SPI) | 1-5 mA selon le capteur | Une decouverte frequente : le module `app_timer` de la pile BLE sur nRF52 declenche un timer logiciel 200 us avant l'evenement radio, reveillant le CPU pendant 1,5 ms pour la preparation. Si l'application a aussi un timer programme en meme temps, le CPU reste reveille plus longtemps, ajoutant 2-4 mA de courant moyen. ## 5. Debogage RF : Direct Test Mode (DTM) DTM est la methode standardisee (BT 4.2+ Vol 6, Part F) pour tester la radio BLE sans passer par la pile complete. Il permet de : 1. Transmettre une porteuse constante (CW) a une frequence et puissance specifiques 2. Transmettre un signal module avec payload PRBS9/PRBS15 3. Recevoir et compter des paquets avec des parametres configurables 4. Mesurer le taux d'erreur de paquet (PER) vs RSSI ### Methodes d'Acces DTM | Methode | Interface | Commandes | Utilisation typique | |--------|-----------|----------|-------------| | UART 2 fils | Broches RX/TX | HCI specifique constructeur | Test production, certification | | UART 3 fils | RX/TX/RTS | Identique a 2 fils | Controle de flux pour tests haut debit | | HCI sur USB | USB | Commandes HCI | Test dongle USB | | Proprietaire constructeur | SWD/JTAG | Specifique SoC | Debug niveau SoC (sans firmware) | ### Structure de Commande DTM (UART 2 fils) DTM utilise un mot de commande 16 bits simple a 19200 bps (8N1) : | Bit | Champ | Valeur | Description | |-----|-------|-------|-------------| | 15 | Type | 0 | Type de paquet | | 14-6 | Longueur | 0-37 | Nombre d'octets dans le paquet (RX) ou longueur a TX | | 5-2 | Canal RF | 0-39 | Canal BLE 0-39 (2402-2480 MHz) | | 1-0 | Type test | 0-3 | 0=PRBS9 TX, 1=PRBS15 TX, 2=PRBS9 RX, 3=CW TX | Exemple : transmettre PRBS9 sur canal 19 (2440 MHz), 32 octets : - Mot de commande = 0b0_00001000_010011_00 = 0x044C - Envoyer comme 2 octets : 0x4C, 0x04 (little-endian) ```c // Sequence de test DTM pour verification RF void dtm_verify_rf(void) { // 1. TX PRBS9 sur canal 19, 32 octets dtm_send(0x044C); delay_ms(100); dtm_send(0x0000); // Terminer test, lire evenement // 2. Test RX sur 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 pour Pre-conformite de Certification Avant d'envoyer un module a un laboratoire de certification, verifiez que les tests DTM suivants passent : | Test | Commande DTM | Critere de reussite | Equipement necessaire | |------|------------|---------------|------------------| | Puissance TX (40 ch) | CW TX par canal | ±2 dB de la spec | Analyseur de spectre ou wattmetre | | Caracteristiques de modulation | PRBS15 TX | Δf1avg = 225-275 kHz, Δf2avg/Δf1avg ≥ 0.8 | Analyseur de spectre + firmware | | Offset frequence porteuse | CW TX | ±50 kHz du nominal | Analyseur de spectre (mode compteur) | | Emissions dans la bande | PRBS9 TX, 1 ch | < -20 dBm au canal adjacent | Analyseur de spectre | | Largeur de bande 20 dB | PRBS15 TX | < 2,0 MHz | Analyseur de spectre (RBW 100 kHz) | | Sensibilite PER | Test RX | < 30,8% PER a -93 dBm (LE 1M) | Generateur de signal + DTM RX | | PER entree maximale | Test RX | < 30,8% PER a -20 dBm | Generateur de signal + DTM RX | | Rejection co-canal | RX + interferent | < 30,8% PER avec desire/interferent = +3 dB | 2 generateurs de signal | ## 6. Strategie GPIO de Debogage : du Developpement a la Production Un module BLE bien concu devrait allouer 2-4 GPIO specifiquement pour le debogage, avec leur fonction changeant entre builds de developpement et de production : ### Exemple d'Allocation GPIO de Debogage (module nRF52832) | GPIO | Fonction developpement | Fonction production | Notes | |------|---------------------|--------------------|----| | P0.31 | Basculement evenement radio | Inutilise (entree, pull-down) | Bascule au debut/fin radio | | P0.30 | Basculement evenement timer | Inutilise (entree, pull-down) | Bascule au declenchement app timer | | P0.29 | Etat machine d'etats BLE | Inutilise (entree, pull-down) | Code etat 3 bits (2 GPIOs) | | P0.28 | Etat machine d'etats BLE | Inutilise (entree, pull-down) | Code etat 3 bits (2 GPIOs) | Les GPIO de machine d'etats codent l'etat BLE actuel comme valeur binaire : | Code etat | Signification | Duree typique | |-----------|---------|-----------------| | 000 | IDLE/veille | 90-99% du temps | | 001 | Prep advertising | 50-100 us | | 010 | TX advertising | 80-376 us | | 011 | RX advertising (reponse scan) | 100-200 us | | 100 | Prep connexion | 100-200 us | | 101 | TX evenement connexion | 80-200 us | | 110 | RX evenement connexion | 100-300 us | | 111 | Flash/traitement | Variable | Cela vous donne une vue en temps reel de la machine d'etats sur un analyseur logique sans surcout logiciel — les ecritures GPIO se font en contexte d'interruption et prennent 2-3 cycles chacune. ### Strapping de Broches de Debogage en Production En production, on ne peut souvent pas se permettre des connecteurs de debogage peuples. Une strategie courante consiste a utiliser des pastilles de test accessibles via fixture a broches pogo : | Pastille | Signal | Diametre broche pogo | Notes | |-----|--------|-------------------|-------| | 1 | SWDIO | 0,68 mm | Pas 0,05", motif 2x5 | | 2 | SWCLK | 0,68 mm | | | 3 | GND | 0,68 mm | 2x pastilles GND | | 4 | VDD | 0,68 mm | Sens alimentation cible | | 5 | nRESET | 0,68 mm | Optionnel | | 6 | UART TX | 0,68 mm | Console production | | 7 | UART RX | 0,68 mm | Console production | | 8 | RF_OUT | 0,68 mm | Test conduit (sans antenne) | Pour les modules avec antenne integree, les tests RF necessitent soit un connecteur RF (U.FL ou similaire) pendant le developpement, soit un fixture de couplage (cellule TEM ou sonde de champ proche) en production. L'approche par couplage ajoute ±3-5 dB d'incertitude, acceptable pour les tests de production go/no-go mais pas pour la certification. ## 7. Dump de Crash et Analyse Post-Mortem Quand un module BLE plante sur le terrain, les interfaces de debogage discutees jusqu'ici sont indisponibles. Le module a besoin d'un mecanisme de dump de crash autonome qui survive a un reset : ### 7.1 Dump de Crash en RAM Retenue (sans reset) ARM Cortex-M retient la RAM a travers un reset logiciel (NVIC_SystemReset). En placant un nombre magique a une adresse RAM connue, le bootloader peut detecter un crash et dumper le contexte sauvegarde : ```c // Placer dans une section RAM connue qui survive au reset logiciel #define CRASH_MAGIC_ADDR 0x20007FF0 // Derniers 16 octets 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; // Dans le bootloader (avant l'app principale): 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; // Effacer pour ne pas re-dumper
}
« `

### 7.2 Journal de Crash Base sur Flash

Pour les modules qui peuvent perdre l’alimentation avant que le dump de crash ne soit recupere, stockez les donnees de crash dans une page flash dediee. Utilisez un journal circulaire avec une entree par crash :

| Champ | Taille | Description |
|——-|——|————-|
| Magic | 4 B | 0xDEAD5F70 |
| Cause reset | 4 B | Registre reset RCU |
| Registres empiles | 32 B | R0-R3, R12, LR, PC, xPSR |
| CFSR/HFSR/BFAR | 12 B | Registres de statut de faute |
| Uptime | 4 B | ms depuis demarrage |
| Handle connexion | 2 B | Handle actif (0xFFFF = aucun) |
| Etat BLE | 1 B | Etat au crash |
| Reserve | 1 B | Alignement |
| CRC16 | 2 B | Controle d’integrite |
| **Total** | **62 B** | Tient dans une unite d’ecriture flash |

Avec une page flash de 4 KB, vous pouvez stocker 65 entrees de crash. En pratique, 10-20 entrees suffisent.

### 7.3 Analyse de Timeout Watchdog

Le type de crash le plus frustrant : le watchdog se declenche mais il n’y a pas de HardFault, donc le dump de crash est vide. Pour diagnostiquer les timeouts watchdog :

1. **Instantane ISR timer** : Dans la fonction d’alimentation du watchdog, sauvegardez la pile d’appels actuelle (valeur LR) dans un emplacement RAM retenu.

2. **Journal de battement periodique** : Ecrivez un battement horodate sur flash toutes les 30 secondes.

3. **Pre-avertissement watchdog** : Configurez le watchdog pour declencher une interruption d’avertissement anticipe 500 ms avant le reset reel :

« `c
void WDT_IRQHandler(void) {
// Avertissement anticipe — 500ms avant 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. Securite de Debogage : Lock Bits, Debug Securise et Durcissement Production

Les interfaces de debogage sont un passif de securite. Un connecteur SWD peuple sur un module de production signifie que quiconque avec une sonde CMSIS-DAP a 10 $ peut lire votre firmware, extraire les cles et cloner votre module. Approche de defense en profondeur :

### 8.1 Niveaux de Lock Bit

| Niveau protection | Mecanisme | Ce qu’il bloque | Recuperation |
|—————–|———–|—————|———-|
| Niveau 0 (ouvert) | Aucun | Rien | N/A |
| Niveau 1 (flash verrouille) | Registre APPROTECT | Lecture/ecriture flash/RAM via SWD | Effacement complet pour deverrouiller |
| Niveau 2 (permanent) | Fuse/OTP bit | Tout acces debug, permanentement | Aucun — irreversible |

Pour nRF52, le registre `APPROTECT` dans `UICR.APPROTECT = 0xFFFFFF00` active le Niveau 1. La sonde de debug peut se connecter mais ne peut pas lire le flash — seul l’effacement complet est possible. Le Niveau 2 est disponible sur certains SoC (ESP32-C3 graver efuses, STM32 RDP Niveau 2) et desactive l’acces debug permanentement.

### 8.2 Debug Securise (Debug Authentifie)

Certains SoC (nRF5340, CC2640R2 avec bootloader securise) supportent le debug authentifie, ou la sonde doit presenter un challenge-response cryptographique :

« `c
// nRF5340 coeur reseau : challenge de debug securise
typedef struct {
uint8_t challenge[16]; // Nonce aleatoire de la cible
uint8_t signature[64]; // Signature ECDSA-P256 du certificat de debug
uint32_t cert_id; // Quel certificat de debug utiliser
} secure_debug_auth_t;
« `

Cela permet l’acces debug sur le terrain (pour le personnel de service autorise) sans compromettre permanentement la securite du module.

### 8.3 Strategie de Debug Production

| Phase | APPROTECT | Console UART | GPIOs debug | DTM |
|——|———–|————-|————-|—–|
| Bring-up (EVT) | Off | On, 460800 | Tous peuples | Via SWD |
| Verification (DVT) | Off | On, 115200 | Tous peuples | Via SWD |
| Pilote (PVT) | Niveau 1 | On, 115200 (pastille test) | 2 pastilles signal seulement | Via fixture |
| Production de masse | Niveau 1 | Off (pastille pour echecs) | Aucun | Fixture seulement |
| Retour terrain | Niveau 1 | Rework pour activer | Rework | Rework |

Principe cle : chaque interface non necessaire en production devrait etre soit depopulee (connecteurs), desactivee (UART via flag compilation), ou protegee (SWD via APPROTECT).

## 9. Erreurs Courantes d’Architecture de Debogage

| Erreur | Impact | Correction |
|———|——–|—–|
| Pas de pull-up SWD sur SWDIO | Connexion sonde intermitente, « DP read failed » aleatoire | Ajouter pull-up externe 4,7-10 kΩ |
| UART TX sur meme broche que DCX pile BLE | Config radio corrompue, deconnexions aleatoires | Deplacer UART vers broche sure |
| Tampon RTT en RAM non retenue | Donnees RTT perdues apres veille/reveil | Placer tampon RTT en section RAM retenue |
| printf dans ISR radio | Latence ISR 2+ ms, paquets perdus | Utiliser RTT ou differer vers tache idle |
| Pas de dump de crash en RAM retenue | Pas de donnees diagnostiques post-reset | Implementer dump de crash section 7.1 |
| GPIOs debug actifs en production | Courant supplementaire, 50-200 uA par entree flottante | Configurer en entree pull-down en build production |
| DTM non accessible sans flasher firmware complet | Ne peut pas tester RF sans effacer app | Bootloader verifie strap DTM au demarrage |
| APPROTECT non defini en firmware d’expedition | Firmware extractible avec sonde a 10 $ | Definir UICR.APPROTECT dans script flash production |
| Baud UART trop eleve pour pile BLE | Perte de caracteres pendant evenements connexion | Utiliser DMA TX ou limiter a 115200 avec FIFO 16 octets |
| Pas d’ISR de pre-avertissement watchdog | Timeouts WDT non diagnostiquables | Activer interruption d’avertissement anticipe 500ms avant reset |

## 10. Checklist d’Interfaces de Debogage pour Nouvelle Conception de Module

Avant de fabriquer un PCB de module BLE, verifiez :

– [ ] Pastilles SWD (SWDIO, SWCLK, nRESET, VDD, GND) accessibles comme micro-connecteur 0,05″ ou pastilles de test
– [ ] SWDIO a un pull-up externe 4,7-10 kΩ (ne pas dependre de l’interne)
– [ ] UART TX/RX sur broches sures (pas de conflit avec cristal, NFC, pile BLE)
– [ ] DMA TX UART configure, tampon circulaire RX
– [ ] Flags de niveau de log a la compilation (DBG_ERROR/WARN/INFO/DEBUG/VERBOSE)
– [ ] 2-4 GPIOs debug alloues, configurables via flag compilation
– [ ] Gestionnaire HardFault dumpe les registres empiles vers RAM retenue + UART
– [ ] Nombre magique de dump de crash en RAM retenue, bootloader verifie au demarrage
– [ ] Journal de crash flash (circulaire, 10-20 entrees)
– [ ] ISR de pre-avertissement watchdog avec instantane de pile
– [ ] DTM accessible via UART 2 fils (pastilles de test en production)
– [ ] Pastille RF ou connecteur U.FL pour tests DTM conduits
– [ ] Parametre APPROTECT dans script flash de production
– [ ] Firmware production compile avec DBG_INFO seulement (pas de DEBUG/VERBOSE)
– [ ] GPIOs debug configures en entree pull-down en build production

## Resume

La conception d’interfaces de debogage n’est pas une pensee apres coup — c’est une discipline d’ingenierie de premier ordre qui determine la vitesse a laquelle vous pouvez diagnostiquer les pannes terrain, reussir les certifications et iterer le firmware. L’investissement est modeste : 2-4 GPIO supplementaires, une empreinte SWD a 5 pastilles, un gestionnaire de dump de crash en RAM retenue et un mode de demarrage DTM. Le retour se mesure en semaines gagnees pendant le bring-up et en milliers de dollars economises en evitant les conjectures sur les retours terrain. Lors de votre prochaine conception de module Bluetooth, budgetez ces interfaces des la revue de schema, pas des le premier rapport de panne.