MicroPython manifest datoteke

Sažetak

MicroPython ima značajku koja omogućuje da se Python kod „zamrzne” u ugrađeni program (firmware), kao alternativa učitavanju koda iz datotečnog sustava.

To donosi sljedeće prednosti:

  • kod je unaprijed preveden u bytecode, čime se izbjegava potreba za prevođenjem Python izvornog koda pri učitavanju.

  • bytecode se može izvršavati izravno iz ROM-a (tj. flash memorije) umjesto da se kopira u RAM. Slično tome, svi konstantni objekti (nizovi, n-torke itd.) također se učitavaju iz ROM-a. To može dovesti do znatno više dostupne memorije za vašu aplikaciju.

  • na uređajima koji nemaju datotečni sustav, ovo je jedini način za učitavanje Python koda.

Tijekom razvoja zamrzavanje općenito nije preporučljivo jer će znatno usporiti vaš razvojni ciklus, budući da će svako ažuriranje zahtijevati ponovno upisivanje cijelog ugrađenog programa (firmware). Međutim, i dalje može biti korisno selektivno zamrznuti neke ovisnosti koje se rijetko mijenjaju (poput biblioteka treće strane).

Način za navođenje Python datoteka koje će biti zamrznute u ugrađeni program (firmware) jest putem „manifesta”, što je Python datoteka koju će interpretirati proces izgradnje. Obično biste manifest datoteku napisali kao dio definicije ploče, ali možete napisati i samostalnu manifest datoteku te je upotrijebiti uz postojeću definiciju ploče.

Manifest datoteke mogu definirati ovisnosti o bibliotekama iz micropython-lib, kao i o Python datotekama u datotečnom sustavu te o drugim manifest datotekama.

Pisanje manifest datoteka

Manifest datoteka je Python datoteka koja sadrži niz poziva funkcija. Pogledajte dostupne funkcije definirane u nastavku.

Bilo koji put korišten u manifest datotekama može sadržavati sljedeće varijable. Sve se one razrješavaju u apsolutne putove.

  • $(MPY_DIR) – put do micropython repozitorija.

  • $(MPY_LIB_DIR) – put do micropython-lib podmodula. Radije upotrijebite require().

  • $(PORT_DIR) – put do trenutnog porta (npr. ports/stm32)

  • $(BOARD_DIR) – put do trenutne ploče (npr. ports/stm32/boards/OPENMV4)

Prilagođene manifest datoteke ne bi trebale postojati u glavnom MicroPython repozitoriju. Trebali biste ih čuvati pod kontrolom verzija zajedno s ostatkom vašeg projekta.

Obično će manifest korišten za prevođenje ugrađenog programa (firmware) morati uključiti manifest porta, koji može uključivati zamrznute module potrebne za rad ploče. Ako samo želite dodati dodatne module postojećoj ploči, tada uključite manifest ploče (koji će zauzvrat uključiti manifest porta).

Izgradnja s prilagođenim manifestom

Vaš se manifest može navesti u make naredbenom retku pomoću:

$ make BOARD=MYBOARD FROZEN_MANIFEST=/path/to/my/project/manifest.py

Ovo se odnosi na sve portove, uključujući one temeljene na CMake-u (npr. rp2), budući da će Makefile omotač to proslijediti u CMake izgradnju.

Dodavanje manifesta u definiciju ploče

Ako imate prilagođenu definiciju ploče, možete je natjerati da automatski uključi vaš prilagođeni manifest. Na portovima temeljenima na make-u (većina portova), u svom mpconfigboard.mk postavite varijablu FROZEN_MANIFEST.

FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py

Na portovima temeljenima na CMake-u (npr. rp2), umjesto toga upotrijebite mpconfigboard.cmake

set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)

Funkcije visoke razine

Ovo su funkcije koje ćete obično koristiti. One dodaju kod u skup koji se unaprijed prevodi u bytecode i zamrzava u sliku ugrađenog programa (firmware):

  • module i package zamrzavaju vaš vlastiti lokalni izvorni kod — pojedinačnu datoteku odnosno cijeli direktorij paketa.

  • require zamrzava objavljeni paket (i njegove ovisnosti) iz micropython-lib, prema imenu.

  • include povlači drugi manifest tako da se i njegovi zamrznuti moduli dodaju.

  • add_library i metadata su pomoćne funkcije (registriranje dodatnih putova za pretraživanje za require te deklariranje metapodataka paketa).

Tipičan manifest ugrađenog programa (firmware) najprije include-a manifest porta ili ploče (tako da moduli koje ploča treba ostanu zamrznuti), a zatim dodaje vlastite module/package/require retke.

Napomena: Imenovani argument opt može se postaviti na raznim funkcijama, on kontrolira razinu optimizacije koju koristi unakrsni prevoditelj. Pogledajte micropython.opt_level().

add_library(library, library_path, prepend=False)

Registrirajte put do vanjske imenovane library.

Upotrijebite ovo kada želite da require razriješi pakete iz direktorija koji nije micropython-lib — na primjer vaše vlastite zbirke upravljačkih programa ili preuzimanja biblioteke treće strane.

Put library_path automatski će se pretraživati pri korištenju require. Po zadanim postavkama dodana se biblioteka dodaje na kraj popisa biblioteka za pretraživanje. Proslijedite True za prepend kako biste je dodali na početak popisa.

Dodatno, dodana se biblioteka može eksplicitno zatražiti korištenjem require("name", library="library").

package(package_path, files=None, base_path='.', opt=None)

Zamrznite cijeli paket — direktorij .py datoteka (po želji s podpaketima) — tako da se može uvesti kao import <package>. Za pojedinačnu samostalnu datoteku umjesto toga upotrijebite module.

Ovo je ekvivalentno kopiranju direktorija „package_path” na uređaj (osim što je riječ o zamrznutom kodu).

U najjednostavnijem slučaju, za zamrzavanje paketa „foo” u trenutnom direktoriju:

package("foo")

rekurzivno će uključiti sve .py datoteke u foo i bit će zamrznute kao foo/**/*.py.

Ako paket nije u istom direktoriju kao manifest datoteka, upotrijebite base_path:

package("foo", base_path="path/to/libraries")

Možete koristiti gore navedene varijable, poput $(PORT_DIR) u base_path.

Za ograničavanje na određene datoteke u paketu upotrijebite files (napomena: putovi bi trebali biti relativni u odnosu na paket): package("foo", files=["bar/baz.py"]).

module(module_path, base_path='.', opt=None)

Zamrznite pojedinačnu samostalnu .py datoteku tako da se može uvesti pod svojim imenom (module("foo.py") omogućuje da import foo radi). Za direktorij/paket upotrijebite package.

Ako je datoteka u trenutnom direktoriju:

module("foo.py")

Inače upotrijebite base_path za lociranje datoteke:

module("foo.py", base_path="src/drivers")

Možete koristiti gore navedene varijable, poput $(PORT_DIR) u base_path.

require(name, library=None)

Zatražite paket prema imenu (i njegove ovisnosti) iz micropython-lib.

Ovako se zamrzavaju proširenja standardne biblioteke i upravljački programi zajednice: imenovani paket dohvaća se iz micropython-lib podmodula i zamrzava zajedno sa svime o čemu ovisi. Za zamrzavanje vlastitog izvornog koda umjesto objavljenog paketa upotrijebite module ili package.

Po želji navedite library (niz) za referenciranje paketa iz biblioteke koja je prethodno registrirana s add_library. U suprotnom će se koristiti popis putova biblioteka.

include(manifest_path)

Uključite drugi manifest. Ovako se manifesti sastavljaju: prilagođeni manifest ugrađenog programa (firmware) trebao bi include-ati manifest porta (ili ploče) kako bi moduli koje ploča treba ostali zamrznuti, a zatim dodati vlastite unose.

Obično će manifest korišten za prevođenje ugrađenog programa (firmware) morati uključiti manifest porta, koji može uključivati zamrznute module potrebne za rad ploče.

Argument manifest može biti niz (naziv datoteke) ili iterabilan objekt nizova.

Relativni putovi razrješavaju se u odnosu na trenutnu manifest datoteku.

Ako put vodi do direktorija, tada implicitno uključuje datoteku manifest.py unutar tog direktorija.

Možete koristiti gore navedene varijable, poput $(PORT_DIR) u manifest_path.

metadata(description=None, version=None, license=None, author=None)

Definirajte metapodatke za ovu manifest datoteku. Ovo je korisno za manifeste micropython-lib paketa.

Ova se polja konzumiraju kada se paket objavljuje na / instalira iz micropython-lib putem mip; nisu potrebna u manifestu ugrađenog programa (firmware) ploče.

Funkcije niske razine

Ove su funkcije dokumentirane radi potpunosti, ali se uz iznimku freeze_as_str sva funkcionalnost može pristupiti putem funkcija visoke razine.

Funkcije freeze* razlikuju se samo u tome kako se kod pohranjuje:

  • freeze_as_mpy / freeze_mpy pohranjuju unaprijed prevedeni bytecode (.mpy) u flash. Kod se izvršava izravno iz flash memorije, koristi minimalnu količinu RAM-a i brzo se uvozi. To je ono što module, package i require koriste interno.

  • freeze_as_str umjesto toga zamrzava Python izvorni kod, koji se prevodi u bytecode u trenutku uvoza (koristeći RAM i zahtijevajući prevoditelj na uređaju). To je jedina mogućnost koju funkcije visoke razine ne izlažu, što je razlog zašto je gore navedena kao iznimka.

freeze(path, script=None, opt=0)

Temeljni primitiv na kojem se grade funkcije visoke razine; radije koristite njih. Zamrznite ulaz naveden s path, automatski određujući njegov tip. .py skripta najprije će se prevesti u .mpy, a zatim zamrznuti, a .mpy datoteka bit će zamrznuta izravno.

path mora biti direktorij, koji je osnovni direktorij za početak pretraživanja datoteka. Pri uvozu rezultirajućih zamrznutih modula, naziv modula počinjat će nakon path, tj. path je isključen iz naziva modula.

Ako je path relativan, razrješava se u odnosu na trenutni manifest.py.

Ako je script None, sve datoteke u path bit će zamrznute.

Ako je script iterabilan, tada se freeze() poziva na svim stavkama iterabilnog objekta (uz proslijeđene iste path i opt).

Ako je script niz, tada on navodi datoteku ili direktorij za zamrzavanje i može sadržavati dodatne direktorije ispred datoteke ili posljednjeg direktorija. Datoteka ili direktorij tražit će se u path. Ako je script direktorij, tada će sve datoteke u tom direktoriju biti zamrznute.

opt je razina optimizacije koja se prosljeđuje u mpy-cross pri prevođenju .py u .mpy. Te su razine opisane u micropython.opt_level().

freeze_as_str(path)

Zamrznite navedeni path i sve .py skripte unutar njega kao niz, koji će se prevesti pri uvozu. Koristite ovo samo kada zamrznuti kod mora ostati Python izvorni kod; to košta RAM-a u trenutku uvoza u usporedbi s .mpy varijantama.

freeze_as_mpy(path, script=None, opt=0)

Zamrznite ulaz tako da najprije prevedete .py skripte u .mpy datoteke, a zatim zamrznete rezultirajuće .mpy datoteke. To je ono što module i package rade u pozadini. Pogledajte freeze() za dodatne pojedinosti o argumentima.

freeze_mpy(path, script=None, opt=0)

Zamrznite ulaz, koji mora biti .mpy datoteke koje se zamrzavaju izravno (bez koraka prevođenja). Pogledajte freeze() za dodatne pojedinosti o argumentima.

Primjeri

Za zamrzavanje pojedinačne datoteke iz trenutnog direktorija koja će biti dostupna kao import mydriver, upotrijebite:

module("mydriver.py")

Za zamrzavanje direktorija datoteka u poddirektoriju „mydriver” trenutnog direktorija koji će biti dostupan kao import mydriver, upotrijebite:

package("mydriver")

Za zamrzavanje „hmac” biblioteke iz micropython-lib, upotrijebite:

require("hmac")

Potpuniji primjer prilagođene manifest.py datoteke (za ploču koja ima vlastiti zadani manifest) jest:

# Include the board's default manifest.
include("$(BOARD_DIR)/manifest.py")
# Add a custom driver
module("mydriver.py")
# Add aiorepl from micropython-lib
require("aiorepl")

Tada se ploča može prevesti s

$ cd ports/stm32
$ make BOARD=MYBOARD FROZEN_MANIFEST=~/src/myproject/manifest.py

Imajte na umu da većina ploča nema vlastiti manifest.py, već izravno koriste onaj porta, u kojem slučaju bi vaš manifest umjesto toga trebao samo include("$(PORT_DIR)/boards/manifest.py").