"Low-Power" Programmierung ========================== .. |uA| replace:: :math:`{\mu}A` .. |us| replace:: :math:`{\mu}s` .. |uW| replace:: :math:`{\mu}W` .. |Ohm| replace:: :math:`{\Omega}` Skala der Leistungsaufnahme --------------------------- .. figure:: img/power_scale.svg.png :target: img/power_scale.svg.png * MCU = Microcontroller Unit * ULP = Ultra low-power * LP = low-power Die "normale" MCU-Programmierung im aktiven Modus ohne Berücksichtigung von Stromsparbetriebsarten liegt im grünen Bereich. Ein paar physikalische Zusammenhänge ------------------------------------ .. code-block:: text Ohm'sches Gesetz: U = I * R (Einheiten: V(olt), A(mpere), Ohm) Leistung: P = U * I (Einheit: W(att)) Energie: W = P * t (Einheit: W*s oder J(oule)) Eine mechanische Definition für ein Joule ist 1 kg * m/(s^2) * m. Wenn man 102 Gramm einen Meter hoch hebt, dann wird dafür 1 Joule Energie benötigt. Es gibt noch weitere Veranschaulichungen: https://de.wikipedia.org/wiki/Joule Akku-Kapazität (Ladung Q): Energie [V*A*s] / Spannung [V] = [A*s] Beispiel: CR2032 Li-Ionen Zelle (3V, 235 mA*h), ca. 0.7 Wh Energiegehalt, das entspricht ca. 2540 Joule. Wenn man alle Tricks nutzt, dann kann ein moderner Mikrocontroller mit Stromsparbetriebsarten bis zu 10 Jahren aus einer CR2032 Batterie versorgt werden. CMOS Schaltungen ---------------- .. code-block:: text P_total = P_switching + P_shortcircuit + P_static + P_leakage P_switching = Kapazitäten auf- bzw. umladen P_shortcircuit = Kurzzeitiges Leiten beider CMOS (P-MOS, N-MOS) Transistoren eines Ausgang. P_static = Statische Stromaufnahme (bei CMOS ohne Bedeutung, wird durch andere Schaltungsstrukturen eingeführt) P_leakage = Leckstrom der Transistoren (nimmt mit kleineren Strukturen zu; nimmt exponentiell mit der Temperatur zu) P_switching = c * V^2 * f P_shortcircuit = I_mean * V Dynamic power consumption: P_switching, P_shortcircuit Static power consumption: P_static, P_leakage Stromsparmöglichkeiten ---------------------- - Taktfrequenz reduzieren (Leistungsaufnahme geht linear mit Frequenz). Siehe |uW|/MHz bzw. mW/MHz Angaben. - Spannung reduzieren (Leistungsaufnahme geht *quadratisch* mit der Spannung) - DMA verwenden, so dass CPU schlafen kann. - Dynamic Voltage Scaling (DVS): Der CPU Kern wird über einen internen Spannungsregler versorgt, der 1.2 - 1.8 Volt erzeugen kann. Wenn eine geringere Taktfrequenz ausreicht, kann die Spannung reduziert werden. Der Bereich wird in der folgenden Abbildung *V_core domain* genannt. Er umfasst CPU Kern, SRAM, Flash-Speicher und digitale Peripherie. Der STM32L Controller hat zusätzlich noch einen *low-power* Spannungsregler, der die Versorgung in den low-power Zuständen ``lprun`` und ``lpsleep`` übernimmt. Er hat einen höheren Wirkungsgrad als der andere Spannungsregler. Die Taktfrequenz darf in den "lp" Zuständen höchstens 2 MHz sein. - Clocks selektiv abschalten. Jede nicht getaktete Peripherieeinheit spart Strom ("clock gating"). - Clocks komplett abschalten (HSI, HSE, PLL) - Stromversorgung selektiv abschalten ("power gating"). - Den internen Spannungsregler abschalten, d.h. Core, SRAM und Flash sind ohne Spannung. - Code im SRAM ablegen braucht weniger Strom, als im Flash ablegen. Die Zugriffe auf den Flash-Speicher reduzieren ("ART accelerator"). - Das Reaktivieren aus dem Schlafmodus kostet um so mehr Strom, je mehr Gatter eingeschaltet werden müssen (Stromspitzen). Man kann schnell oder langsam aufwachen. Langsames Aufwachen dämpft die Stromspitzen. Power Domains ------------- .. figure:: img/pwrdoml476.png :target: img/pwrdoml476.png Die "Power-Domains" des STM32L476 (entnommen aus [RM0351R6], Kap. 5) Stromspar-Betriebsarten ----------------------- Der Cortex M Core kennt nur drei Betriebsarten. Die STM32 Controller spalten diese Betriebsarten in weitere Zustände auf: .. code-block:: text Cortex-M STM32F STM32L ------------------------------------------- run run run 1 (20-80 MHz) run 2 (0-25 MHz) lprun sleep sleep sleep lpsleep deep sleep stop stop0 standby stop1 stop2 standby shutdown * Der ``sleep`` Modus schaltet den CPU Takt aus. Der Spannungsregler des CPU Kerns (VREG) bleibt angeschaltet. Zum Aufwecken kann jeder Interrupt verwendet werden, die gesamte Peripherie bleibt aktiv. Die Leistungsaufnahme wird immer noch von HCLK bestimmt. Man kann den ``sleep`` Modus nutzen, wenn man einen DMA Transfer startet und dann die CPU in dieser Zeit schlafen legt. Der ``lpsleep`` Modus beim STM32L4 soll bei einer Taktfrequenz von 100 kHz und abgeschaltetem Flash-Speicher nur etwa 18 |uA| Strom aufnehmen (laut [AN4621]_). * Im ``stop`` Modus wird der schnelle Takt (HSI, HSE, PLL) abgeschaltet, der langsame Takt läuft noch (*peripheral clock gating*). Das SRAM und die Peripherieregister behalten die Daten. Beim Aufwachen muss die Takteinstellung neu konfiguriert werden. Der ``stop0`` Modus liegt bei 100 |uA|, ``stop1`` bei 4 |uA|. Im ``stop2`` Modus werden etwa 1 |uA| Stromaufnahme erreicht. Der LPUART funktioniert noch. Aus dem ``stop`` Modus kommt man in etwa 5 |us| wieder in den ``run`` Modus. * Im ``standby`` Modus wird der VREG abgeschaltet. SRAM und Registerinhalte gehen verloren. Zum Aufwecken kann man noch einen von fünf Wakeup-Pins verwenden, sowie den Reset Pin oder den IWDG (independent watchdog). Der RTC funktioniert auch noch und kann zum Unterbrechen des ``standby`` Modus verwendet werden. In diesem Modus sollte die Stromaufnahme auf unter 1 |uA| heruntergehen. * Beim ``shutdown`` Modus wird auch das *power monitoring* (Brown-Out Reset) und die automatische Umschaltung auf VBAT abgeschaltet. Hier sollte die Stromaufnahme bei ein paar zehn nA sein. Die Stromsparbetriebsarten des STM32L4 .. figure:: img/lpmodes11.png :alt: Die 11 low-power Betriebsarten des STM32L4 :target: img/lpmodes11.png Die 11 low-power Betriebsarten des STM32L4 (aus [NOVIELLO]_, Kap. 19) .. figure:: img/lpfsm.png :alt: Beispielanwendung als Zustandsdiagramm der Stromsparzustände :target: img/lpfsm.png Beispielanwendung als Zustandsdiagramm der Stromsparzustände (aus AN4365: Using STM32F4 MCU power modes with best dynamic efficiency). FreeRTOS und Stromsparen ------------------------ - Die "idle" Task kann den Prozessor in eine stromsparende Betriebsart versetzen. Das ist meist der "sleep" Modus. Mit "hooks" kann man benutzerdefinierte Funktionen von der Idle-Task aufrufen. - Es können in FreeRTOS nur Stromsparbetriebsarten verwendet werden, die das SRAM erhalten, das sind ``run``, ``sleep`` und ``stop``. Die beiden ``standby`` und ``shutdown`` sind nicht möglich. - "tick-less" idle mode https://www.freertos.org/low-power-tickless-rtos.html Beispielcode, der zeigt, wie man die ``sleep`` und ``stop`` Betriebsarten in FreeRTOS verwenden kann: ``FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/`` - Demo für gewöhnlichen ``sleep`` Modus in FreeRTOS ``/opt/rtlab/share/stm32cubel4/src/Projects/STM32L476G-EVAL/Applications/FreeRTOS/FreeRTOS_LowPower`` Beispielprogramme für das Nucleo L476 Board ------------------------------------------- In ``CUBE_HOME`` unter ``src/Projects/NUCLEO-L476RG/Examples/PWR/`` gibt es viele Beispielprogramme (ohne FreeRTOS): .. code-block:: text PWR_LPRUN PWR_ModesSelection PWR_STANDBY PWR_STOP1_RTC PWR_LPRUN_SRAM1 PWR_SHUTDOWN PWR_STANDBY_RTC PWR_STOP2 PWR_LPSLEEP PWR_SLEEP PWR_STOP1 PWR_STOP2_RTC Solarbetriebenes Lesegerät -------------------------- .. figure:: img/solar-reader.jpg :target: img/solar-reader.jpg Ein mit Solarenergie betriebenes Lesegerät (aus Unterlagen von Arrow und Sharp). Praktische Strommessung ----------------------- Auf den STM32 Nucleo Boards gibt es die "IDD" Steckbrücke, der in der Stromzuführung des STM32 liegt. Damit das Board funktioniert, muss die Steckbrücke eingesetzt sein. Wenn man sie entfernt, kann man den Versorgungsstrom des STM32 messen. Dazu verbindet man einfach ein Strommessgerät ("Amperemeter") mit den zwei freien Pins, nachdem die Steckbrücke entfernt wurde. Die meisten preiswerten Multimeter in der 100 Euro Region haben mehrere Strommessbereiche. Zum Beispiel hat das PeakTech 4390 Multimeter einen Milliampere-Messbereich mit zwei Nachkommastellen, die kleinste Ziffer löst also 10 Mikroampere auf. Ausserdem gibt es einen Mikroampere-Messbereich mit einer Auflösung von ein Mikroampere. Bei preiswerten Messgeräten ist in der Regel hier Schluss. Teurere Messgeräte ab ca. 500 Euro bieten meist auch einen Messbereich kleiner als Mikroampere. Zum Beispiel hat beim Rigol DM3068 die kleinste Ziffer im Strommessbereich eine Auflösung von 10 nA. .. figure:: img/dm3086.jpg :target: img/dm3086.jpg Rigol DM3086 Multimeter. **Variante: Messen der Stromstärke mit dem Oszilloskop** Direkt geht das nicht, da das Oszilloskop nur Spannungen messen kann. Man muss daher zunächst den Stromfluss in eine Spannung umwandeln. Eine Spannungsdifferenz entsteht immer dann, wenn Strom durch einen Widerstand fliesst. Meist wird ein kleiner Widerstand (klein, damit er das Messobjekt - den STM32 - nicht stört) an die positive Versorgungsspannung geschaltet (engl. *high-side current shunt*). Da das Oszilloskop in der Regel nur gegen Masse messen kann (der negative Eingang ist geerdet), kann es nicht direkt zur Messung das Spannungsabfalls an dem Widerstand verwendet werden. Die Spannungsdifferenz über dem Widerstand muss erst in eine Spannung gegen Masse umgewandelt werden. Dazu gibt es spezielle integrierte Schaltungen, zum Beispiel den INA139 von Texas Instrument, den man im folgenden Schaltplan sieht: .. figure:: img/current-shunt-monitor.jpg :target: img/current-shunt-monitor.jpg Schaltplan zum Messen der Stromstärke mit dem Oszilloskop. Der Shunt-Widerstand hat 17,22 Ohm, der Lastwiderstand :math:`R_L` hat 5615 Ohm. Die Ausgangsspannund :math:`V_{OUT}` des INA139 berechnet sich wie folgt: :math:`V_{OUT} = I_S \cdot R_S \cdot R_L / 1000 Ohm`. Der Masse-Anschluss des Oszilloskops muss mit der Masse der Schaltung verbunden werden. Datenblatt zum *Current Shunt Monitor* INA139: https://www.ti.com/product/INA139 Der Aufbau sah so aus: .. figure:: img/ina139_aufbau.jpg :target: img/ina139_aufbau.jpg Aufbau der Strommessung mit INA139. Die vier roten LEDs stammen noch von den FreeRTOS-Versuchen, sie haben hier keine Bedeutung. Die folgende Abbildung zeigt eine Messung mit dem Oszilloskop TDS 1002B von Tektronix. Auf dem Nucleo-Board lief das "starter" Beispiel, bei dem die grüne LED blinkt. .. figure:: img/tek0001.png :target: img/tek0001.png Spannung :math:`V_{OUT}` am Ausgang des INA139. Achtung: Die rote Linie zeigt den eingestellten Massepegel. **Literatur** .. [AN4621] STM32L4 and STM32L4+ ultra-low-power features overview, Rev. 4, March 2018. https://hhoegl.informatik.hs-augsburg.de/es2/stm32l4/Manuals/en.DM00148033.pdf [NOVIELLO]_, Kap. 19 (Power Management), S. 511-542 Das Kapitel bietet eine gute Übersicht zum Power Management bei STM32F und STM32L Mikrocontrollern. Es wird auch beschrieben, mit welchen HAL Funktionen aus der *Cube* Bibliothek man in die verschiedenen Stromsparzustände kommt. Ausserdem findet man hier Beispielprogramme. [YIUDG]_ Kap. 9 (Low Power and System Control Features), S. 290 - 325. [WHITE]_ Making Embedded Systems, Kapitel 10 (Reducing Power Consumption), S. 285-298, O'Reilly 2011. ``_ [KEIL]_ Designing energy efficient systems with Cortex-M Microcontrollers, 2009.