Powrót do strony głównej

RTT CLI dla Cortex-M przez J-Link SWD

Artykuł opisuje integrację shell CLI przez J-Link RTT na ARM Cortex-M. Podano kod inicjalizacji, obsługi poleceń i wysyłania odpowiedzi. Omówiono konfigurację Viewer, dostęp TCP i porównanie z UART.

CLI przez RTT: SWD shell dla ARM bez UART
Advertisement 728x90

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.

Google AdInline article slot

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:

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

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_cnt do 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:

Google AdInline article slot
  • 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

Advertisement 728x90

Czytaj dalej