Configuración de una Shell CLI mediante J-Link RTT para ARM Cortex-M
Para implementar una CLI sobre SWD sin UART, utiliza la biblioteca SEGGER_RTT. Descarga los archivos fuente: SEGGER_RTT.h (API, 253 líneas), SEGGER_RTT.c (implementación, 1751 líneas), SEGGER_RTT_printf.c (printf, 516 líneas), SEGGER_RTT_Conf.h (configuración, 333 líneas).
Comienza inicializando el canal RTT cero:
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;
}
Llama a SeggerInit() al inicio del firmware para configurar los búferes de transmisión y recepción no bloqueantes.
Procesamiento de Comandos Entrantes
Consulta periódicamente el canal mediante SEGGER_RTT_Read en el bucle principal o un temporizador:
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 función devuelve el número de bytes recibidos. Pasa los datos al manejador CLI: cli_process_data().
Envío de Respuestas desde el Firmware
Para transmitir cadenas, usa SEGGER_RTT_Write. Implementa funciones para putc/puts y un búfer 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;
}
}
Extrae datos del FIFO Tx y escríbelos en el canal RTT. Esto asegura transmisión asíncrona sin pérdida de datos.
- Ventajas del FIFO: El almacenamiento en búfer evita desbordamientos durante picos de carga.
- Monitoreo: Registra
tx_cntpara depurar transmisiones perdidas. - Escalabilidad: Soporte para múltiples canales (num > 0).
Configuración de J-Link RTT Viewer en PC
Instala el paquete SEGGER J-Link. Ejecuta JLinkRTTViewer.exe desde C:\Program Files\SEGGER\JLink_V834.
Configura la conexión:
- Selecciona SWD o JTAG.
- Especifica el dispositivo objetivo (ARM Cortex-M).
- Establece la velocidad (hasta megahercios).
- Confirma la conexión.
Introduce comandos en Terminal 0 — soporta resaltado de colores. Si el FIFO se desborda, edita SEGGER_RTT_Conf.h para aumentar los tamaños de búfer.
Acceso Alternativo mediante TCP
RTT Viewer abre un socket en 127.0.0.1:19021 (verifica con netstat -ano | grep 19021).
Conéctate usando PuTTY o Tera Term:
- Host: 19021
- Tipo: TCP
Esto emula una terminal UART. Funciona de forma remota a través de una red WiFi.
Ventajas y Limitaciones de la CLI RTT
Ventajas:
- Operación paralela con depuración paso a paso.
- No requiere archivo ELF: flashea y pasa a J-Link.
- Transmisión instantánea a velocidades SWD.
- Copia y pega registros con resaltado.
- Múltiples terminales.
Desventajas:
- Dependencia de J-Link (no para AVR/ESP32/RISC-V).
- Desconexión al reiniciar el MCU — requiere reconexión manual.
- Ventana de entrada separada (resuelto mediante TCP).
- Sin soporte para \r en Viewer (disponible en Tera Term).
| Aspecto | RTT vía SWD | UART |
|--------|-------------|------|
| Velocidad | MHz SWD | 115200+ |
| Pines | 3-4 | 2+ |
| Depuración | Paralela | No |
| Reinicio | Desconexión | Estable |
Puntos Clave
- Inicializa RTT antes de main() para registro temprano.
- Usa NO_BLOCK_SKIP para evitar bloqueos.
- Monitorea desbordamiento FIFO mediante registros tx/rx_cnt.
- TCP 19021 resuelve problemas del Viewer de interfaz.
- Adecuado para Cortex-M con soporte J-Link.
— Editorial Team
Aún no hay comentarios.