Programmierung von Mikrocontrollern

Energieeffizient per Software

12. März 2012, 10:03 Uhr | Roger Neumair
Diesen Artikel anhören

Fortsetzung des Artikels von Teil 1

Energieeffizient per Software

In Schleifen Abwärtszähler verwenden

Listing 2: for-Schleife
; Schleife mit Aufwärtszähler
; for(n=0;n<100;n++)
; P1OUT ^= 0x01;

MOV.W #0,r15 ; Schleifenzähler in r15 laden
CMP.W #100,r15 ; Vergleich auf obere Grenze
JGE After_Loop1 ; Sprung, wenn grösser oder gleich

Loop1:
XOR.B #1,&P1OUT ; Portpin P1.0 Toggle
ADD.W #1,r15 ; Schleifenzähler erhöhen
CMP.W #100,r15 ; Vergleich auf obere Grenze
JL Loop1 ; Sprung wenn kleiner
After_Loop1:


; Schleife mit Abwärtszähler
; for(n=100;n>0;n--)
; P1OUT ^= 0x01;

MOV.W #100,r15 ; Schleifenzähler in r15 laden
CMP.W #1,r15 ; Vergleich auf untere Grenze
JL After_Loop2 ; Sprung, wenn kleiner
Loop2:
XOR.B #1,&P1OUT ; Portpin P1.0 Toggle
SUB.W #1,r15 ; Schleifenzähler verkleinern
JNZ Loop2 ; Sprung, wenn nicht 0
After_Loop2:

passend zum Thema

Listing 2 zeigt eine typische in C programmierte for-Schleife und das Resultat nach dem Compilerlauf in Assembler. Verwendet der Entwickler einen Aufwärtszähler, muss der Schleifenzähler mit der oberen Grenze verglichen werden. Dies entfällt beim Abwärtszähler.

Hier kann man direkt das Zero-Flag testen. Im Beispiel der kurzen Schleifen spart sich der Entwickler 25 Prozent an aktiver Zeit beziehungsweise Instruktionszugriffen. Ein weiterer Bereich, wo sich Energie einsparen lässt, sind Übergaben.

Listing 3: Übergaben
struct S
{
int Int1;
int Int2;
char Char1;
char Char2;
float Float1;
float Float2;
};


struct S localS;
struct S Funktion(struct S myS)
{
myS.Char1++;
}

void FunktionOpt(struct S *myS);
{
myS->Char1++;
}
.
.
.
// Methode 1: Übergabe mittels Wert
localS = Funktion(localS);

// Methode 2: Übergabe mittels Referenz
FunktionOpt(&localS);

Die Struktur S (Listing 3) soll als Parameter an eine Funktion übergeben werden. Es gibt zwei Methoden die Struktur an die Funktion zu übergeben: Methode 1 übergibt den tatsächlichen Wert mittels »Funktion«, Methode 2 übergibt mittels Referenz per »FunktionOpt«.

Listing 4: Assembler-Ausgabe des Speicherbedarfs für die verschiedenen Übergabemethoden
;*****************************************************************************
;* FUNCTION NAME: Funktion                                                   *
;*                                                                           *
;*   Regs Modified     : SP,SR,r10,r11,r12,r13,r14,r15                       *
;*   Regs Used         : SP,SR,r10,r11,r12,r13,r14,r15                       *
;*   Local Frame Size  : 0 Args + 14 Auto + 4 Save = 18 byte                 *
;*****************************************************************************

;*****************************************************************************
;* FUNCTION NAME: FunktionOpt                                                *
;*                                                                           *
;*   Regs Modified     : SP,SR,r10,r11,r12,r13,r14,r15                       *
;*   Regs Used         : SP,SR,r10,r11,r12,r13,r14,r15                       *
;*   Local Frame Size  : 0 Args + 0 Auto + 4 Save = 4 byte                   *
;*****************************************************************************

Listing 4 zeigt die Assembler-Ausgabe des Speicherbedarfs für beide Funktionen. Der große Unterschied zwischen diesen beiden Methoden besteht in der Art, wie die C-Funktion die Werte weiterverarbeitet. Bei der Übergabe mittels Wert erzeugt die »Funktion« mithilfe von »memcpy()« eine lokale Kopie von S und auch das Ergebnis.

Dies benötigt 14 Byte RAM und die entsprechenden Zyklen von memcpy(). Im anderen Fall verwendet »FunktionOpt« direkt die Variablen in der Struktur, die per Zeiger adressiert werden, und benötigt deshalb keinen weiteren Speicherplatz im RAM. Die Anzahl der Zyklen unterscheidet sich deutlich: 292 Zyklen bei der Übergabe mittels Wert und 17 Zyklen bei Übergabe mittels Referenz.

Bild 2: Mithilfe optimierter Software lässt sich signifikant Verlustleistung einsparen
Bild 2: Mithilfe optimierter Software lässt sich signifikant Verlustleistung einsparen
© Texas Instruments Deutschland

Der Grund hierfür ist der zusätzliche Aufwand zum Kopieren der Struktur. Ausgehend von 3 V Versorgungsspannung und einem durchschnittlichen Strombedarf von 1,5 mA beim »MSP430F5172« bei einer Taktfrequenz von 8 MHz kann man die aufgenommene Energie einfach bestimmen, denn E = U · I · ∆t. Daraus folgt für die »Funktion« mit ihren 292 Zyklen 3 V · 1,5 mA · 292/8 MHz = 0,16 µJ. Demgegenüber benötigt »FunktionOpt« mit seinen 17 Zyklen nur 0,01 J.

Ausgehend von der gleichen Energiemenge könnte man also »FunktionOpt« 16-mal so oft ausführen wie die »Funktion«. Das Balkendiagramm in Bild 2 zeigt die relative Energieeinsparung normiert auf die nicht optimierte Variante (100%) bei der Verwendung von Timer, Abwärtszähler in Schleifen und der Übergabe mittels Referenz.

Zusätzliche Einsparpotenziale sind natürlich auch in der Struktur der Software vorhanden. Zudem enthält die Entwicklungsumgebung »Code Composer Studio« für den MSP430 ab Version 5.1 ein Analysetool, den »ULPAdvisor«, welches das C-Programm untersucht und nützliche Hinweise zur Stromeinsparung gibt.

Über den Autor:

Rober Neumair ist System Engineering Manager für die »MSP430«-Produktlinie bei Texas Instruments.


  1. Energieeffizient per Software
  2. Energieeffizient per Software

Lesen Sie mehr zum Thema


Das könnte Sie auch interessieren

Jetzt kostenfreie Newsletter bestellen!

Weitere Artikel zu Texas Instruments Deutschland GmbH