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.
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:
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:
- 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
Noch keine Kommentare.