Ich habe mir überlegt, wie ich bequem Debug Meldungen über ITM ausgeben kann. Das Konstrukt mit den variablen Argumenten (args) ist mir allerdings neu. Habe ich das so richtig umgesetzt?
1
#include"stm32g4xx.h"
2
#include<stdio.h>
3
#include<stdarg.h>
4
5
// Output an ITM message
6
voiddebug_print(constchar*ptr){
7
while(*ptr){
8
ITM_SendChar((uint32_t)*ptr++);
9
}
10
}
11
12
// Like printf() but using ITM. Max. 80 characters.
Der Code in den Zeilen 19 bis 22 ist soweit formal korrekt, so verwendet man va_list.
Unabhängig davon: Die Funktion belegt halt u.a. die Puffergröße auf dem Stack, das kann für eine Debugausgabe problematisch werden.
Günstiger könnte es sein, die Variante vfprintf zu verwenden, und die dort letztlich rausfallenden Zeichen direkt an ITM_SendChar zu übergeben.
Dazu musst Du allerdings rausfinden, wie in Deiner Entwicklungsumgebung mit printf und Dateihandles wie stdio etc. umgegangen wird.
Oft muss man nur eine lowlevel-Funktion wie _write ersetzen.
Und rein stilitisch: Was sollen die Leerzeichen vor den Zeilenumbrüchen in main()?
Könnte man doch eigentlich auch so schreiben, oder nicht?
Günstiger könnte es sein, die Variante vfprintf zu verwenden, und die
dort letztlich rausfallenden Zeichen direkt an ITM_SendChar zu
übergeben.
Ja das klappt.
Dazu musst Du allerdings rausfinden, wie in Deiner Entwicklungsumgebung
mit printf und Dateihandles wie stdio etc. umgegangen wird.
Oft muss man nur eine lowlevel-Funktion wie _write ersetzen.
Jawoll, den Punkt kenne ich. Im Fall von Arduino schien es mir naheliegender, einen kleinen Puffer zu verwenden. STM32duino saut eh schon herum, was den Speicherbedarf angeht. Da fallen die 81 Bytes nicht weiter auf :-)
Was sollen die Leerzeichen vor den Zeilenumbrüchen in main()?
Soll die Lesbarkeit des Beispiels erhöhen. In echt programmiere ich nicht so.
Mir ist es als /unerwartet/ aufgestoßen. Ich hatte mal einen Kollegen, der statt "\n" oder der unter Windows üblichen Sequenz "\r\n" hartnäckig ”\n\r" verwendete, und das auch noch am Zeilenanfang statt -Ende.
Günstiger könnte es sein, die Variante vfprintf zu verwenden, und die
dort letztlich rausfallenden Zeichen direkt an ITM_SendChar zu
übergeben.
Dazu musst Du allerdings rausfinden, wie in Deiner Entwicklungsumgebung
mit printf und Dateihandles wie stdio etc. umgegangen wird.
Oft muss man nur eine lowlevel-Funktion wie _write ersetzen.
Günstiger könnte es sein, die Variante vfprintf zu verwenden,
und die dort letztlich rausfallenden Zeichen direkt an
ITM_SendChar zu übergeben.
Im Fall von Arduino schien es mir naheliegender, einen kleinen
Puffer zu verwenden. STM32duino saut eh schon herum, was den
Speicherbedarf angeht. Da fallen die 81 Bytes nicht
weiter auf :-)
Ein Kompromiss: der Puffer könnte static sein. So ein debug_print() möchte man irgendwann auch in einem fault handler benutzen, da fällt das auf dem Stack eher auf. Dafür lohnt sich evt. sogar Formatierung im Eigenbau. Wenn man auf Luxus wie %f, %*.*s verzichtet, braucht die nur ca. 12 Byte Puffer für beliebig lange Ausgaben. Und keine lib.
P.S. ich fände debug_printf mit 'f' schöner, gerade, wenn die die lib benutzt und alles kann.
Dafür lohnt sich evt. sogar Formatierung im
Eigenbau. Wenn man auf Luxus wie %f, %*.*s verzichtet, braucht die nur
ca. 12 Byte Puffer für beliebig lange Ausgaben. Und keine lib.
Ich frage mich, wieviel Lebenszeit schon sinnlos verschwendet wurde, um krampfhaft printf() & Co. zu vermeiden, nur weil es etwas Code einspart.
Damals, als die µCs wirklich noch keinen Programmspeicher hatten, da war das wirklich ein Argument, aber hier geht es um irgendeinen Cortex - und der hat nun wirklich keine Probleme damit, die wenigen kByte einer printf-Implementierung unterzubringen. Und auf float-Unterstützung kann man immer noch verzichten; die Runtime-Libraries üblicher Compiler bieten genau deswegen verschieden zurechtgekürzte printf-Libraries an.
Ich frage mich, wieviel Lebenszeit schon sinnlos verschwendet wurde, um
krampfhaft printf() & Co. zu vermeiden, nur weil es etwas Code einspart.
Mir ging es drum, Abhängigkeiten zu vermeiden, Flash hat man, ausreichend. Mit einem printf(), das keinen Stack braucht, kann ich im fault handler immer noch "drucken", egal, wie groß das Chaos ist. OK, Hintergrund ist auch, ich lasse die Programme erstmal im RAM laufen und flashe selten.
Ich finde es auch angenehm, wenig bis keine fremden libs zu brauchen.