Kapitel 2 - Power Management (Stromsparen)
← Startseite · ARM-Architektur · 2 Power Management · → Kap. 3 PIO
Verwandt: Kap. 1 §6 Memory Map · Kap. 3 PIO · Kap. 5 Timer
Quellen: [Q: PM] ES-02-PM · [Q: PM-AB] ES-02-PM-AB (AT91+SAM3X) · [Q: ZF §2/§2a]
Inhalt
- Wozu Power Management?
- Wie? - Methoden
- Konkret: Clocks über Register schalten
- AT91 PMC
- SAM3X PMC & Peripheral IDs
- Prüfungsrelevanz
1. Wozu Power Management?
- Auch Power Saving Modi / Stromsparmodi genannt. Niedrige Stromaufnahme ist extrem wichtig, besonders bei batteriebetriebenen Anwendungen.
- Kernidee: Nicht jede Anwendung braucht jede Peripherie (Timer, USART, …). Nicht benötigte Komponenten so vollständig wie möglich abschalten.
- Auch der CPU-Kern kann abgeschaltet werden, wenn kein Rechenbedarf besteht (z. B. beim Warten auf einen Interrupt - Sleep-Mode; verknüpft mit Kap. 6).
2. Wie? - Methoden
- Taktfrequenz reduzieren (langsamerer Takt → weniger Verbrauch, CMOS-Prinzip: Verbrauch ∝ Schaltfrequenz).
- Taktabschaltung (Clock Gating) von CPU-Kernen und/oder Peripherie.
- Tiefschlafzustände: weitere Komponenten aus, z. B. Teile des RAM (erfordert Rekonstruktion des Inhalts beim Aufwachen).
- Einzelne Funktionsblöcke ganz von der Clock trennen → CMOS: kein Umschalten → minimaler Strom.
Systemstart-Grundeinstellung (typisch, „häufiger"):
- Takt CPU = EIN beim Reset (damit die CPU überhaupt etwas einschalten kann)
- Takt Peripherie = AUS beim Reset → muss von Software aktiviert werden
Merksatz: „Nach dem Reset ist die Peripherie stromlos. Wer sie nutzen will, muss zuerst ihren Clock einschalten." Das ist die häufigste Fehlerquelle im Praktikum: „Komponente funktioniert nicht → ist das Power Management richtig eingestellt (Clock an)?"
3. Konkret: Clocks über Register schalten
- Ein-/Ausschalten durch Setzen/Löschen von Bits in Registern (im Datenblatt spezifiziert).
- Meist wählbar: verschiedene Clocks und Clockteiler (Prescaler).
- Achtung - Hierarchie: Clocks sind oft hierarchisch definiert (Master Clock → verteilt an Controller). Genaues Verständnis nötig.
4. AT91 - Power Management Controller (PMC)
Zwei Takte: System-Takt (CPU) und Peripherie-Takt. Grundeinstellung Reset: CPU-Takt ein, Peripherie-Takt aus.
PMC-Register (Enable/Disable/Status-Muster)
| Offset | Register | Name | Zugriff |
|---|---|---|---|
0x00 | System Clock Enable | PMC_SCER | write only |
0x04 | System Clock Disable | PMC_SCDR | write only |
0x08 | System Clock Status | PMC_SCSR | read only |
0x10 | Peripheral Clock Enable | PMC_PCER | write only |
0x14 | Peripheral Clock Disable | PMC_PCDR | write only |
0x18 | Peripheral Clock Status | PMC_PCSR | read only |
Enable/Disable/Status-Prinzip: Eine 1 in PCER schaltet ein, eine 1 in PCDR schaltet aus - man muss nie das ganze Register lesen-ändern-schreiben (atomar, kein Read-Modify-Write). Dieses Muster zieht sich durch fast die ganze Atmel-Peripherie (auch PIO → Kap. 3).
Bit-Layout PMC_PCER (AT91, Auszug): Bit 13=PIOB, 12=PIOA, 10..8=TC3..TC5? … 7=TC1, 6=TC0, 5=SPI, 4=US2, 3=US1, 2=US0.
Code AT91
// Variante 1 - hartcodierte Adresse
#define PMC_PCER ((volatile unsigned int *) 0xFFFF4010)
*PMC_PCER = 0x4200; // Peripheral Clock für PIOB einschalten (Bit 13 + ... )
// Variante 2 - sauber über struct (bevorzugt)
typedef volatile unsigned int at91_reg;
typedef struct {
at91_reg PMC_SCER, PMC_SCDR, PMC_SCSR, Reserved0;
at91_reg PMC_PCER, PMC_PCDR, PMC_PCSR;
} StructPMC;
#define PMC_BASE ((StructPMC*) 0xFFFF4000)
StructPMC* pmc = PMC_BASE;
pmc->PMC_PCER = 0x4200; // Peripheral Clocks einschalten
5. SAM3X - PMC & Peripheral IDs (PID)
Der SAM3X hat so viele Peripheriekomponenten, dass ein 32-Bit-Register nicht reicht → zwei Enable-Register:
PMC_PCER0(Offset0x10) für PID 0–31PMC_PCER1(Offset0x100) für PID 32–44- analog
PMC_PCDR0/1,PMC_PCSR0/1
Peripheral ID (PID): eindeutige Nummer je Peripheriekomponente. Das Bit n in PMC_PCERx schaltet die Peripherie mit PID n ein.
Wichtige PIDs (SAM3X, Auszug) [Q: ZF §2a]
| PID | Instance | Beschreibung |
|---|---|---|
| 11 | PIOA | Parallel I/O Controller A |
| 12 | PIOB | Parallel I/O Controller B |
| 17 | USART0 | serielle Schnittstelle 0 |
| 18 | USART1 | serielle Schnittstelle 1 |
| 27 | TC0 | Timer Counter Channel 0 |
| 36 | PWM | Pulse Width Modulation Controller |
| 37 | ADC | AD-Wandler |
Code SAM3X
// USART1 hat PID 18 → Bit 18 in PCER0
PMC->PMC_PCER0 = 1 << 18; // oder: PMC->PMC_PCER0 = ID_USART1;
// PID 27 (TC0)
PMC->PMC_PCER0 = 0x1 << 27; // == PMC_PCER0_PID27
// PID 35 (TC8) liegt in Register 1 → Bit (35-32)=3
PMC->PMC_PCER1 = 0x1 << 3; // == PMC_PCER1_PID35
PID ≥ 32 → PCER1, Bit = PID − 32. Häufiger Fehler: PID 35 in
PCER0schreiben zu wollen. PID 0–31 →PCER0Bit PID; PID 32–44 →PCER1Bit (PID−32).
Takthierarchie SAM3X
Clock Generator → Master Clock Controller (PMC_MCKR) erzeugt MCK → verteilt an:
- Processor Clock (HCLK), Peripherals Clock (
PMC_PCERx→periph_clk), Programmable Clock (PMC_PCKx), USB Clock (PMC_USB).
Laborhardware-Vergleich
| MC | Fähigkeiten |
|---|---|
| AT91 | Ein-/Ausschalten einzelner Peripherie + CPU per PMU |
| SAM3X | wie AT91 + wählbare Taktfrequenzen + PID-Konzept |
| RP2040 | keine spezifischen PM-Eigenschaften im Kurs |
Prüfungsrelevanz
- Enable/Disable/Status-Prinzip verstehen (atomar, kein Read-Modify-Write).
- Nach Reset Peripherie-Takt AUS → immer zuerst
PCERsetzen (auch in PIO-/Timer-Init-Aufgaben nötig). - PID → Bit → richtiges Register (PCER0/PCER1) rechnen können.
- Praktikums-/Codeaufgaben starten fast immer mit
PMC->PMC_PCERx = 1 << ID_...;
Typische Fehler: vergessen, den Clock einzuschalten (Komponente „tot") · PID ≥ 32 ins falsche Register · Enable- mit Status-Register verwechseln.