machine — Funktionen rund um die Hardware

Das machine-Modul enthält spezifische Funktionen, die sich auf die Hardware eines bestimmten Boards beziehen. Die meisten Funktionen in diesem Modul ermöglichen einen direkten und uneingeschränkten Zugriff auf und die Steuerung von Hardwareblöcken eines Systems (wie CPU, Timer, Busse usw.).

Speicherzugriff

Das Modul stellt drei subskriptierbare Objekte für den rohen Speicherzugriff bereit. Jedes verhält sich wie ein dünn besetztes Array, das über die Byte-Adresse indiziert wird: value = memN[addr] liest, memN[addr] = value schreibt. Die Adresse ist unabhängig von der Zugriffsbreite immer eine Byte-Adresse.

machine.mem8

Subskriptierbarer 8-Bit-Speicherzugriff. mem8[addr] liest einen int im Bereich 0-255 aus dem Byte an addr; mem8[addr] = value schreibt die unteren 8 Bit von value. addr muss auf 1 Byte ausgerichtet sein (beliebige Adresse).

machine.mem16

Subskriptierbarer 16-Bit-Speicherzugriff (Halbwort). mem16[addr] liest einen int im Bereich 0-65535; mem16[addr] = value schreibt die unteren 16 Bit. addr muss auf 2 Byte ausgerichtet sein.

machine.mem32

Subskriptierbarer 32-Bit-Speicherzugriff (Wort). mem32[addr] liest einen int im Bereich 0-0xFFFFFFFF; mem32[addr] = value schreibt die unteren 32 Bit. addr muss auf 4 Byte ausgerichtet sein.

Beispielverwendung (die Register sind spezifisch für einen STM32H7-Mikrocontroller – auf der OpenMV Cam H7 / H7 Plus / Pure Thermal ist der Header-Pin P0 mit PB15 verdrahtet):

import machine
from micropython import const

GPIOB = const(0x58020400)
GPIO_BSRR = const(0x18)
GPIO_IDR = const(0x10)

# set P0 (PB15) high via the GPIOB bit-set/reset register
machine.mem32[GPIOB + GPIO_BSRR] = 1 << 15

# read P0 (PB15) directly out of the GPIOB input-data register
value = (machine.mem32[GPIOB + GPIO_IDR] >> 15) & 1

Verschiedene Funktionen

machine.unique_id() bytes

Gibt ein bytes-Objekt zurück, das eine eindeutige Kennung für dieses Board enthält. Der Wert wird aus der Hardware des MCU ausgelesen (typischerweise die werkseitig programmierte Geräteseriennummer), sodass er über Neustarts hinweg stabil ist und sich von einem Board zum nächsten unterscheidet.

Die Länge hängt von der MCU-Familie ab – 12 Bytes auf STM32, 8 Bytes auf den mimxrt- und alif-Ports. Wenn Ihre Anwendung eine ID fester Länge benötigt, schneiden oder hashen Sie den zurückgegebenen Wert.

machine.time_pulse_us(pin: Pin, pulse_level: int, timeout_us: int = 1000000, /) int

Misst die Breite eines einzelnen Impulses an pin und gibt seine Dauer in Mikrosekunden zurück.

pin muss als digitaler Eingang konfiguriert sein.

pulse_level ist die zu messende Impulspolarität: 1 für einen High-Impuls, 0 für einen Low-Impuls.

Die Funktion arbeitet in zwei Phasen. Zunächst wartet sie, falls der Pin nicht bereits auf pulse_level ist, darauf, dass der Pin auf pulse_level wechselt (der Beginn des Impulses). Dann misst sie die Zeit, die der Pin auf pulse_level bleibt, bevor er zurückwechselt (das Ende des Impulses). Die gemessene Zeit wird in Mikrosekunden zurückgegeben.

timeout_us begrenzt jede Phase unabhängig (sodass ein Aufruf im schlimmsten Fall bis zu 2 * timeout_us dauert). Bei Timeout gibt die Funktion einen negativen Wert zurück, der angibt, welche Phase das Timeout überschritten hat:

  • -2 – Timeout beim Warten auf die steigende Flanke (der Pin erreichte nie pulse_level).

  • -1 – Timeout beim Warten auf die fallende Flanke (der Impuls war länger als timeout_us).

machine.bitstream(pin: Pin, encoding: int, timing: tuple, data: bytes, /) None

Überträgt data durch Bit-Banging des angegebenen pin. Das Argument encoding gibt an, wie die Bits kodiert werden, und timing ist eine kodierungsspezifische Timing-Spezifikation.

Die unterstützten Kodierungen sind:

  • 0 für die Pulsdauermodulation „High Low“. Diese überträgt 0- und 1-Bits als zeitgesteuerte Impulse, beginnend mit dem höchstwertigen Bit. Das timing muss ein Vier-Tupel von Nanosekunden im Format (high_time_0, low_time_0, high_time_1, low_time_1) sein. Beispielsweise ist (400, 850, 800, 450) die Timing-Spezifikation für WS2812 RGB-LEDs bei 800 kHz.

Die Timing-Genauigkeit ist hardwareabhängig; schnellere MCUs erzeugen präzisere Impulse (typischerweise einige zehn Nanosekunden).

Bemerkung

Zur Ansteuerung von WS2812- / NeoPixel-Strips siehe das neopixel-Modul für eine höherstufige API.

Konstanten

Die folgenden Konstanten werden von reset_cause() zurückgegeben und geben an, warum der MCU zuletzt zurückgesetzt wurde. Verfügbar auf den STM32- und mimxrt-Ports; der alif-Port (OpenMV Cam AE3) stellt derzeit keine Reset-Ursachen-Konstanten bereit und sein reset_cause() gibt stets 0 zurück.

machine.PWRON_RESET: int

Reset durch Anlegen von Spannung an den Chip. STM32- und mimxrt-Ports.

machine.WDT_RESET: int

Reset durch Ablaufen des Watchdog-Timers. STM32- und mimxrt-Ports.

machine.SOFT_RESET: int

Reset durch soft_reset() (der Python-Interpreter wurde ohne Hardware-Reset neu gestartet). STM32- und mimxrt-Ports.

machine.HARD_RESET: int

Reset durch Aktivieren des NRST-Pins (externe Reset-Taste). Nur STM32-Ports.

machine.DEEPSLEEP_RESET: int

Reset durch Aufwachen aus dem Deep-Sleep. Nur STM32-Ports.

Klassen