Falls nötig, kann die statische Stromaufnahme-Messung mit einem Multimeter erfolgen, allerdings ist das im laufenden Betrieb wenig aussagekräftig. Dynamisch und mit hoher Genauigkeit und Abtastrate kann der Strom als Spannungsabfall über einen Messwiderstand dagegen mit Hilfe eines Oszilloskops gemessen werden. Aber abgesehen davon, dass diese Geräte einem Software-Entwickler nicht unbedingt zur Verfügung stehen, bieten die traditionellen Messmethoden einen entscheidenden Nachteil: Die Messungen sind nicht mit dem Programmablauf korreliert, das heißt, sie können nicht dem Wert von Variablen oder der Ausführung bestimmter Funktionen zugeordnet werden. Um das zu erreichen, müsste der Code instrumentalisiert werden, etwa durch das Setzen von GPIO-Pins, die dann die Messung des Oszilloskopes triggern. Diesen Aufwand wird man höchstens dann betreiben, wenn ein konkreter Verdacht besteht, dass die Stromaufnahme höher ist als erwartet. Das Loggen über einen längeren Zeitraum ist aber auch damit noch nicht unbedingt möglich. Mit „Power Debugging“ bietet IAR Systems jedoch eine Technologie, um während des Debuggens an beliebigen Punkten der Zielhardware, zum Beispiel am Prozessor oder an Schnittstellen, Ströme und Spannungen zu messen, diese innerhalb der Entwicklungs-Toolsuite IAR Embedded Workbench anzeigen zu lassen und mit Zeit, möglicherweise sogar mit dem ausgeführten Code, Interrupts oder Variablen zu korrelieren.
Power Debugging
Ermöglicht wird Power Debugging durch die IAR Embedded Workbench für ARM und dem I-Scope von IAR Systems. Wie der Name bereits impliziert, handelt es sich hierbei um ein einfaches Oszilloskop, mit dem unterschiedliche Spannungen gemessen werden. Diese Werte werden als serieller Datenstrom an die In-Circuit-Probe I-Jet übertragen, mit einem Zeitstempel versehen und schließlich im C-SPY Debugger der IAR Embedded Workbench in unterschiedlichen Ansichten visualisiert. Der I-Scope verfügt über einen differentiellen Eingangskanal mit dem Spannungen bis 110 mV gemessen werden. Dieser Kanal dient üblicherweise der Strommessung über einen niederohmigen Messwiderstand (Shunt). Bei einem Shunt von 1 Ω können nach dem Ohmschen Gesetz also Ströme bis zu 110 mV erfasst werden, bei 0,1 Ω maximal 11 mA. Da der verwendete Analog/Digital-Wandler eine Auflösung von 12 Bit hat, beträgt die effektive Genauigkeit circa 100 µV, wenn wir die zwei niedrigsten Bits als Rauschen betrachten. Zusätzlich verfügt der I-Scope über bis zu drei Common-Mode-Spannungskanäle mit einem Messbereich von 0 bis 6 V, die Auflösung beträgt hier wiederum etwa 6 mV. Alle Kanäle können optional auch gleichzeitig aktiviert werden. Die Abtastrate beträgt 200 kHz, allerdings hängt es unter anderem von der Taktfrequenz des Prozessors ab, wie schnell das Signal wirklich in der Entwicklungsumgebung dargestellt werden kann. Je nach Prozessorkern können die Messdaten mit weiteren Werten, wie etwa Variablen oder Interrupts, korreliert werden. Bei einem Cortex-M3 oder -M4 kommt hierfür der SWO(Single Wire Output)-Kanal zum Einsatz. Die bereits verfügbaren Daten des ITM (Instrumentation Trace Module) - also Data-Interrupt- und Event-Log - werden mit den abgetasteten Werten des I-Scope über dessen Zeitstempel synchronisiert. Abhängigkeiten zwischen Stromaufnahme und der Ausführung von Interrupts oder dem Wechsel von Zuständen werden damit sofort erkannt. Bei Bedarf lässt sich die Ausführung bei Über- oder Unterschreitung der gemessenen Spannung auch anhalten (Power Breakpoint). Da für jedes Strom- und Spannungssample auch der korrespondierte PC (Programmcounter) erfasst wird, kann der Stromverbrauch den Funktionen des Quellcodes zugeordnet werden. Im „Function Profiler“ des C-SPY-Debuggers kann sich der Entwickler hiermit ein Stromprofil seiner Anwendung anzeigen lassen. Dieses zeigt, innerhalb welcher Funktion(en) am meisten Strom verbraucht wird, und wie hoch der minimale, maximale oder durchschnittliche Strom innerhalb jeder Funktion ist. Für die Strom- oder Spannungsmessung über einen längeren Zeitraum können die Messwerte mit der „Live log“-Funktion auch direkt in eine Datei geschrieben und später ausgewertet werden.
Anwendungsbeispiele
Ungenutzte I/O-Ports werden üblicherweise in der Hardware auf „Ground“ gelegt. Wenn dieser Port nun fälschlicherweise auf „aktiv high“ gesetzt wird, kann das einen Verluststrom von mehreren Milliampere pro Port bedeuten. Derartige Fehler können mit „Power Debugging“ leicht erkannt werden, wenn deutlich wird, dass der Strom nach der Initialisierung der Applikation sprunghaft ansteigt. In vielen Anwendungen wird die meiste Leistung durch Warten verbraucht, zum Beispiel mit Delay-Schleifen oder durch das Warten auf das �?ndern eines Device-Zustands. Günstiger ist hier zum Beispiel die Verwendung von Hardware-Timern, mit denen der Prozessor während des Wartens in einen Sleep-Modus versetzt wird. Mit der vorgestellten Technik kann der Entwickler auch hier schnell erkennen, ob und welchen Vorteil dies in Bezug auf die Stromaufnahme hat. Ein weiteres Szenario ist die Ermittlung der optimalen Taktfrequenz des CPU. Bekanntlich ist die Verlustleistung eines Prozessors proportional zur Frequenz, so dass eine möglichst geringe Taktrate der Stromersparnis dienen müsste. Anderseits bedeutet dies eine hohe Auslastung, das heißt, der Prozessor ist die meiste Zeit im aktiven Modus. Umgekehrt wird bei hoher Frequenz zunächst mehr Strom verbraucht, aber es kann auch deutlich öfter in den „Sleep“-Modus gewechselt werden. Die Kunst ist nun, die optimale Taktrate festzustellen, um beide Effekte zu optimieren. Hier bietet sich das Power Debugging an, mit dem unterschiedliche Taktfrequenzen getestet werden können und sich leicht zeigen lässt, welche insgesamt am günstigsten ist. Bei den meisten Compilern lässt sich der Code auf Größe oder Geschwindigkeiten optimieren. Aus denselben Gründen, die bereits im letzten Abschnitt diskutiert wurden, ist eine Optimierung auf Schnelligkeit äquivalent zu einer Optimierung auf geringen Stromverbrauch - je schneller eine Aufgabe abgearbeitet ist, umso schneller kann in einen „Power-Down“-Modus gewechselt werden. Wird ein Programm komplett mit maximaler Optimierung auf Geschwindigkeit optimiert, steigt aber auch die Größe des generierten Codes, möglicherweise in erheblichen Maß. Bei der Suche nach dem „Sweet Spot“ zwischen Codegröße und Stromaufnahme ist Power Debugging wieder eine genauso nützliche wie einfache Hilfe.