14.2.2.1. Zmrazení skriptů do firmwaru¶
Zmrazený (frozen) modul je soubor .py zkompilovaný do bytekódu a slinkovaný do obrazu firmwaru během sestavení. Běhové prostředí importuje zmrazený modul přímo z flash paměti, aniž by se kdy podívalo na souborový systém na disku. U dodávaného produktu je toto správné místo pro aplikační kód: koncový uživatel nemá co smazat, žádný zastaralý .py na SD kartě jej nemůže přepsat a kamera při každém spuštění spouští stejný kód bez ohledu na to, co (pokud vůbec něco) je na jejích discích.
Tato stránka popisuje spouštěcí sekvenci, kterou kamera prochází, a poté to, jak manifest.py a direktiva freeze zapečou aplikaci do sestavení.
14.2.2.1.1. Spouštěcí sekvence¶
Co se spouští a kdy na kameře vycházející z resetu:
Bootloader. Po zapnutí se vstoupí do krátkého okna DFU, které IDE používá k nahrávání aktualizací firmwaru. Okno se po několika sekundách zavře a bootloader předá řízení MicroPythonu. Běžící skript může do tohoto okna na vyžádání znovu vstoupit voláním
machine.bootloader().Inicializace zmrazeného souborového systému. Před spuštěním jakéhokoli aplikačního kódu běhové prostředí spustí souborové systémy. Interní flash paměť je připojena na
/flash(a naformátována načisto, pokud tam nic není). Pokud je přítomna SD karta a na interní flash paměti neexistuje značkovací soubor s názvemSKIPSD, je SD karta připojena na/sdcard. ROMFS, pokud jej sestavení obsahuje, je automaticky připojen na/rom. Pracovní adresář je nastaven na spouštěcí adresář (/sdcard, pokud byla karta připojena, jinak/flash) asys.pathje naplněna hodnotami/flash,/flash/lib,/sdcard,/sdcard/lib,/roma/rom/lib. Nastavení rezidentní ve flash paměti je obstaráno zmrazeným modulem s názvem_boot.py– jde o infrastrukturu portu a desky, nikoli o aplikační háček. Aplikace_boot.pynepřizpůsobují; dělá to sestavení. Vložení souboruSKIPSDna flash paměť z IDE je podporovaný způsob, jak přimět kameru spustit se z interní flash paměti namísto z SD karty.Nastavení před REPL.
boot.pyse spustí při každém měkkém resetu – studeném startu,Ctrl-Dz REPL, návratu běžícího skriptu i obnovení po watchdogu – předtím, než se REPL stane dostupným. Jeho úkolem je připravit prostředí, ve kterém běží zbytek systému: takový druh nastavení, které REPL, aplikace i jakékoli nástroje pro obnovu potřebují mít na svém místě, aby fungovaly. Není to místo, kde sídlí samotná aplikace.main.pyje vstupní bod aplikace.Hlavní smyčka.
main.pyje hlavní smyčka aplikace. Spustí se jednou při studeném startu, ihned poboot.py. Nespouští se znovu při následujících měkkých resetech – kamera místo toho přejde do REPL. Tato asymetrie je důležitá pro vývoj (Ctrl-D přejde do REPL bez opětovného spuštění smyčky, takže vývojář může zkontrolovat stav), ale nikoli pro produkci: nasazená kamera vidí zapnutí napájení, watchdog a tvrdé resety, což jsou vesměs hardwarové resety, které znovu vstupují do cesty studeného startu a opět spouštějímain.py.
14.2.2.1.2. Zmrazení do firmwaru¶
Sada zmrazených modulů desky je deklarována v souboru boards/<TARGET>/manifest.py ve stromu firmwaru. Manifest je malý soubor v Pythonu, který volá hrstku direktiv:
freeze("$(OMV_LIB_DIR)/", "foo.py")– zapeče jedinýfoo.pydo sestavení.package("mylib", base_path="...")– zapeče vícesouborový Python balíček a zachová jeho adresářové rozložení pod zadanou základní cestou.include("...")– vtáhne jiný soubor manifestu. Manifesty desek to používají ke sdílení společných sad modulů.require("logging")– vtáhne pojmenovaný upstreamový modulmicropython-libpodle názvu.
Minimální aplikační manifest přidává jeden řádek freeze na každý skript nejvyšší úrovně a jeden řádek package na každý balíček, na kterém aplikace závisí.
14.2.2.1.2.1. Kde se nachází zdrojový kód¶
Zdrojový kód aplikace se nachází v scripts/libraries/ ve stromu firmwaru, vedle modulů, které sestavení již zmrazuje. Proměnná manifestu $(OMV_LIB_DIR) se rozvine na tuto cestu, takže záznamy v manifestu zůstávají krátké. Úprava manifestu je již operací uvnitř stromu, takže ponechání zdrojového kódu uvnitř stromu vás zbaví žonglování se samostatným repozitářem projektu při řešení cest.
Typické rozložení pro aplikaci, která dodává jediný main.py plus podpůrný balíček:
scripts/libraries/
main.py
my_lib/
__init__.py
helpers.py
A v souboru boards/<TARGET>/manifest.py desky jeden řádek freeze pro skript a jeden řádek package pro balíček:
freeze("$(OMV_LIB_DIR)/", "main.py")
package("my_lib", base_path="$(OMV_LIB_DIR)/my_lib")
Jednosouborové skripty – zde main.py, ale stejné pravidlo platí pro boot.py nebo jakýkoli samostatný pomocný soubor – používají freeze. Vícesouborové balíčky používají package. Přidání dalšího skriptu znamená jeden řádek freeze navíc; přidání dalšího balíčku znamená jeden řádek package navíc.
14.2.2.1.2.2. Sestavení a flashování¶
Jakmile je manifest na svém místě, sestavte firmware přesně tak, jak popisuje kapitola o firmwaru
make -j$(nproc) -C lib/micropython/mpy-cross # once, builds the cross-compiler
make -j$(nproc) TARGET=<TARGET> # builds the firmware
Výstup přistane v build/<TARGET>/bin/
build/<TARGET>/bin/
firmware.bin # flash through the IDE
romfs0.img # flash through the IDE in a separate step
Flashování .bin a .img přes IDE vytvoří kameru, jejíž aplikace je součástí sestavení.
Výše uvedená spouštěcí sekvence je tím, co činí zapečení účinným: běhové prostředí překládá boot.py a main.py na zmrazené kopie ještě předtím, než vůbec zkontroluje souborový systém, takže dodaná kamera spouští kód ze sestavení, i když SD karta obsahuje zastaralý boot.py ponechaný z vývoje.
14.2.2.1.2.3. Pořadí vyhledávání¶
Sémantika přepisování je odlišná pro cestu spouštění boot.py / main.py a pro běžné příkazy import. Vědět, co je co, je důležité pro produkci i pro vývoj:
Pro
boot.pyamain.py: běhové prostředí nejprve hledá zmrazenou kopii a teprve poté souborový systém. Zmrazenýboot.pynelze přepsat vložením jiného na SD kartu – kdokoli kameru drží v ruce, nemůže změnit vstupní bod bez opětovného flashování.Pro
import foo: běhové prostředí nejprve prohledásys.path– která pokrývá/flash,/sdcard,/roma jejich podadresářelib– a poté zmrazené moduly. Stejnojmennýfoo.pyna flash paměti nebo SD kartě zmrazenýfooskutečně přepíše. To je vývojová výhoda: vložte opravený modul na kartu, proveďte měkký reset a uvidíte změnu bez opětovného flashování.
Dodávaný produkt, který chce u importů potlačit chování, kdy souborový systém přepisuje zmrazené moduly, může vyčistit sys.path na začátku boot.py
import sys
sys.path.clear()
Když je sys.path prázdná, všechny importy se rozpoznávají pouze ze zmrazených modulů; nic na flash paměti, SD kartě ani ROMFS je nemůže zastínit.
14.2.2.1.2.4. Problém s aktivy¶
Zmrazení je skvělé pro kód. Není skvělé pro velká binární aktiva: soubory modelů strojového učení, tabulky štítků, konfiguraci JSON, šablony obrazů. Vložení těchto dat jako literálů v Pythonu nafoukne zdrojový kód, zpomalí rekompilaci a zbytečně plýtvá kontejnerem bytekódu na data, která interpret stejně jen přečte v surové podobě. Stránka Sestavení obrazu ROMFS popisuje souborový systém ve flash paměti určený jen pro čtení, který tuto mezeru vyplňuje.