Version | Anpassungen |
---|---|
1.0 (2023-10-29) | Basis-Version |
Inhaltsverzeichnis
Die Arduino-Bibliothek ESP (EspClass mit vordefinierter Instanz ESP in Esp.h) bietet bereits einige Methoden zur CPU-, Prozess- und Speicherkontrolle. Einige wichtige Funktionen fehlen jedoch. Die Klasse Bibliothek UrsEsp (UrsEspClass mit vordefinierter Instanz UrsESP in UrsEsp.h) ergänzt EspClass per Ableitung.
Die Arduino-Bibliothek ist außerdem schlecht dokumentiert. In der folgenden Funktionsbeschreibung sind ebenfalls die Funktionen aufgeführt, die in EspClass definiert sind. Diese stehen wegen der Ableitung natürlich auch über die Instanz UrsESP zur Verfügung.
Name | Funktion | Anmerkung | Klasse |
---|---|---|---|
Restart | |||
void restart () | Führt einen Reset der CPU aus. | Diese Funktion kann sowohl von PRO- als auch von APP-CPUs aufgerufen werden. Nach einem erfolgreichen Neustart lautet der Grund für das Zurücksetzen der CPU SW_CPU_RESET (s. esp_err.h). Peripheriegeräte(außer WiFi, BT, UART0, SPI1 und ältere Timer) werden nicht zurückgesetzt. |
ESP |
esp_err_t registerShutdownHandler ( void (*shutdownHandler)(void)) | Registriert einen Shutdown-Handler. | Mit dieser Funktion kann einen Handler registriert werden, der aufgerufen wird, bevor die Anwendung mit
der Funktion restart neu gestartet wird. Mögliche Fehler (s. esp_err.h) - ESP_OK bei Erfolg. - ESP_ERR_INVALID_STATE, wenn der Handler bereits registriert wurde. - ESP_ERR_NO_MEM, wenn keine Shutdown-Handler-Slots mehr verfügbar sind. |
UrsESP |
esp_err_t unregisterShutdownHandler ( void (*shutdownHandler)(void)) | Registrierung des Shutdown-Handlers aufheben | Mögliche Fehler (s. esp_err.h) - ESP_OK bei Erfolg. - ESP_ERR_INVALID_STATE, wenn der angegebene Handler noch nicht registriert wurde. |
UrsESP |
int getResetReason ( int cpuNumber) | Ruf den Grund für das Zurücksetzen der CPU ab. | Die Enumeration RESET_REASON für die Gründe findet man in <cpu>rom/rtc.h. | UrsESP |
String getResetReasonName ( int reason) | Liefert die Bezeichnung des Reset-Grundes. | Z.B. POWERON_RESET. Die Enumeration RESET_REASON für die Gründe findet man in <cpu>rom/rtc.h. | UrsESP |
String getResetReasonDescription ( int reason) | Liefert die Beschreibung des Reset-Grundes. | Z.B. Vbat power on reset. Die Enumeration RESET_REASON für die Gründe findet man in <cpu>rom/rtc.h. | UrsESP |
Heap | |||
uint32_t getHeapSize () | Liefert die Größe des gesamten Heaps. | ESP | |
uint32_t getFreeHeap () | Liefert die Größe des freien Heaps. | ESP | |
uint32_t getMinFreeHeap () | Liefert den niedrigsten Stand des freien Heaps seit dem Booten. | ESP | |
uuint32_t getMaxAllocHeap () | Ruft die Größe des größten freien Speicherblocks ab, der zugewiesen werden kann. | ESP | |
uint32_t getLargestFreeDmaHeapBlock () | Ruft die Größe des größten freien Heap-Speicherblocks ab, der für DMA-Zugriff zugewiesen werden kann. | UrsESP | |
void* allocDmaHeapBlock ( size_t size) | Allokiert size Bytes nicht initialisierten Speicher, auf den per DMA zugegriffen
werden kann. Liefert einen Zeiger auf den allokierten Bereich oder NULL (nullptr), wenn eine Zuweisung nicht möglich war. |
Um ein Speicherleck zu vermeiden, muss der zurückgegebene Zeiger mit free oder dmaRealloc freigegeben werden. | UrsESP |
void* dmaMalloc ( size_t size) | S.o., Alias von allocDmaHeapBlock | S.o. | UrsESP |
void* reallocDmaHeapBlock ( void* ptr, size_t newSize) | Allokiert den angegebenen Speicherbereich neu. | Bereits vorhandene Zeiger in den Speicherbereich können dabei ungültig werden! | |
void* dmaRealloc ( void* ptr, size_t newSize) | S.o., Alias von reallocDmaHeapBlock | S.o. | |
PSRAM*) | |||
uint32_t getPsramSize () | Liefert die Größe des gesamten PSRAMs. | ||
uint32_t getFreePsram () | Liefert die Größe des freien PSRAMs. | ||
uint32_t getMinFreePsram () | Liefert den niedrigsten Stand des freien PSRAMs seit dem Booten. | ||
uint32_t getMaxAllocPsram () | Ruft die Größe des größten freien PSRAM-Speicherblocks ab, der zugewiesen werden kann. | ||
bool psramFound () | Liefert true, wenn PSRAM vorhanden ist. | UrsESP | |
void* psramMalloc ( size_t size) | Allokiert size Bytes nicht initialisierten Speicher. Liefert einen Zeiger auf den allokierten Bereich oder NULL (nullptr), wenn eine Zuweisung nicht möglich war. | Um ein Speicherleck zu vermeiden, muss der zurückgegebene Zeiger mit free oder psramRealloc freigegeben werden (s. cppreference.com:malloc). | UrsESP |
void* psramRealloc ( void *ptr, size_t newSize) | Allokiert den angegebenen Speicherbereich neu. Bereits vorhandene Zeiger in den Speicherbereich können dabei ungültig werden! |
Die Neuzuweisung erfolgt entweder durch: a) Erweiterung oder Verkleinerung des von ptr genannten bestehenden Bereichs, sofern möglich. Der Flächeninhalt bleibt bis zur kleineren der neuen und alten Größen unverändert. Wenn der Bereich erweitert wird, ist der Inhalt des neuen Teils des Arrays undefiniert. b) Zuweisung eines neuen Speicherblocks mit der Größe newSize Bytes, Kopieren des Speicherbereichs mit einer Größe, die der kleineren der neuen und alten Größen entspricht, und Freigeben des alten Blocks. Wenn nicht genügend Speicher vorhanden ist, wird der alte Speicherblock nicht freigegeben und ein nullptr zurückgegeben. Siehe cppreference.com:realloc |
UrsESP |
void* psramCalloc ( size_t num, size_t size) | Allokiert Speicher für ein Array von num Objekten der Größe size und initialisiert alle Bytes im zugewiesenen Speicher auf 0. | Wenn die Zuweisung erfolgreich ist, wird ein Zeiger auf das unterste (erste) Byte im zugewiesenen Speicherblock zurückgegeben, ansonsten nullptr (s. cppreference.com:calloc). | UrsESP |
Flash | |||
uint32_t getFlashChipSize () | Gibt die Größe des Flash-Speichers in Bytes zurück. | ESP | |
uint32_t getFlashChipSpeed () | Gibt die Zugriffsgeschwindigkeit auf das Flash in Hz zurück. | Dies ist i.d.R. die max. Mögliche SPI-Taktfrequenz von 80 MHz. | ESP |
FlashMode_t getFlashChipMode () | Gibt die Art des Zugriffs auf das Flash zurück. | Die Enumeration FlashMode_t besitzt folgende Member: FFM_QIO = 0x00, FM_QOUT = 0x01, FM_DIO = 0x02, FM_DOUT = 0x03, FM_FAST_READ = 0x04, FM_SLOW_READ = 0x05, FM_UNKNOWN = 0xff |
ESP |
uint32_t magicFlashChipSize ( uint8_t byte) | Liefert eine Konstante zur Einstellung der Flash-Größe. | Diese Erklärung der Funktion ist unsicher! | ESP |
uint32_t magicFlashChipSpeed ( uint8_t byte) | Liefert eine Konstante zur Einstellung der Flash-Geschwindigkeit. | Diese Erklärung der Funktion ist unsicher! | ESP |
FlashMode_t magicFlashChipMode ( uint8_t byte) | Liefert eine Konstante zur Einstellung der Flash-Zugriffsart. | Diese Erklärung der Funktion ist unsicher! | ESP |
bool flashEraseSector ( uint32_t sector) | Löscht einen Flash-Sektor. Sektor: Sektor-Nummer, die Zählung beginnt bei Sektor 0, 4KB pro Sektor. Liefert true bei Erfolg. |
ESP | |
bool flashWrite ( uint32_t offset, uint32_t *data, size_t size) | Daten ins Flash schreiben. offset: Zieladresse im Flash. data: Zeiger auf die Quelldaten. size: Anzahl zu schreibender Bytes. Liefert true bei Erfolg. |
Die schnellste Schreibleistung erhält man, wenn die zu schreibende Menge ein Vielfaches von 4 Bytes ist
(uint32_t, DWORD). Der Quellpuffer und der Flash-Offset sollte an einer 4-Byte-Grenze beginnen. Das Variieren eines dieser Parameter funktioniert trotzdem, ist aber aufgrund der Pufferung langsamer. Das Schreiben von mehr als 8 KB auf einmal wird in mehrere Schreibvorgänge aufgeteilt, um andere Aufgaben im System nicht zu stören. |
ESP |
bool flashRead ( uint32_t offset, uint32_t *data, size_t size) | Daten aus dem Flash auslesen. offset: Quelladresse im Flash. data: Zeiger auf die Zieldaten. size: Anzahl zu lesender Bytes. Liefert true bei Erfolg. |
Um die schnellste Leseleistung zu erzielen, sollten alle Parameter auf 4 Byte-Grenzen (uint32_t, DWORD)
ausgerichtet sein. Wenn Quelladresse und Lesegröße nicht 4 Byte ausgerichtet sind, kann das Lesen in mehrere
Flash-Operationen aufgeteilt werden. Wenn der Zielpuffer nicht auf 4 Byte ausgerichtet ist, wird ein temporärer
Puffer auf dem Stack zugewiesen. Das Lesen von mehr als 16 KB Daten auf einmal wird in mehrere Lesevorgänge aufgeteilt, um eine Unterbrechung anderer Aufgaben im System zu vermeiden. |
ESP |
bool partitionEraseRange ( const esp_partition_t *partition, uint32_t offset, size_t size) | Zu Partitionen siehe Partition Table in der ESP32 Arduino Core’s documentation. | ESP | |
bool partitionWrite ( const esp_partition_t *partition, uint32_t offset, uint32_t *data, size_t size) | Zu Partitionen siehe Partition Table in der ESP32 Arduino Core’s documentation. | ESP | |
bool partitionRead ( const esp_partition_t *partition, uint32_t offset, uint32_t *data, size_t size) | Zu Partitionen siehe Partition Table in der ESP32 Arduino Core’s documentation. | ESP | |
CPU | |||
uint8_t getChipRevision () | Liefert die Revisionsnummer des Chips. | Siehe Chip Revision | ESP |
const char* getChipModel () | Liefert einen String mit der Modellbezeichnung. | Z.B. "ESP32-S3" | ESP |
uint8_t getChipCores () | Liefert die Anzahl der im Chip enthaltenen Kerne. | ESP | |
uint32_t getCpuFreqMHz () | Liefert die CPU-Taktfrequenz in MHz. | ESP | |
uint32_t getCycleCount () | Ermittelt den aktuellen Wert des internen Zählers, der bei jedem Prozessor-Taktzyklus erhöht wird. | Liefert 0, wenn diese Funktion nicht unterstützt wird. | ESP |
const char* getSdkVersion () | Rückgabe der vollständigen IDF-Versionszeichenkette. | ESP | |
Sonstige | |||
void deepSleep ( uint32_t time_us) | In den Deep-Sleep-Modus wechseln. time_us: Anzahl μs für den Modus. |
Das Gerät wacht nach der Tiefschlafzeit automatisch auf. Nach dem Aufwachen ruft das Gerät den Tiefschlaf-Wake-Stub
(s. nächste Funktion) auf und fährt dann mit dem Laden der Anwendung fort. deepSleep beendet WiFi-, BT- und höherwertige Protokollverbindungen nicht ordnungsgemäß. Es sollte sicher gestellt werden, dass die relevanten WiFi- und BT-Stack-Funktionen aufgerufen werden, um alle Verbindungen zu schließen und die Peripheriegeräte zu deinitialisieren. Dazu gehören: esp_bluedroid_disable, esp_bt_controller_disable, esp_wifi_stop |
ESP |
void esp_wake_deep_sleep(void) | Standard-Stub für die Ausführung beim Aufwachen aus dem Deep-Sleep. | Ermöglicht die Ausführung von Code unmittelbar nach dem Aufwachen aus dem Ruhezustand, bevor der Software-Bootloader
oder die ESP-App gestartet wurde. Diese Funktion ist schwach verlinkt (weak-linked), so dass eine eigene Version implementiert werden kann. Diese muss mit extern "C" umschrieben sein (Name Mangling bei C++). |
|
uint64_t getEfuseMac() | Liefert die MAC-Basisadresse, die werkseitig von Espressif über EFUSE programmiert wurde. | ESP |
*) PSRAM oder SPI-RAM ist ein externes RAM, das per SPI mit der CPU verbunden ist. PSRAM muss aktiviert werden (s.u. PSRAM).
PSRAM (Pseudo-RAM) oder SPI-RAM ist ein externes RAM, das per SPI mit der CPU verbunden ist. Beim ESP32-S3 ist die Größe in der Bezeichnung enthalten. Für den ESP32-S3 gilt die folgende Tabelle:
Modul | Flash | PSRAM | SPI Spannung | ||
---|---|---|---|---|---|
ESP32-S3-WROOM-1-N8 | 8 MB QD | — | 3.3 V | QD: Zugriff über Quad-SPI OT: Zugriff über Octal-SPI |
|
ESP32-S3-WROOM-1-N8R2 | 8 MB QD | 2 MB QD | 3.3 V | ||
ESP32-S3-WROOM-1-N8R8 | 8 MB QD | 8 MB OT | 3.3 V | ||
ESP32-S3-WROOM-2-N16R8V | 16 MB OT | 8 MB OT | 1.8 V | ||
ESP32-S3-WROOM-2-N32R8V | 32 MB OT | 8 MB OT | 1.8 V | ||
ESP32-S3-WROOM-1U-N8 | 8 MB QD | — | 3.3 V | ||
ESP32-S3-WROOM-1U-N8R2 | 8 MB QD | 2 MB QD | 3.3 V | ||
ESP32-S3-WROOM-1U-N8R8 | 8 MB QD | 8 MB OT | 3.3 V |
PSRAM muss in den Sketch-Einstellungen aktiviert werden:
Ardiuino-IDE-Einstellungen | Visual-Micro-Einstellungen |
Alternativ kann esp_spiram_init (deklariert in spiram.h) aufgerufen werden. Dies ist die Beschreibung der Funktion: Initialize spiram interface/hardware. Normally called from cpu_start.c.
Das Espressif-IDF, das Basis für das Arduino-Framework ist, sorgt dafür, dass nach einer Programm-Exception ein Reset ausgelöst wird. Da dadurch der Fehler nicht behoben wird, wird erneut ein Reset ausgelöst. So geht es dann endlos weiter. Wenn man dann noch Ausgaben über die serielle auf ein Terminal macht, gibt es dort schnell eine Pufferüberlauf.
Aus diesem Grund macht es Sinn, den Grund für den Reset abzufragen und bei einem nicht erwarteten Grund die Ausführung zu stoppen. Der folgende Code zeigt ein Beispiel:
...
#include <UrsEsp.h>
using namespace UrsCPU;
...
void setup() {
Serial.begin(115200);
Serial.println("\n" APP_NAME " gestartet. Version: " APP_VERSION "\n");
auto resetReason = UrsESP.getResetReason(0);
Serial.printf("CPU0 Reset Grund: %i (%s) %s\n", resetReason, UrsESP.getResetReasonName(resetReason).c_str(), UrsESP.getResetReasonDescription(resetReason).c_str());
// Interne Fehler führen dauernd zu einem neuen Reset
// Reason 1: POWER_ON_RESET
// Reason 12: SW_CPU_RESET (z.B. nach OTA)
if (resetReason != 1 && resetReason != 12)
while (1);
Das ZIP-Archiv für Bibliothek UrsEsp zum Download. Die entpackten Dateien ins Verzeichnis <user>\Documents\Arduino\libraries kopieren (siehe Installing Additional Arduino Libraries).