Low-power-Design Schluss mit Energieverschwendung

Software optimiert den Energiefluss und optimiert dadurch die Leistungsaufnahme.
Software reduziert den Energiefluss und optimiert dadurch die Leistungsaufnahme.

Für das Design von Low-Power-Anwendungen reicht es nicht aus, einfach einen Low-Power-Mikrocontroller zu verwenden. Erst die Software sorgt dafür, dass nicht mehr Leistung verbraten wird, als nötig.

Will man bei einer Low-Power-Anwendung auch nur in die Nähe einer optimalen Lösung kommen, geht es nicht ohne einen systemorientierten Design-Ansatz. Dies bezieht sich gleichermaßen auf die aktiven und die passiven Phasen des Systems. Wenn die aktive Betriebsart einen großen Anteil hat, gibt es viel zu analysieren. Die optimale Lösung erreicht man hier mit großer Wahrscheinlichkeit dann, wenn man für eine Optimierung nicht nur die Anwendung mit einbezieht, sondern auch die jeweils verwendeten Kommunikationsmethoden in die Betrachtungen mit einbezieht.

Ohne Frage geht es zunächst darum, die funktionalen Spezifikationen des Produkts zu verstehen, die Verlustleistungs-Vorgaben für das Design zu kennen und eine schleichende Überfrachtung mit unnötigen Features zu verhindern. Es ist unwahrscheinlich, dass eine generalisierte Lösung die energieeffizienteste Implementierung für einen spezifischen Anforderungssatz ergibt, obwohl es natürlich eine ganze Reihe von Maßnahmen gibt, die als Erstes ergriffen werden können. Dies wäre beispielsweise die Verwendung eines auf minimale Verlustleistung hin optimierenden Compilers und seine Einstellung auf den maximalen Optimierungsgrad.

Sorgfältige Systemanalyse

Es gibt zwei Möglichkeiten, eine Embedded-Anwendung auf minimale Leistungsaufnahme zu trimmen, nämlich die Minimierung der Verlustleistung im inaktiven bzw. passiven Status und die Minimierung der Verlustleistung im aktiven Betriebszustand. Hier soll der Blick auf den aktiven Status gerichtet werden und darauf, welche Rolle die Software bei der Minimierung der Leistungsaufnahme übernehmen kann. Wieviel sich hiermit unter dem Strich gewinnen lässt, hängt vom Verhältnis zwischen aktiver und passiver Leistungsaufnahme ab:

space space space space space space space space space space space left parenthesis d u r c h s c h n i t t l i c h e space a k t i v e
fraction numerator L e i s t u n g s a u f n a h m e space x space a k t i v e space Z e i t right parenthesis over denominator left parenthesis d u r c h s c h n i t t l i c h e space p a s s i v e end fraction
L e i s t u n g s a u f n a h m e space x space p a s s i v e space Z e i t

Reduziert man den einen Term, wächst der relative Beitrag des anderen. Das entscheidende Prinzip ist hier, dass es in jeder Anwendung eines systemorientierten Designkonzepts bedarf, um eine optimale Leistungsaufnahme zu erzielen. Dies bedingt eine sorgfältige Analyse der an das Produkt gestellten Anforderungen, damit die Aktivitäten mit dem größten Leistungsbedarf analysiert und optimiert werden können. Anschließend gilt es, ein Hard- und Software-Design zu erarbeiten, das diese Anforderungen erfüllt, dabei aber auf alle unnötigen oder redundanten Funktionen verzichtet. Die meisten tief eingebetteten Systeme besitzen eine oder mehrere Eingangsquellen und einen oder mehrere Ausgänge. Einige Systeme sind komplexer Natur, sodass hier zwangsläufig auch die Optionen komplizierter sind – mit entsprechenden Auswirkungen auf die Verbesserungsmöglichkeiten. Zu den Designzielen für die aktive Phase gehört es, den Zeitbedarf der Software zur Verarbeitung der einzelnen Aufgaben zu verringern und auch die Zeit zu reduzieren, in der die externen I/Os und Peripheriefunktionen aktiv sind.

Planung der System-Tasks

Der einfachste Entwurf eines Embedded-Systems besteht darin, jede Task immer dann zu starten, wenn dies von einem Interrupt angefordert wird. Der gesamte Code ist dann ereignisgetrieben: Er erledigt das Erforderliche und kehrt anschließend in einen Stromspar-Modus zurück. Dieser Ansatz dürfte jedoch nur für besonders einfache Anwendungen praktikabel sein. Ist eine Datenkommunikation nötig, wird dieses Verfahren unpraktikabel und kann den Codeaufwand rapide ansteigen lassen. Die Lösung besteht im Einsatz eines Scheduler oder eines ähnlichen Betriebssystems zum Koordinieren der Task- und Daten-Interaktionen. Jede Variante hat allerdings ganz spezifische Auswirkungen auf die Leistungsaufnahme.

Eine Super Loop sollte beispielsweise nur dann verwendet werden, wenn es sich um eine sehr einfache Anwendung handelt und die Verlustleistungs-Anforderungen unkritisch sind. Diese Methode ermöglicht nämlich nur eine begrenzte Software-Wiederverwendung und bietet keine Perspektive für die künftige Weiterentwicklung. Sie ist somit nicht gerade ideal, denn bei einer Super Loop ist ein gewisses Maß an unnötigen Verarbeitungsaufgaben für die Entscheidung erforderlich, was als Nächstes verarbeitet werden soll. Außerdem ist die Verwendung extern zugelieferter Komponenten mit Super Loops generell schwierig – wenn auch keineswegs unmöglich. Als weitere Option kommt die Verwendung eines präemptiven Echtzeit-Betriebssystems (RTOS) in Frage. Dies bringt dem Entwickler umgehend Vorteile, da der Großteil des Systems dann ereignisgetrieben sein kann. Code wird also nur als Reaktion auf ein bestimmtes Ereignis ausgeführt. Das Resultat ist ein System, das sehr flexibel, wenn auch in Bezug auf das Low-Power Design keineswegs optimal ist. Echtzeit-Betriebssysteme sind in der Regel eher auf hohe Performance als auf geringe Leistungsaufnahme abgestimmt. Durch das Design wird speziell die Antwortzeit der Task mit der höchsten Priorität minimiert.

Bei RTOS-basierten Designs sind deshalb häufig die Kontextwechselzeit und die Interrupt-Latenz die wichtigsten Features. Bei Low-Power-Systemen ist es dagegen im Kontext moderner Prozessoren unwahrscheinlich, dass die Interrupt-Latenz kritisch ist, und auch die Bedeutung der Kontextwechselzeit tritt angesichts der Tatsache, dass sich das System die meiste Zeit im Idle-Zustand befindet, in den Hintergrund. Eine gute Option kann ein kooperativer Scheduler sein, wie er in Bild 1 zu sehen ist. Die Tasks geben die Kontrolle hier erst ab, wenn sie ihre Arbeit erledigt haben, und anschließend kommt die Task mit der nächstniedrigeren Priorität an die Reihe. Auf diese Weise wird die Zahl der Kontextwechsel minimiert. Unabhängig von der gewählten Scheduling-Methode sollte dem Interrupt Handling sorgfältige Beachtung gewidmet werden.

Der nach einem Interrupt entstehende Verarbeitungsaufwand zur Abarbeitung dieses Interrupt ist nicht besonders kritisch für die Verlustleistung. Die wichtigste Zielsetzung besteht stattdessen darin, die Zahl der Interrupts im System zu minimieren, indem optimaler Gebrauch von FIFOs und Timeouts gemacht und ein Scheduling-Mechanismus gewählt wird, der die im Zielgerät verfügbaren Low-Power-Betriebsarten ausnutzt (Bild 2).