Zurück zur Startseite

RTT CLI für Cortex-M über J-Link SWD

Der Artikel beschreibt die Integration der CLI-Shell über J-Link RTT auf ARM Cortex-M. Initialisierungscode, Befehlsverarbeitung und Antwortversand werden bereitgestellt. Viewer-Einrichtung, TCP-Zugriff und Vergleich mit UART werden erörtert.

CLI über RTT: SWD-Shell für ARM ohne UART
Advertisement 728x90

Einrichten einer CLI-Shell über J-Link RTT für ARM Cortex-M

Um eine CLI über SWD ohne UART zu implementieren, verwenden Sie die SEGGER_RTT-Bibliothek. Laden Sie die Quelldateien herunter: SEGGER_RTT.h (API, 253 Zeilen), SEGGER_RTT.c (Implementierung, 1751 Zeilen), SEGGER_RTT_printf.c (printf, 516 Zeilen), SEGGER_RTT_Conf.h (Konfiguration, 333 Zeilen).

Beginnen Sie mit der Initialisierung des Null-RTT-Kanals:

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;
}

Rufen Sie SeggerInit() beim Firmware-Start auf, um nicht-blockierende Sende- und Empfangspuffer zu konfigurieren.

Google AdInline article slot

Verarbeitung eingehender Befehle

Rufen Sie den Kanal regelmäßig über SEGGER_RTT_Read in der Hauptschleife oder einem Timer ab:

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;
}

Die Funktion gibt die Anzahl der empfangenen Bytes zurück. Übergeben Sie die Daten an den CLI-Handler: cli_process_data().

Senden von Antworten aus der Firmware

Zum Übertragen von Zeichenketten verwenden Sie SEGGER_RTT_Write. Implementieren Sie Funktionen für putc/puts und einen FIFO-Puffer:

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;
    }
}

Extrahieren Sie Daten aus dem Tx-FIFO und schreiben Sie sie in den RTT-Kanal. Dies gewährleistet asynchrone Übertragung ohne Datenverlust.

  • FIFO-Vorteile: Pufferung verhindert Überlauf bei Spitzenlast.
  • Überwachung: Protokollieren Sie tx_cnt, um fehlgeschlagene Übertragungen zu debuggen.
  • Skalierung: Unterstützung für mehrere Kanäle (num > 0).

Konfiguration von J-Link RTT Viewer auf dem PC

Installieren Sie das SEGGER J-Link-Paket. Führen Sie JLinkRTTViewer.exe aus C:\Programme\SEGGER\JLink_V834 aus.

Konfigurieren Sie die Verbindung:

Google AdInline article slot
  • Wählen Sie SWD oder JTAG.
  • Geben Sie das Zielgerät an (ARM Cortex-M).
  • Stellen Sie die Geschwindigkeit ein (bis zu Megahertz).
  • Bestätigen Sie die Verbindung.

Geben Sie Befehle in Terminal 0 ein – unterstützt Farbhervorhebung. Bei FIFO-Überlauf bearbeiten Sie SEGGER_RTT_Conf.h, um die Puffergrößen zu erhöhen.

Alternativer Zugriff über TCP

RTT Viewer öffnet einen Socket auf 127.0.0.1:19021 (überprüfen mit netstat -ano | grep 19021).

Verbinden Sie sich mit PuTTY oder Tera Term:

  • Host: 19021
  • Typ: TCP

Dies emuliert ein UART-Terminal. Funktioniert remote über ein WLAN-Netzwerk.

Vorteile und Einschränkungen von RTT CLI

Vorteile:

  • Paralleler Betrieb mit schrittweisem Debugging.
  • Keine ELF-Datei erforderlich: flashen und an J-Link übergeben.
  • Sofortige Übertragung bei SWD-Geschwindigkeiten.
  • Kopieren-Einfügen von Protokollen mit Hervorhebung.
  • Mehrere Terminals.

Nachteile:

  • Abhängigkeit von J-Link (nicht für AVR/ESP32/RISC-V).
  • Trennung bei MCU-Reset – erfordert manuelle Wiederverbindung.
  • Separates Eingabefenster (gelöst über TCP).
  • Keine Unterstützung für \r im Viewer (verfügbar in Tera Term).

| Aspekt | RTT über SWD | UART |

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

| Geschwindigkeit | MHz SWD | 115200+ |

| Pins | 3-4 | 2+ |

| Debugging | Parallel | Nein |

| Reset | Trennung | Stabil |

Wichtige Punkte

  • Initialisieren Sie RTT vor main() für frühe Protokollierung.
  • Verwenden Sie NO_BLOCK_SKIP, um Hänger zu vermeiden.
  • Überwachen Sie FIFO-Überlauf über tx/rx_cnt-Protokolle.
  • TCP 19021 löst UI-Viewer-Probleme.
  • Geeignet für Cortex-M mit J-Link-Unterstützung.

— Editorial Team

Advertisement 728x90

Weiterlesen