When developing for embedded platforms, one of the first things I usually implement is a command-line-interface (CLI) which is invaluable for debugging. Traditionally, I use a UART, but when developing for STM32 targets using my favorite IDE (EmBitz), there’s another option that uses only the STLinkV2 debug probe and so doesn’t consume a UART (or require additional connections to the target). This option is EB monitor which uses the EMBitz GDB server replacement EBlink and works very well.
The documentation for EBmonitor is a bit thin, so here’s an example of how it is used:
#include <stdio.h>
// EBLink GDB Server supports console I/O via STLink debug interface
// so we don't have to use the UART for debugging. printf output
// is buffered until \r\n or fflush(stdout) and then displayed in EB monitor
// input is read from stdin (scanf, fgets, etc.)
void EBmonitor_buffer(FILE* , char*, uint16_t);
#define EBM_outLength 128 // EB Monitor is used for debugging
#define EBM_inLength 80
char EBM_out[EBM_outLength];
char EBM_in[EBM_inLength];
void cli_init() {
// Route console I/O over the STLink debug interface
EBmonitor_buffer(stdout, EBM_out, EBM_outLength);
EBmonitor_buffer(stdin, EBM_in, EBM_inLength);
}
void sample_fn_using_cli() {
printf("prompt>");
fflush(stdout); // don't wait for EOL, send prompt now
char in_buf[80];
if (fgets(in_buf, sizeof(in_buf), stdin) {
// process the user input
char *token = strtok(NULL, " \r\n");
// process token(s)
}
}
You can use all the standard format specifiers for printf: %u %s %lu…
You can use scanf, fgets, or any of the standard file/stream IO functions
Pretty sweet.
Your EmBitz project will have to be configured to use EBmonitor including:
- Project->Build Options->Linker Settings->Categories: Debug features->Use EB monitor plugin
- Debug->Plugins->EB monitor->Enable EB monitor
- Debug->Plugins->EB monitor->Send NEWLINE as EOL on enter
STLinkV2 clone dongles are dirt cheap and beautifully integrated with EmBitz. You just Build and then start debugging. EmBitz uses the STLink to flash the target very fast and then lets you run in a full source-level debugger where you can set breakpoints, stop the processor, step through code, examine variables and memory. Using the same interface for your CLI means you only need the dongle and 4 wires connected to the target (includes power and ground!) to do development.
Pingback: Embedded Systems CLI | David Albert