Retour à l'accueil

RTT CLI pour Cortex-M via J-Link SWD

L'article décrit l'intégration d'un shell CLI via J-Link RTT sur ARM Cortex-M. Le code d'initialisation, le traitement des commandes et l'envoi des réponses sont fournis. Configuration du Viewer, accès TCP et comparaison avec UART sont discutés.

CLI via RTT : shell SWD pour ARM sans UART
Advertisement 728x90

Configuration d'un shell CLI via J-Link RTT pour ARM Cortex-M

Pour implémenter un CLI via SWD sans UART, utilisez la bibliothèque SEGGER_RTT. Téléchargez les fichiers sources : SEGGER_RTT.h (API, 253 lignes), SEGGER_RTT.c (implémentation, 1751 lignes), SEGGER_RTT_printf.c (printf, 516 lignes), SEGGER_RTT_Conf.h (configuration, 333 lignes).

Commencez par initialiser le canal RTT zéro :

void SeggerInit() {
    SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
    SEGGER_RTT_ConfigDownBuffer(0, "RTTDOWN", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);    
    SEGGER_RTT_SetTerminal(0); 
}

bool segger_rtt_init_custom(void) {
    bool res = true;
    SeggerInit();
    return res;
}

Appelez SeggerInit() au démarrage du firmware pour configurer les tampons de transmission et de réception non bloquants.

Google AdInline article slot

Traitement des commandes entrantes

Interrogez périodiquement le canal via SEGGER_RTT_Read dans la boucle principale ou un timer :

bool segger_rtt_proc_one(uint8_t num) {
    bool res = false;
    LOG_PARN(SEGGER_RTT, "RTT%u,Proc", num);
    SeggerRttHandle_t* Node = SeggerRttGetNode(num);
    if(Node) {
        if(Node->RxBuffer) {
            if(Node->buffer_size) {
                unsigned rx_byte = SEGGER_RTT_Read(Node->BufferIndex, 
                                                   Node->RxBuffer, 
                                                   Node->buffer_size);
                if(rx_byte) {
                    res = segger_rtt_writer(num);
                    LOG_DEBUG(SEGGER_RTT,"RxData:[%s]=[%s],rxByteCnt:%u Bytes", 
                              ArrayToStr(Node->RxBuffer,rx_byte), 
                              ArrayToAsciiStr(Node->RxBuffer,rx_byte), 
                              rx_byte);
                    res = cli_process_data(Node->cli_num, 
                                           Node->RxBuffer, 
                                           rx_byte);
                    memset(Node->RxBuffer, 0, rx_byte);
                }
            }
        }
    }
    return res;
}

La fonction retourne le nombre d'octets reçus. Transmettez les données au gestionnaire CLI : cli_process_data().

Envoi des réponses depuis le firmware

Pour transmettre des chaînes, utilisez SEGGER_RTT_Write. Implémentez des fonctions pour putc/puts et un tampon FIFO :

Google AdInline article slot
void segger_rtt1_puts(void* stream_ptr, const char* str, int32_t len) {
    SeggerRttHandle_t* Node = SeggerRttGetNode(1);
    if(Node) {
        if(str) {
            if(len) {
                unsigned tx_cnt = SEGGER_RTT_Write(Node->BufferIndex,
                                                   (void* )  str,
                                                   (unsigned) len);
                (void)tx_cnt;
            }
        }
    }
}

void segger_rtt1_putc(void* stream_ptr, char ch) {
    SeggerRttHandle_t* Node = SeggerRttGetNode(1);
    if(Node) {
        unsigned tx_cnt = SEGGER_RTT_Write(Node->BufferIndex,
                                           (void* )  &ch,
                                           (unsigned)  1);
        (void)tx_cnt;
    }
}

Extrayez les données de la FIFO Tx et écrivez-les dans le canal RTT. Cela garantit une transmission asynchrone sans perte de données.

  • Avantages de la FIFO : Le tampon évite le débordement pendant les pics de charge.
  • Surveillance : Enregistrez tx_cnt pour déboguer les transmissions manquées.
  • Évolutivité : Prise en charge de plusieurs canaux (num > 0).

Configuration de J-Link RTT Viewer sur PC

Installez le package SEGGER J-Link. Exécutez JLinkRTTViewer.exe depuis C:\Program Files\SEGGER\JLink_V834.

Configurez la connexion :

Google AdInline article slot
  • Sélectionnez SWD ou JTAG.
  • Spécifiez le périphérique cible (ARM Cortex-M).
  • Définissez la vitesse (jusqu'à mégahertz).
  • Confirmez la connexion.

Entrez les commandes dans Terminal 0 — prend en charge la coloration syntaxique. Si la FIFO déborde, modifiez SEGGER_RTT_Conf.h pour augmenter la taille des tampons.

Accès alternatif via TCP

RTT Viewer ouvre un socket sur 127.0.0.1:19021 (vérifiez avec netstat -ano | grep 19021).

Connectez-vous avec PuTTY ou Tera Term :

  • Hôte : 19021
  • Type : TCP

Cela émule un terminal UART. Fonctionne à distance via un réseau WiFi.

Avantages et limites du CLI RTT

Avantages :

  • Fonctionnement parallèle avec débogage pas à pas.
  • Aucun fichier ELF requis : flashez et passez à J-Link.
  • Transmission instantanée aux vitesses SWD.
  • Copier-coller des logs avec mise en évidence.
  • Terminaux multiples.

Inconvénients :

  • Dépendance à J-Link (non compatible AVR/ESP32/RISC-V).
  • Déconnexion lors de la réinitialisation du MCU — nécessite une reconnexion manuelle.
  • Fenêtre d'entrée séparée (résolu via TCP).
  • Pas de support pour \r dans Viewer (disponible dans Tera Term).

| Aspect | RTT via SWD | UART |

|--------|-------------|------|

| Vitesse | MHz SWD | 115200+ |

| Broches | 3-4 | 2+ |

| Débogage | Parallèle | Non |

| Réinitialisation | Déconnexion | Stable |

Points clés

  • Initialisez RTT avant main() pour les logs précoces.
  • Utilisez NO_BLOCK_SKIP pour éviter les blocages.
  • Surveillez le débordement FIFO via les logs tx/rx_cnt.
  • TCP 19021 résout les problèmes de l'interface Viewer.
  • Adapté pour Cortex-M avec support J-Link.

— Editorial Team

Advertisement 728x90

Lire ensuite