Z notýsku vývojáře – Jak zachytit občasný pád aplikace v ESP8266

Dříve, nebo později se s tím setká každý, kdo tvoří aplikace na mikrokontroléry – skvělá, téměř hotová aplikace občas spadne. Ne tak často, aby se pád dal zachytit debuggerem (pokud se dá k hardware vůbec připojit), ale příliš často na to, aby bylo možné pády ignorovat. Stává se to i při programování ESP8266 a to častěji, než by se mohlo zdát (ti, kdo používají intenzívně komunikující sériový port pomocí knihovny SoftwareSerial o tom zcela nepochybně ví své). Ladění těchto situací bývá velmi obtížné a zdlouhavé, ale naštěstí pro nás existuje v případě ESP8266 cesta, jak si práci usnadnit. SDK, poskytované přímo od Espressif obsahuje možnost, jak při pádu aplikace zavolat uživatelskou funkci, která se jmenuje custom_crash_callback(…). Funkce je volaná z postmortem stavu přímo z jádra (weak alias je definovaný v core_esp8266_postmortem.c ). Její použití ale má nějaká úskalí – nesmí se použít dynamická alokace, blokovací funkce (serial, network, delay, …) a vykonání funkce nesmí trvat příliš dlouho, protože HW watchdog stále běží. Nápad tedy spočívá v tom, že se do EEPROM uloží informace o pádu, které se dají použít pro následnou analýzu. Tento nápad mělo přede mnou už více vývojářů, takže vznikla knihovna EspSaveCrash, která ale bohužel ignoruje zapovězení dynamické alokace, takže pokud vznikl pád aplikace z důvodu problému na heapu, EspSaveCrash nebude fungovat správně. Napsal jsem tedy vlastní variantu, která vychází z uvedené knihovny, ale netrpí tímto neduhem a kterou používám již řadu měsíců.

Nejdříve je třeba říct, že se nejedná o knihovnu v pravém slova smyslu – jedná se o samostatný .ino soubor, který je umístěný ve stejném adresáři, jako hlavní skript. Využívám zde vlastnosti, kdy ArduinoBuilder/PIO při každé kompilaci nejdříve sestaví pro překlad dočasný soubor, který sestává z vhodně poskládaných všech .ino, které jsou nalezeny v adresáři projektu.

Modul poskytuje tyto funkce:

void crashClear(void) – vymaže všechny informace o záznamech předchozích pádů.

void crashGet(String &out) – vrátí HTML formátovaný seznam zaznamenaných pádů včetně všech zaznamenaných informací.

int crashGetCount(void) – vrátí počet zaznamenaných pádů.

int crashSanityCheck(void) – ověří stav oblasti pro zaznamenávání pádů.

Ve svých aplikacích to používám tak, že na crashClear namířím webovou stránku cc (abych z webového rozhraní mohl vymazat staré záznamy/poprvé nainicializovat oblast), no a crashGet mi doplní text do webové stránky cg, takže vidím všechny zaznamenané pády přímo v prohlížeči.

Konfigurace je velmi jednoduchá – předpokládám definici indexu v EEPROM, do kterého se budou záznamy ukládat (SAVE_CRASH_EEPROM_OFFSET) a velikost EEPROM vyhrazenou pro záznamy pádů (SAVE_CRASH_SPACE_SIZE). EEPROM musí být spuštěna v uživatelské aplikaci (EEPROM.begin(…) ) a je na tvůrci aplikace, aby zajistil vyhrazení odpovídající velikosti pro práci crash.ino .

Modul byl testován s Core verze 2.3.0, 2.4.0 a git verze.

No a na závěr vlastní modul ke stažení:

Crash
Crash
crash.zip
2.1 KiB
17 Downloads
Details

Pro zvídavější jsou zde odkazy k dalšímu studiu:

http://arduino-esp8266.readthedocs.io/en/latest/faq/a02-my-esp-crashes.html

https://github.com/SuperHouse/esp-open-rtos/wiki/Crash-Dumps

https://github.com/esp8266/Arduino/issues/1152

2 thoughts on “Z notýsku vývojáře – Jak zachytit občasný pád aplikace v ESP8266”

  1. Napad je to dobry, ale potreba take rici jak pak nalozit s daty. Jak v nich cist?

    Protoze me treba toto nic nerika:
    Stack: SP=0x3fff5040
    0x3fff5040: 00000000 00000000 00000000 00000000
    0x3fff5050: 00000000 a5a5a5a5 a5a5a5a5 00000290
    0x3fff5060: 3fff5408 00000000 00000000 00000000
    0x3fff5070: 00000000 00000000 00000000 00000000
    0x3fff5080: 00000000 00000000 00000000 00000000
    0x3fff5090: 00000000 00000000 00000000 00000000
    0x3fff50a0: 00000000 00000000 00000000 00000000
    0x3fff50b0: 00000000 00000000 00000000 00000000

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *