14.2.2.1. Membekukan skrip ke dalam firmware¶
Sebuah modul frozen adalah berkas .py yang dikompilasi menjadi bytecode dan dihubungkan ke dalam citra firmware pada saat build. Runtime mengimpor modul frozen langsung dari flash, tanpa pernah memeriksa filesystem di disk. Untuk produk yang dikirimkan, inilah tempat yang tepat untuk kode aplikasi: tidak ada yang bisa dihapus oleh pengguna akhir, tidak ada .py yang basi di kartu SD yang bisa menggantikannya, dan kamera menjalankan kode yang sama setiap kali boot terlepas dari apa (jika ada) yang ada di drive-nya.
Halaman ini mencakup urutan startup yang diikuti oleh kamera, kemudian bagaimana manifest.py dan direktif freeze memanggang sebuah aplikasi ke dalam build.
14.2.2.1.1. Urutan startup¶
Apa yang berjalan, dan kapan, pada kamera yang baru keluar dari reset:
Bootloader. Daya masuk mengaktifkan jendela DFU singkat yang digunakan IDE untuk mendorong pembaruan firmware. Jendela ditutup setelah beberapa detik dan bootloader menyerahkan kendali ke MicroPython. Skrip yang berjalan dapat masuk kembali ke jendela ini sesuai permintaan dengan memanggil
machine.bootloader().Inisialisasi filesystem frozen. Sebelum kode aplikasi apa pun berjalan, runtime mempersiapkan filesystem. Flash internal dipasang di
/flash(dan diformat kosong jika tidak ada apa pun di sana). Jika kartu SD ada dan berkas penanda bernamaSKIPSDtidak ada di flash internal, kartu SD dipasang di/sdcard. ROMFS, ketika build menyertakannya, dipasang secara otomatis di/rom. Direktori kerja diatur ke direktori boot (/sdcardjika kartu terpasang,/flashjika tidak), dansys.pathdiisi dengan/flash,/flash/lib,/sdcard,/sdcard/lib,/rom, dan/rom/lib. Pengaturan yang berada di flash ditangani oleh modul frozen bernama_boot.py-- infrastruktur port dan board, bukan hook aplikasi. Aplikasi tidak mengkustomisasi_boot.py; build yang melakukannya. Menjatuhkan berkasSKIPSDke flash dari IDE adalah cara yang didukung untuk membuat kamera boot dari flash internal, bukan dari kartu SD.Pengaturan pra-REPL.
boot.pyberjalan pada setiap soft reset -- cold boot,Ctrl-Ddari REPL, skrip yang berjalan mengembalikan hasil, dan pemulihan watchdog -- sebelum REPL dapat dijangkau. Tugasnya adalah mempersiapkan lingkungan tempat sisa sistem berjalan: jenis pengaturan yang dibutuhkan REPL, aplikasi, dan semua tooling pemulihan agar berfungsi. Ini bukan tempat aplikasi itu sendiri berada.main.pyadalah titik masuk aplikasi.Loop utama.
main.pyadalah loop utama aplikasi. Berjalan sekali saat cold boot, segera setelahboot.py. Tidak dijalankan ulang pada soft reset berikutnya -- kamera turun ke REPL sebagai gantinya. Asimetri tersebut penting untuk pengembangan (Ctrl-D turun ke REPL tanpa menjalankan ulang loop, sehingga pengembang dapat memeriksa status) tetapi tidak untuk produksi: kamera yang dikirimkan mengalami power-on, watchdog, dan hard reset, yang semuanya adalah hard reset perangkat keras yang masuk kembali ke jalur cold-boot dan menjalankanmain.pylagi.
14.2.2.1.2. Membekukan ke dalam firmware¶
Set modul frozen sebuah board dideklarasikan di boards/<TARGET>/manifest.py di pohon firmware. Manifest adalah berkas Python kecil yang memanggil sejumlah direktif:
freeze("$(OMV_LIB_DIR)/", "foo.py")-- memanggang satufoo.pyke dalam build.package("mylib", base_path="...")-- memanggang paket Python multi-berkas, mempertahankan tata letak direktorinya di bawah base path yang diberikan.include("...")-- menarik berkas manifest lain. Manifest board menggunakan ini untuk berbagi set modul umum.require("logging")-- menarik modulmicropython-libupstream yang bernama sesuai namanya.
Manifest aplikasi minimal menambahkan satu baris freeze per skrip tingkat atas dan satu baris package per paket yang digunakan aplikasi.
14.2.2.1.2.1. Lokasi sumber¶
Sumber aplikasi berada di bawah scripts/libraries/ di pohon firmware, berdampingan dengan modul yang sudah dibekukan oleh build. Variabel manifest $(OMV_LIB_DIR) diperluas ke jalur tersebut, sehingga entri manifest tetap singkat. Mengedit manifest sudah merupakan operasi dalam pohon, jadi menyimpan sumber dalam pohon menghindari pengelolaan repo proyek terpisah di resolusi jalur.
Tata letak tipikal untuk aplikasi yang mengirimkan satu main.py ditambah paket pendukung:
scripts/libraries/
main.py
my_lib/
__init__.py
helpers.py
Dan di boards/<TARGET>/manifest.py board, satu baris freeze untuk skrip dan satu baris package untuk paket:
freeze("$(OMV_LIB_DIR)/", "main.py")
package("my_lib", base_path="$(OMV_LIB_DIR)/my_lib")
Skrip berkas tunggal -- main.py di sini, tetapi aturan yang sama berlaku untuk boot.py atau helper mandiri apa pun -- menggunakan freeze. Paket multi-berkas menggunakan package. Menambahkan skrip lain berarti satu baris freeze lagi; menambahkan paket lain berarti satu baris package lagi.
14.2.2.1.2.2. Membangun dan mem-flash¶
Setelah manifest siap, build firmware persis seperti yang dijelaskan di bab firmware
make -j$(nproc) -C lib/micropython/mpy-cross # once, builds the cross-compiler
make -j$(nproc) TARGET=<TARGET> # builds the firmware
Output berada di build/<TARGET>/bin/
build/<TARGET>/bin/
firmware.bin # flash through the IDE
romfs0.img # flash through the IDE in a separate step
Men-flash .bin dan .img melalui IDE menghasilkan kamera yang aplikasinya merupakan bagian dari build.
Urutan startup di atas adalah yang membuat pemanggang efektif: runtime me-resolve boot.py dan main.py ke salinan frozen sebelum pernah memeriksa filesystem, sehingga kamera yang dikirimkan menjalankan kode build meskipun kartu SD menyimpan boot.py basi yang tersisa dari pengembangan.
14.2.2.1.2.3. Urutan pencarian¶
Semantik override berbeda untuk jalur eksekusi boot.py / main.py dan untuk pernyataan import biasa. Mengetahui mana yang mana penting untuk produksi maupun pengembangan:
Untuk
boot.pydanmain.py: runtime mencari salinan frozen terlebih dahulu, kemudian filesystem.boot.pyyang dibekukan tidak dapat ditimpa dengan menjatuhkannya ke kartu SD -- siapa pun yang memegang kamera tidak dapat mengubah titik masuk tanpa melakukan reflash.Untuk
import foo: runtime mencarisys.pathterlebih dahulu -- yang mencakup/flash,/sdcard,/rom, dan subdirektorilibmereka -- kemudian modul frozen.foo.pydengan nama yang sama di flash atau SD memang menimpafooyang dibekukan. Ini adalah fasilitas pengembangan: jatuhkan modul yang diperbaiki di kartu, soft-reset, lihat perubahan tanpa reflash.
Produk yang dikirimkan yang ingin menekan perilaku filesystem-menimpa-frozen untuk impor dapat menghapus sys.path di awal boot.py
import sys
sys.path.clear()
Dengan sys.path kosong, semua impor di-resolve hanya dari modul frozen; tidak ada di flash, SD, atau ROMFS yang dapat menutupinya.
14.2.2.1.2.4. Masalah aset¶
Pembekuan sangat bagus untuk kode. Ia tidak bagus untuk aset biner besar: berkas model machine learning, tabel label, konfigurasi JSON, template citra. Menyematkan ini sebagai literal Python membengkakkan sumber, kompilasi lambat, dan membuang container bytecode untuk data yang akan dibaca mentah-mentah oleh interpreter. Halaman Membangun citra ROMFS mencakup filesystem flash read-only yang mengisi kesenjangan ini.