Wie drucke ich Debug-Meldungen mit dem STM32 Discovery Board unter Verwendung von GDB, OpenOCD und arm-none-eabi-gcc auf die GDB-Konsole?

15

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 erfordert anscheinend das Einlesen von newlib oder anderen großen Bibliotheken. (Es sind nur 64-KByte-Flash-Speicher verfügbar.) Gibt es eine einfachere Möglichkeit, Text über SWD zu protokollieren, oder ist die Verwendung des UART die einzige praktikable Option?

foldl
quelle
1
Ich schlage vor, Sie versuchen die Semihosting-Option. Aus Gründen der Übersichtlichkeit sind die von CooCox (einer kostenlosen Windows Cortex-M-Umgebung) für M3 / 4 angebotenen Bibliotheken recht minimalistisch, ihre Einzelbyte-Übertragung umfasst 17 Assembler-Anweisungen. Durch die Neuerstellung eines alten (STM32F4) Projekts mit Semihosting und -O0 wurden der Codegröße 48 Byte hinzugefügt.
Markt
Möglicherweise entfernt Ihr Linker nicht verwendeten Code nicht. Was Alternativen angeht, hat Texanes Github-Repo für den Antrieb von stlink-Tools ein einfaches Mailbox-Schema, das ich jedoch noch nicht ausprobiert habe.
Chris Stratton

Antworten:

15

Danke für die Hinweise, Markt und Chris-Stratton. Die Semihosting-Option erwies sich als recht einfach. Ich konnte die Quelle für einige einfache Protokollierungsroutinen finden, die Nachrichten an die OpenOCD-Konsole senden können. Ich werde sie hier posten, da (i) sie einige Modifikationen für die Arbeit benötigten und (ii) ich denke, dass diese Informationen für Leute, die gerade erst anfangen, nicht sehr einfach zu finden sind.

Erstens kann der D-Code hier leicht angepasst werden, 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 einen String 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, da die putchar Funktion in den Kommentaren hier funktioniert gut, außer dass ich ein ‚#‘ hinzuzufügen , bevor 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"
    );
}

Um die Ausgabe dieser Funktionen zu betrachten, 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 im Standard des OpenOCD-Prozesses und nicht in der GDB-Konsole angezeigt werden.

foldl
quelle
1
Es gibt einen Bug, der sizeof () sollte strlen () sein.
1
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 modifiziert.
Falten
Gute Antwort! Sie können auch putcharso einfach schreiben wievoid putchar(char c) { send_command(3,&c); }
mvds
1
Die "sizeof" zählt die abschließende \ 0 der Zeichenkette, während strlen dies nicht tut. Wenn openocd nur zu stdout und einem 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 wahrscheinlich überrascht sein, diese Nullen dort zu finden. Oder gibt das Protokoll an, dass Sie Zeichenfolgen mit dem nachgestellten Abschlusszeichen senden müssen?
user242579
Ah, guter Punkt user242579. Ich habe ein '-1' hinzugefügt, um die nachgestellte \ 0 zu berücksichtigen.
Foldl