# How do I print debug messages to gdb console with STM32 discovery board using GDB, OpenOCD and arm-none-eabi-gcc?

I'm programming an STM32 Cortex M0 discovery board (32F0308DISCOVERY) using OpenOCD, arm-none-eabi-gcc, and gdb. I was wondering if there is any straightforward way to log debug messages over SWD. I've read about the semihosting option, but this seems to require pulling in newlib or other big libraries. (There's only 64k flash available.) Is there any more lightweight way to log text over SWD, or is using the UART the only practical option?

• I suggest you try the semihosting option. By way of indication, the libraries offered by CooCox (a free Windows Cortex-M environment) for M3/4 are pretty minimalist, their single-byte transfer is 17 assembly instructions. A rebuild of an old (STM32F4) project with their semihosting and -O0 added 48 bytes to the code size. – markt Jan 16 '15 at 3:32
• You may not have your linker stripping unused code. As for alternatives, texane's github repo for driving stlink tools has a simple mailboxing scheme, though I have't tried it out yet. – Chris Stratton Jan 16 '15 at 4:04

Thanks for the pointers, markt and chris-stratton. The semihosting option turned out to be quite straightforward. I managed to find the source for a couple of simple logging routines that can send messages to the OpenOCD console. I'll post them here since (i) they required some modification to work and (ii) I think this info is not super easy to find for people who are just starting out.

First, the D code here is easily adapted to provide the following C function:

void send_command(int command, void *message)
{
asm("mov r0, %[cmd];"
"mov r1, %[msg];"
"bkpt #0xAB"
:
: [cmd] "r" (command), [msg] "r" (message)
: "r0", "r1", "memory");
}


Example of calling send_command to write a string to the OpenOCD console:

const char s[] = "Hello world\n";
uint32_t m[] = { 2/*stderr*/, (uint32_t)s, sizeof(s)/sizeof(char) - 1 };
send_command(0x05/* some interrupt ID */, m);


Second, the putChar function given in the comments here works fine, except that I had to add a '#' before 0x03:

void put_char(char c)
{
asm (
"mov r0, #0x03\n"   /* SYS_WRITEC */
"mov r1, %[msg]\n"
"bkpt #0xAB\n"
:
: [msg] "r" (&c)
: "r0", "r1"
);
}


To look at the output from these functions, I first start up OpenOCD, then connect using arm-none-eabi-gdb as follows:

target remote localhost:3333
monitor arm semihosting enable
monitor reset halt

• Great answer! You could also write putchar as simple as void putchar(char c) { send_command(3,&c); } – mvds Dec 10 '16 at 12:18