Wie drucke ich mit GDB, OpenOCD und arm-none-eabi-gcc Debug-Meldungen an die gdb-Konsole mit dem STM32-Discovery-Board?

Ich programmiere ein STM32 Cortex M0 Discovery Board (32F0308DISCOVERY) mit OpenOCD, arm-none-eabi-gcc und gdb. Ich habe mich gefragt, ob es eine einfache Möglichkeit gibt, Debug-Meldungen über SWD zu protokollieren. Ich habe über die Semihosting-Option gelesen, aber dies scheint das Einziehen von Newlib oder anderen großen Bibliotheken zu erfordern. (Es ist nur 64k-Flash verfügbar.) Gibt es eine einfachere Möglichkeit, Text über SWD zu protokollieren, oder ist die Verwendung des UART die einzige praktische Option?

Ich schlage vor, dass Sie die Semihosting-Option ausprobieren. Als Hinweis: Die von CooCox (einer kostenlosen Windows-Cortex-M-Umgebung) angebotenen Bibliotheken für M3/4 sind ziemlich minimalistisch, ihre Single-Byte-Übertragung besteht aus 17 Assembler-Anweisungen. Ein Rebuild eines alten (STM32F4) Projekts mit seinem Semihosting und -O0 fügte der Codegröße 48 Bytes hinzu.
Möglicherweise haben Sie Ihren Linker nicht verwendet, um unbenutzten Code zu entfernen. Was Alternativen betrifft, hat das Github-Repo von texane zum Fahren von Stlink-Tools ein einfaches Mailboxing-Schema, obwohl ich es noch nicht ausprobiert habe.

Antworten (1)

Danke für die Hinweise, Markt und Chris-Stratton. Die Semihosting-Option erwies sich als recht einfach. Ich habe es geschafft, die Quelle für ein paar einfache Protokollierungsroutinen zu finden, die Nachrichten an die OpenOCD-Konsole senden können. Ich werde sie hier posten, da (i) sie einige Änderungen erforderten, um zu funktionieren, und (ii) ich denke, dass diese Informationen für Leute, die gerade erst anfangen, nicht sehr einfach zu finden sind.

Zunächst wird der D-Code hier leicht angepasst, um die folgende C-Funktion bereitzustellen:

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

Beispiel für den Aufruf von send_command, um eine Zeichenfolge in die OpenOCD-Konsole zu schreiben:

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

Zweitens funktioniert die hier in den Kommentaren angegebene putChar-Funktion einwandfrei , außer dass ich vor 0x03 ein '#' hinzufügen musste:

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

Um die Ausgabe dieser Funktionen zu sehen, starte ich zuerst OpenOCD und verbinde mich dann mit arm-none-eabi-gdb wie folgt:

target remote localhost:3333
monitor arm semihosting enable
monitor reset halt
load code.elf
continue

Beachten Sie, dass die Meldungen auf der Standardausgabe des OpenOCD-Prozesses erscheinen, nicht auf der GDB-Konsole.

Es gibt einen Fehler, die sizeof() sollte strlen() sein.
Danke user107642. Tatsächlich ist es möglich, sizeof hier zu verwenden, wenn 's' eher ein Array als ein Zeiger ist, also habe ich es so geändert.
Gute Antwort! Du könntest auch putcharso einfach schreibenvoid putchar(char c) { send_command(3,&c); }
"sizeof" zählt das abschließende \0 der Zeichenfolge, während strlen dies nicht tut. Wenn openocd nur auf stdout und ein xterm-Terminalfenster druckt, wird das wahrscheinlich keinen merklichen Unterschied machen, da das Terminal es wahrscheinlich ignorieren wird. Aber wenn Sie am Ende Dinge in einer Datei ablegen, werden Sie überrascht sein, diese Nullen darin zu finden. Oder legt das Protokoll fest, dass Sie Zeichenfolgen mit dem abschließenden Abschlusszeichen senden müssen?
Ah, guter Punkt user242579. Ich habe eine '-1' hinzugefügt, um das nachgestellte \0 zu berücksichtigen.