File manifest MicroPython¶
Ringkasan¶
MicroPython memiliki fitur yang memungkinkan kode Python untuk "dibekukan" ke dalam firmware, sebagai alternatif dari memuat kode dari sistem file.
Ini memiliki manfaat berikut:
kode dikompilasi terlebih dahulu menjadi bytecode, sehingga tidak perlu mengompilasi sumber Python saat dimuat.
bytecode dapat dieksekusi langsung dari ROM (yaitu memori flash) alih-alih disalin ke RAM. Demikian pula, objek konstan apa pun (string, tuple, dll.) juga dimuat dari ROM. Ini dapat menyebabkan lebih banyak memori tersedia untuk aplikasi Anda.
pada perangkat yang tidak memiliki sistem file, ini adalah satu-satunya cara untuk memuat kode Python.
Selama pengembangan, pembekuan umumnya tidak disarankan karena akan sangat memperlambat siklus pengembangan Anda, karena setiap pembaruan akan memerlukan flashing ulang seluruh firmware. Namun, masih berguna untuk membekukan secara selektif beberapa dependensi yang jarang berubah (seperti perpustakaan pihak ketiga).
Cara untuk mendaftar file Python yang akan dibekukan ke dalam firmware adalah melalui "manifest", yang merupakan file Python yang akan diinterpretasikan oleh proses build. Biasanya Anda akan menulis file manifest sebagai bagian dari definisi board, tetapi Anda juga bisa menulis file manifest mandiri dan menggunakannya dengan definisi board yang sudah ada.
File manifest dapat mendefinisikan dependensi pada perpustakaan dari micropython-lib serta file Python di sistem file, dan juga pada file manifest lainnya.
Menulis file manifest¶
File manifest adalah file Python yang berisi serangkaian pemanggilan fungsi. Lihat fungsi-fungsi yang tersedia yang didefinisikan di bawah ini.
Setiap jalur yang digunakan dalam file manifest dapat menyertakan variabel-variabel berikut. Semuanya diselesaikan ke jalur absolut.
$(MPY_DIR)-- jalur ke repositori micropython.$(MPY_LIB_DIR)-- jalur ke submodul micropython-lib. Lebih baik gunakanrequire().$(PORT_DIR)-- jalur ke port saat ini (misalnyaports/stm32)$(BOARD_DIR)-- jalur ke board saat ini (misalnyaports/stm32/boards/OPENMV4)
File manifest kustom tidak boleh berada di repositori utama MicroPython. Anda harus menyimpannya dalam version control bersama dengan proyek Anda.
Biasanya manifest yang digunakan untuk mengompilasi firmware perlu menyertakan manifest port, yang mungkin mencakup modul yang dibekukan yang diperlukan agar board dapat berfungsi. Jika Anda hanya ingin menambahkan modul tambahan ke board yang sudah ada, maka sertakan manifest board (yang pada gilirannya akan menyertakan manifest port).
Membangun dengan manifest kustom¶
Manifest Anda dapat ditentukan pada baris perintah make dengan:
$ make BOARD=MYBOARD FROZEN_MANIFEST=/path/to/my/project/manifest.py
Ini berlaku untuk semua port, termasuk yang berbasis CMake (misalnya rp2), karena wrapper Makefile akan meneruskannya ke build CMake.
Menambahkan manifest ke definisi board¶
Jika Anda memiliki definisi board kustom, Anda dapat membuatnya menyertakan manifest kustom Anda secara otomatis. Pada port berbasis make (sebagian besar port), di mpconfigboard.mk Anda, setel variabel FROZEN_MANIFEST.
FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py
Pada port berbasis CMake (misalnya rp2), gunakan mpconfigboard.cmake
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
Fungsi tingkat tinggi¶
Ini adalah fungsi-fungsi yang biasanya Anda gunakan. Fungsi-fungsi ini menambahkan kode ke set yang dikompilasi lebih dahulu menjadi bytecode dan dibekukan ke dalam citra firmware:
moduledanpackagemembekukan sumber lokal Anda sendiri -- satu file atau seluruh direktori paket masing-masing.requiremembekukan paket yang diterbitkan (dan dependensinya) dari micropython-lib, berdasarkan nama.includemenarik manifest lain sehingga modul yang dibekukannya juga ditambahkan.add_librarydanmetadataadalah fungsi pendukung (mendaftarkan jalur pencarian tambahan untukrequire, dan mendeklarasikan metadata paket).
Manifest firmware yang umum pertama-tama includes manifest port atau board (sehingga modul yang dibutuhkan board tetap dibekukan), kemudian menambahkan entri module/package/require-nya sendiri.
Catatan: Argumen kata kunci opt dapat disetel pada berbagai fungsi, ini mengontrol tingkat optimisasi yang digunakan oleh kompiler silang. Lihat micropython.opt_level().
- add_library(library, library_path, prepend=False)¶
Daftarkan jalur ke library bernama eksternal.
Gunakan ini ketika Anda ingin
requiremenyelesaikan paket dari direktori selain micropython-lib -- misalnya koleksi driver Anda sendiri, atau checkout perpustakaan pihak ketiga.Jalur library_path akan dicari secara otomatis saat menggunakan
require. Secara default, perpustakaan yang ditambahkan ditambahkan ke akhir daftar perpustakaan yang akan dicari. TeruskanTrueke prepend untuk menambahkannya ke awal daftar.Selain itu, perpustakaan yang ditambahkan dapat diminta secara eksplisit menggunakan
require("name", library="library").
- package(package_path, files=None, base_path='.', opt=None)¶
Bekukan seluruh paket -- direktori file
.py(opsional dengan sub-paket) -- sehingga dapat diimpor sebagaiimport <package>. Gunakanmodulesebagai gantinya untuk satu file mandiri.Ini setara dengan menyalin direktori "package_path" ke perangkat (kecuali sebagai kode yang dibekukan).
Dalam kasus paling sederhana, untuk membekukan paket "foo" di direktori saat ini:
package("foo")akan secara rekursif menyertakan semua file .py di foo, dan akan dibekukan sebagai
foo/**/*.py.Jika paket tidak ada di direktori yang sama dengan file manifest, gunakan
base_path:package("foo", base_path="path/to/libraries")Anda dapat menggunakan variabel di atas, seperti
$(PORT_DIR)dibase_path.Untuk membatasi file tertentu dalam paket, gunakan
files(catatan: jalur harus relatif terhadap paket):package("foo", files=["bar/baz.py"]).
- module(module_path, base_path='.', opt=None)¶
Bekukan satu file
.pymandiri sehingga dapat diimpor dengan namanya (module("foo.py")membuatimport fooberfungsi). Gunakanpackageuntuk direktori/paket.Jika file ada di direktori saat ini:
module("foo.py")Jika tidak, gunakan base_path untuk menemukan file:
module("foo.py", base_path="src/drivers")Anda dapat menggunakan variabel di atas, seperti
$(PORT_DIR)dibase_path.
- require(name, library=None)¶
Membutuhkan paket berdasarkan nama (dan dependensinya) dari micropython-lib.
Inilah cara ekstensi perpustakaan standar dan driver komunitas dibekukan: paket yang disebutkan diambil dari submodul micropython-lib dan dibekukan bersama dengan semua yang bergantung padanya. Gunakan
moduleataupackagesebagai gantinya untuk membekukan sumber Anda sendiri daripada paket yang diterbitkan.Secara opsional tentukan library (string) untuk merujuk paket dari perpustakaan yang sebelumnya telah didaftarkan dengan
add_library. Jika tidak, daftar jalur perpustakaan akan digunakan.
- include(manifest_path)¶
Sertakan manifest lain. Inilah cara manifest dikompilasi: manifest firmware kustom harus
includemanifest port (atau board) sehingga modul yang dibutuhkan board tetap dibekukan, kemudian menambahkan entri-entri miliknya sendiri.Biasanya manifest yang digunakan untuk mengompilasi firmware perlu menyertakan manifest port, yang mungkin mencakup modul yang dibekukan yang diperlukan agar board dapat berfungsi.
Argumen manifest bisa berupa string (nama file) atau iterable berisi string.
Jalur relatif diselesaikan berdasarkan file manifest saat ini.
Jika jalur menuju ke direktori, maka secara implisit menyertakan file manifest.py di dalam direktori tersebut.
Anda dapat menggunakan variabel di atas, seperti
$(PORT_DIR)dimanifest_path.
- metadata(description=None, version=None, license=None, author=None)¶
Definisikan metadata untuk file manifest ini. Ini berguna untuk manifest paket micropython-lib.
Kolom-kolom ini digunakan saat paket diterbitkan ke / dipasang dari micropython-lib melalui mip; kolom-kolom ini tidak diperlukan dalam manifest firmware board.
Fungsi tingkat rendah¶
Fungsi-fungsi ini didokumentasikan untuk kelengkapan, tetapi dengan pengecualian freeze_as_str semua fungsionalitas dapat diakses melalui fungsi tingkat tinggi.
Fungsi-fungsi freeze* berbeda hanya dalam cara kode disimpan:
freeze_as_mpy/freeze_mpymenyimpan bytecode yang dikompilasi lebih dahulu (.mpy) di flash. Kode berjalan langsung dari flash, menggunakan RAM minimal, dan diimpor dengan cepat. Inilah yang digunakanmodule,package, danrequiresecara internal.freeze_as_strsebaliknya membekukan sumber Python, yang dikompilasi menjadi bytecode saat impor (menggunakan RAM, dan memerlukan kompiler di perangkat). Ini adalah satu kemampuan yang tidak diekspos oleh fungsi tingkat tinggi, itulah mengapa ini merupakan pengecualian yang disebutkan di atas.
- freeze(path, script=None, opt=0)¶
Primitif dasar tempat fungsi tingkat tinggi dibangun; lebih baik gunakan fungsi-fungsi tersebut. Bekukan input yang ditentukan oleh path, secara otomatis menentukan jenisnya. Skrip
.pyakan dikompilasi terlebih dahulu ke.mpylalu dibekukan, dan file.mpyakan dibekukan langsung.path harus berupa direktori, yang merupakan direktori dasar untuk mulai mencari file. Saat mengimpor modul yang dibekukan yang dihasilkan, nama modul akan dimulai setelah path, yaitu path dikecualikan dari nama modul.
Jika path relatif, maka diselesaikan ke
manifest.pysaat ini.Jika script adalah None, semua file di path akan dibekukan.
Jika script adalah iterable, maka
freeze()dipanggil pada semua item iterable (dengan path dan opt yang sama diteruskan).Jika script adalah string maka itu menentukan file atau direktori yang akan dibekukan, dan dapat menyertakan direktori tambahan sebelum file atau direktori terakhir. File atau direktori akan dicari di path. Jika script adalah direktori, maka semua file di direktori tersebut akan dibekukan.
opt adalah tingkat optimisasi yang akan diteruskan ke mpy-cross saat mengompilasi
.pyke.mpy. Tingkat-tingkat ini dijelaskan dalammicropython.opt_level().
- freeze_as_str(path)¶
Bekukan path yang diberikan dan semua skrip
.pydi dalamnya sebagai string, yang akan dikompilasi saat impor. Gunakan ini hanya jika kode yang dibekukan harus tetap berupa sumber Python; ini membutuhkan RAM saat impor dibandingkan dengan varian.mpy.
- freeze_as_mpy(path, script=None, opt=0)¶
Bekukan input dengan terlebih dahulu mengompilasi skrip
.pyke file.mpy, kemudian membekukan file.mpyyang dihasilkan. Inilah yang dilakukanmoduledanpackagedi balik layar. Lihatfreeze()untuk detail lebih lanjut tentang argumen.
- freeze_mpy(path, script=None, opt=0)¶
Bekukan input, yang harus berupa file
.mpyyang dibekukan langsung (tanpa langkah kompilasi). Lihatfreeze()untuk detail lebih lanjut tentang argumen.
Contoh¶
Untuk membekukan satu file dari direktori saat ini yang akan tersedia sebagai import mydriver, gunakan:
module("mydriver.py")
Untuk membekukan direktori file dalam subdirektori "mydriver" dari direktori saat ini yang akan tersedia sebagai import mydriver, gunakan:
package("mydriver")
Untuk membekukan perpustakaan "hmac" dari micropython-lib, gunakan:
require("hmac")
Contoh yang lebih lengkap dari file manifest.py kustom (untuk board yang memiliki manifest defaultnya sendiri) adalah:
# 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")
Kemudian board dapat dikompilasi dengan
$ cd ports/stm32
$ make BOARD=MYBOARD FROZEN_MANIFEST=~/src/myproject/manifest.py
Perhatikan bahwa sebagian besar board tidak memiliki manifest.py sendiri, melainkan menggunakan manifest port secara langsung, dalam hal ini manifest Anda hanya perlu include("$(PORT_DIR)/boards/manifest.py") sebagai gantinya.