Konfiguracja CLI shell przez J-Link RTT dla ARM Cortex-M
Aby zaimplementować CLI przez SWD bez UART, użyj biblioteki SEGGER_RTT. Pobierz źródła: SEGGER_RTT.h (API, 253 linie), SEGGER_RTT.c (implementacja, 1751 linii), SEGGER_RTT_printf.c (printf, 516 linii), SEGGER_RTT_Conf.h (konfiguracja, 333 linie).
Zacznij od inicjalizacji zerowego kanału RTT:
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;
}
Wywołaj SeggerInit() przy starcie oprogramowania, aby skonfigurować bufory transmisji i odbioru bez blokowania.
Obsługa przychodzących poleceń
Okresowo odpytywaj kanał przez SEGGER_RTT_Read w głównej pętli lub timerze:
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;
}
Funkcja zwraca liczbę odebranych bajtów. Przekaż dane do handlera CLI: cli_process_data().
Wysyłanie odpowiedzi z oprogramowania
Do przesyłania ciągów użyj SEGGER_RTT_Write. Zaimplementuj funkcje dla putc/puts i bufora FIFO:
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;
}
}
Wyodrębnij dane z Tx FIFO i zapisz do kanału RTT. Zapewnia to asynchroniczne wysyłanie bez utraty danych.
- Zalety FIFO: Buforowanie zapobiega przepełnieniu przy szczytowych obciążeniach.
- Monitorowanie: Loguj
tx_cntdo debugowania pominięć. - Skalowanie: Obsługa wielu kanałów (num > 0).
Konfiguracja J-Link RTT Viewer na PC
Zainstaluj pakiet SEGGER J-Link. Uruchom JLinkRTTViewer.exe z C:\Program Files\SEGGER\JLink_V834.
Skonfiguruj połączenie:
- Wybierz SWD lub JTAG.
- Wskaż urządzenie docelowe (ARM Cortex-M).
- Ustaw prędkość (do megaherców).
- Potwierdź połączenie.
Wprowadzaj polecenia w Terminal 0 — obsługa kolorowego podświetlania. Przy przepełnieniu FIFO edytuj SEGGER_RTT_Conf.h, aby zwiększyć bufory.
Alternatywny dostęp przez TCP
RTT Viewer otwiera gniazdo na 127.0.0.1:19021 (sprawdź netstat -ano | grep 19021).
Połącz się PuTTY lub Tera Term:
- Host: 19021
- Typ: TCP
To emuluje terminal UART. Działa zdalnie w sieci WiFi.
Zalety i ograniczenia RTT CLI
Zalety:
- Równoległa praca z debugowaniem krok po kroku.
- Nie wymaga pliku ELF: wgraj oprogramowanie i przekaż J-Link.
- Natychmiastowa transmisja z prędkościami SWD.
- Copy-paste logów z podświetlaniem.
- Wiele terminali.
Wady:
- Zależność od J-Link (nie dla AVR/ESP32/RISC-V).
- Przerwanie przy resecie MCU — ręczne ponowne połączenie.
- Oddzielne okno wprowadzania (rozwiązane przez TCP).
- Brak obsługi \r w Viewer (jest w Tera Term).
| Aspekt | RTT przez SWD | UART |
|--------|-------------|------|
| Prędkość | MHz SWD | 115200+ |
| Piny | 3-4 | 2+ |
| Debugowanie | Równolegle | Nie |
| Reset | Przerwanie | Stabilnie |
Co jest ważne
- Zainicjalizuj RTT przed main() dla wczesnego logowania.
- Użyj NO_BLOCK_SKIP, aby uniknąć zawieszeń.
- Monitoruj przepełnienie FIFO przez logi tx/rx_cnt.
- TCP 19021 rozwiązuje problemy UI Viewer.
- Nadaje się dla Cortex-M z obsługą J-Link.
— Editorial Team
Brak komentarzy.