Ich versuche, eine Anwendung für den Mikrocontroller NXP LPC1788 zu entwickeln, und möchte formatierte Zeichenfolgen an beliebigen Stellen im Quellcode so in einer Protokolldatei protokollieren können, dass die Leistung des Programms vernachlässigbar ist. Im Wesentlichen möchte ich etwas, das den Logger-Dienstprogrammen, die Sie mit Java erhalten, so nahe wie möglich kommt.
ITM_EVENT8_WITH_PC
Derzeit verwende ich einen iJet-Debugger und damit kann ich einzelne 8-Bit- oder 32-Bit-Zahlenwerte mit und ITM_EVENT32_WITH_PC
zusammen mit dem Programmzähler und dem Zeitstempel in das IAR EW-Ereignisfenster drucken . Zahlen allein sind jedoch nicht aussagekräftig genug, und ich bin auf vier Kanäle beschränkt. Dies bedeutet, dass ich oft einen kleinen Teil des Programms auswählen muss, um ihn gleichzeitig zu protokollieren, Aufrufe ITM_EVENT...
in nicht verwandten Teilen auskommentieren und neue hinzufügen oder vorhandene auskommentieren muss in dem Teil, den ich genau überwachen möchte. Dies ist nicht wirklich ein sehr effizienter Ansatz.
Eine Sache, die ich versucht habe, ist das Erstellen einer Makrodatei, die eine Funktion enthält, LogMessage
die eine Zeichenfolge als Parameter akzeptiert und an das integrierte __message
Makro übergibt. Ich bin mir jedoch nicht sicher, wie ich dieses Makro in das Programm einfügen kann, damit ich LogMessage
es im Quellcode aufrufen kann - ich habe versucht, es in anzugeben , aber dies ist nicht mit dem Quellcode Debugger -> Setup Macros
verknüpft .LogMessage
Jede Hilfe wäre willkommen.
BEARBEITEN
Wie es in Java gemacht wird
Um ein Beispiel dafür zu geben, wie das Logger-Framework (insbesondere der SLF4J-Variante) in Java verwendet werden kann, nehme ich das aus dem SLF4J-Handbuch und erkläre, was passiert:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
In diesem Fall erstellen wir eine Klasse mit einer statischen main
Methode, die als Einstiegspunkt für die Anwendung dient. Dann rufen wir eine Factory-Methode auf, getLogger
um ein Protokollierungsobjekt zu erzeugen, das wir auf die Klasse aufmerksam machen, in der wir es instanziieren - HelloWorld.class
. Diese Informationen können so konfiguriert werden, dass sie in Protokollausgaben eingeschlossen werden.
Wir können dieses Protokollierungsobjekt dann verwenden, um Protokolle mit unterschiedlichen Protokollebenen zu erstellen , je nach Wichtigkeit und Art dessen, was wir protokollieren. In dem Beispiel geben wir „Hello World“ auf Protokollebene aus INFO
, die zum Protokollieren relativ wichtiger Informationen verwendet wird, und das Protokollierungsframework behandelt diese Ausgabe entsprechend seiner Protokollebene und der Konfiguration des Frameworks – dies kann die Ausgabe an stdout umfassen oder in einer Datei speichern.
Wie ich es machen möchte
Es wäre schön, wenn ich etwas Ähnliches für die Arbeit mit IAR Embedded Workbench-Anwendungen bekommen könnte. I-jet/JTAGjet -> SWO Configuration...
Ich habe das Problem mit einem Kollegen besprochen und festgestellt, dass wir Daten von den ITM-Stimulus-Ports über die Menüleiste oben zum Terminal-E/A-Fenster leiten und dann das Terminal-E/A-Fenster protokollieren können . Sie können sich direkt von den ITM-Ports in eine Protokolldatei einloggen, aber ich finde, dass es die Datei jedes Mal zu überschreiben scheint, wenn Sie aus irgendeinem Grund einen neuen Wert in einen ITM-Port schreiben.
Womit ich jetzt experimentiere, ist das Erstellen einer Methode wie logData(uint16_t logId, uint8_t logLevel, uint32_t value)
, die bewirkt, dass die Daten auf eine bestimmte Weise in einer Protokolldatei gespeichert werden:
Die erzeugte Protokolldatei ist nicht lesbar, aber ich könnte ein Python-Skript zusammenstellen, das die generierte Protokolldatei nimmt und eine schön formatierte, für Menschen lesbare Datei im gleichen Stil wie eine SLF4J-Protokolldatei erstellt.
Das ist zumindest die Idee.
BEARBEITEN 2
Ich habe ein scheinbar anständiges Protokollierungs-Framework für meine Anforderungen zusammengestellt, obwohl ich noch nicht versucht habe, es ausgiebig zu verwenden, um zu sehen, wie es sich unter Druck hält.
In der Methode meiner Mikrocontroller-Anwendung main
kann ich einen Aufruf wie durchführen LOGGER_Init(LOG_LEVEL_DEBUG, 5);
, wobei das erste Argument die Logger-Protokollebene und das zweite Argument der ITM-Stimulus-Port zum Drucken von Protokolldaten ist. Der Logger druckt nur Log-Meldungen, deren Log-Level gleich oder höher als sein eigener ist (z. B. druckt ein Logger LOG_LEVEL_INFO
Meldungen LOG_LEVEL_WARN
und LOG_LEVEL_INFO
Meldungen, aber keine LOG_LEVEL_DEBUG
Meldungen).
Ich kann dann Daten auf folgende Weise protokollieren:
LOGGER_Info(0x1, 0x20);
LOGGER_Debug(0x2, 0x3A, 0xFF);
Diese Methoden behandeln den ersten Wert als Protokollkennung und die verbleibenden Argumente werden auf unterschiedliche Weise als Protokolldaten behandelt.
In einer 'log map'-Datei verwalte ich eine Zuordnung von Protokollkennungen zu Platzhalter-Protokollausgabemeldungen, wobei '{}' einen Platzhalterwert wie in SLF4J darstellt:
static const LOG_MAP_T logMappings[] = {
{1, "The first log message in main provides {}"},
{2, "The second log message provides {} and also {}"}
};
Der Logger druckt Protokollmeldungen der entsprechenden Ebenen an den konfigurierten ITM-Stimulus-Port aus, der sie dann an das Terminal-E/A-Fenster weiterleitet, wo sie in einer Protokolldatei gespeichert werden.
Ich habe dann ein Python-Skript, das sowohl die Protokollausgaben als auch die Zuordnungsdatei durchgeht und alles zusammenfügt, um so etwas zu produzieren:
>>>
INFO The first log message in main provides 32
DEBUG The second log message provides 58 and also 255
Ich würde empfehlen, dass Sie die ETM-Funktion des von Ihnen verwendeten LPC-Chips aktivieren. Die Embedded Trace Macrocell ist im Wesentlichen ein Speicherort, in den Sie Zeichen schreiben können, die über die JTAG/SWD-Verbindung zu Ihrem EWARM in die Terminalfenster (oder sogar in das Eclipse-Plugin) gelangen.
Sie können einfach ein Makro schreiben, um die Zeichen direkt in die Mem-Adresse zu schreiben, oder Sie können das verwenden, was IAR "Host-Modus" nennt, ich denke, wo sie Ihre Standardausgabe hacken und es für Sie tun. Verwenden Sie dann einfach printf eines beliebigen Wrappers, den Sie mögen.
Suchen Sie auf ihrer Website nach der Appnote und ignorieren Sie alle ausgefallenen Trace-Funktionen, die ETM bietet (wenn Sie sie nicht benötigen), und suchen Sie einfach nach den Debug-Ausgaben.
Wenn Sie gewartet werden, rufen Sie das nächste IAR-Büro an und fragen Sie nach einem FAE, und sie werden Sie Schritt für Schritt durchgehen.
Benutzer694733
Tagc
Benutzer694733
Tagc
RHaguiuda