Urutan Reset dan Boot

Perangkat yang menjalankan MicroPython mengikuti urutan boot tertentu untuk memulai dan menginisialisasi dirinya sendiri setelah reset.

Catatan

Urutan _boot.pyboot.pymain.py → REPL yang dijelaskan di bawah ini adalah yang dijalankan firmware pada setiap reset, terlepas dari bagaimana Anda terhubung — sehingga selalu berlaku. Saat Anda menjalankan skrip dari OpenMV IDE, IDE menghentikan main.py yang sedang berjalan dan menjalankan skrip yang terbuka di editor sebagai gantinya, melalui protokol debug miliknya sendiri. IDE tidak menggunakan REPL yang ada di perangkat, sehingga referensi khusus REPL di halaman ini (prompt interaktif, Ctrl-D / Ctrl-C di terminal serial, dll.) berlaku untuk operasi mandiri dan sesi terminal serial langsung — tetapi urutan boot itu sendiri berlaku dalam semua kasus.

Hard reset

Boot dari hard reset adalah yang terjadi ketika board pertama kali dinyalakan, yaitu cold boot. Ini adalah reset lengkap dari perangkat keras MCU.

Kode port MicroPython menginisialisasi semua perangkat keras penting (termasuk clock dan regulator daya tertanam, UART serial internal, dll), kemudian memulai lingkungan MicroPython. Konfigurasi RTC yang ada mungkin dipertahankan setelah hard reset, tetapi semua status perangkat keras lainnya dihapus.

Urutan boot hard reset yang sama dapat dipicu oleh sejumlah kejadian seperti:

  • Kode Python yang mengeksekusi machine.reset().

  • Pengguna menekan tombol Reset fisik pada board (jika ada).

  • Bangun dari deep sleep (pada sebagian besar port).

  • Reset watchdog perangkat keras MCU.

  • Detektor brown out perangkat keras MCU.

Detail pemicu reset spesifik perangkat keras bergantung pada port dan perangkat keras terkait. Fungsi machine.reset_cause() dapat digunakan untuk menentukan lebih lanjut penyebab reset.

Soft Reset

Ketika MicroPython sudah berjalan, dimungkinkan untuk memicu soft reset dengan mengetik Ctrl-D di REPL atau mengeksekusi machine.soft_reset().

Soft reset menghapus interpreter Python, membebaskan semua memori Python, dan memulai kembali lingkungan MicroPython.

Status yang dihapus oleh soft reset meliputi:

  • Semua variabel Python, objek, modul yang diimpor, dll.

  • Sebagian besar periferal yang dikonfigurasi menggunakan modul machine. Ada pengecualian yang sangat terbatas, misalnya mode machine.Pin (yaitu apakah pin adalah input atau output, tinggi atau rendah) tidak direset pada sebagian besar port. Konfigurasi lebih lanjut seperti Pin.irq() selalu direset.

  • Bluetooth.

  • Socket jaringan. Socket TCP terbuka ditutup dengan bersih terhadap pihak lain.

  • File terbuka. Sistem file dibiarkan dalam keadaan valid.

Beberapa status sistem tetap sama setelah soft reset, termasuk:

  • Koneksi jaringan yang ada (Ethernet, Wi-Fi, dll) tetap aktif di lapisan IP Network. Menanyakan antarmuka jaringan dari kode mungkin menunjukkan bahwa antarmuka jaringan masih aktif dengan alamat IP yang dikonfigurasi, dll.

  • Sebuah REPL yang aktif tampak berkelanjutan sebelum dan sesudah soft reset, kecuali dalam beberapa kasus yang tidak biasa:

    • REPL UART serial akan memulihkan konfigurasi perangkat keras bawaannya (laju baud, dll).

  • Kecepatan clock CPU biasanya tidak diubah oleh soft reset.

  • Konfigurasi RTC (yaitu pengaturan waktu saat ini) tidak diubah oleh soft reset.

Urutan Boot

Ketika MicroPython boot setelah hard reset atau soft reset, ia mengikuti urutan boot ini secara berurutan:

_boot.py

Ini adalah skrip internal yang dibekukan ke dalam firmware MicroPython. Ini disediakan oleh MicroPython pada banyak port untuk melakukan inisialisasi penting.

Misalnya, pada sebagian besar port _boot.py akan mendeteksi boot pertama perangkat baru dan memformat sistem file flash internal siap untuk digunakan.

Kecuali Anda membuat build MicroPython kustom atau menambahkan port baru, Anda mungkin tidak perlu khawatir tentang _boot.py. Sebaiknya jangan mengubah isinya kecuali Anda benar-benar tahu apa yang Anda lakukan.

boot.py

File bernama boot.py dapat disalin ke sistem file internal board menggunakan mpremote.

Jika boot.py ditemukan maka ia akan dieksekusi. Anda dapat menambahkan kode di boot.py untuk melakukan inisialisasi kustom sekali waktu (misalnya, untuk mengonfigurasi perangkat keras board).

Praktik umum adalah mengonfigurasi koneksi jaringan board di boot.py sehingga selalu tersedia setelah reset untuk digunakan dengan REPL, mpremote, dll.

Peringatan

boot.py harus selalu keluar dan tidak berjalan tanpa batas.

Bergantung pada board, beberapa inisialisasi perangkat keras ditunda hingga setelah boot.py keluar. Ini termasuk inisialisasi USB pada OpenMV Cam berbasis STM32. Pada board ini, output yang dicetak dari boot.py mungkin tidak terlihat di port serial USB bawaan sampai setelah boot.py selesai berjalan.

Tujuan inisialisasi yang terlambat ini adalah agar dimungkinkan untuk mengonfigurasi perangkat keras tertentu sebelumnya di boot.py, dan kemudian memulainya dengan konfigurasi yang benar.

Catatan

Terkadang lebih sederhana untuk tidak memiliki file boot.py dan menempatkan kode inisialisasi apa pun di bagian atas main.py.

main.py

Mirip dengan boot.py, file bernama main.py dapat disalin ke sistem file internal board. Jika ditemukan maka ia akan dieksekusi berikutnya dalam proses startup.

main.py adalah untuk kode Python apa pun yang ingin Anda jalankan setiap kali perangkat Anda mulai.

Beberapa tips untuk penggunaan main.py:

  • main.py tidak harus keluar, jangan ragu untuk menempatkan loop while True yang tak terbatas di sana.

  • Untuk aplikasi Python yang kompleks, Anda tidak perlu meletakkan semua kode di main.py. main.py bisa menjadi titik masuk sederhana yang mengimpor aplikasi Anda dan memulai eksekusi:

    import my_app
    my_app.main()
    

    Ini dapat membantu menjaga struktur aplikasi Anda tetap jelas. Ini juga memudahkan untuk menginstal beberapa aplikasi di board dan beralih di antara mereka.

  • Praktik yang baik saat menulis aplikasi yang tangguh adalah membungkus kode di main.py dengan penanganan eksepsi untuk mengambil tindakan yang tepat jika kode mengalami crash. Misalnya:

    import machine, sys
    import my_app
    try:
        my_app.main()
    except Exception as e:
        print("Fatal error in main:")
        sys.print_exception(e)
    
    # Following a normal Exception or main() exiting, reset the board.
    # Following a non-Exception error such as KeyboardInterrupt (Ctrl-C),
    # this code will drop to a REPL. Place machine.reset() in a finally
    # block to always reset, instead.
    machine.reset()
    

    Jika tidak, MicroPython akan turun ke REPL setelah crash apa pun atau jika main keluar (lihat di bawah).

  • Setiap variabel global yang ditetapkan di boot.py masih akan ditetapkan dalam konteks global main.py.

  • Untuk sepenuhnya mengoptimalkan penggunaan flash dan konsumsi memori, Anda dapat menyalin file pra-kompilasi main.mpy dan/atau boot.mpy ke sistem file, atau bahkan membekukan mereka ke dalam build firmware.

  • Eksekusi main.py dilewati ketika soft reset dimulai dari mode raw REPL (misalnya, ketika mpremote atau program lain berinteraksi langsung dengan MicroPython).

Interpreter Interaktif (REPL)

Jika main.py tidak ditemukan, atau jika main.py keluar, maka Mode Interpreter Interaktif MicroPython (alias REPL) akan segera dimulai.

Catatan

Bahkan jika main.py berisi loop tak terbatas, mengetik Ctrl-C pada port serial REPL akan menyuntikkan KeyboardInterrupt. Jika tidak ada penanganan eksepsi yang menangkapnya maka main.py akan keluar dan REPL akan dimulai.

Setiap variabel global yang ditetapkan di boot.py dan main.py masih akan ditetapkan dalam konteks global REPL.

REPL terus mengeksekusi hingga kode Python memicu hard reset atau soft reset.

Soft Bricking (gagal boot)

Jarang terjadi tetapi mungkin bagi MicroPython untuk menjadi tidak responsif selama startup, suatu kondisi yang terkadang disebut "soft bricked". Misalnya:

  • Jika eksekusi boot.py tersangkut dan port serial USB native tidak pernah diinisialisasi.

  • Jika kode Python mengonfigurasi ulang antarmuka REPL, membuatnya tidak dapat diakses.

Jangan khawatir, pemulihan masih memungkinkan!

Jika Anda menggunakan OpenMV IDE, hanya dengan menghubungkan biasanya sudah cukup — IDE menghentikan main.py yang sedang berjalan dan mengambil alih. Jika kamera tidak dapat terhubung sama sekali, gunakan Factory Reset di bawah ini. Metode Ctrl-C yang dijelaskan berikutnya adalah untuk sesi terminal serial langsung — ini bergantung pada REPL yang ada di perangkat, yang tidak digunakan oleh OpenMV IDE.

KeyboardInterrupt

Dalam banyak kasus, membuka port serial REPL dan mengetik Ctrl-C akan menyuntikkan KeyboardInterrupt dan dapat menyebabkan skrip yang berjalan keluar dan REPL dimulai. Dari REPL, Anda dapat menggunakan os.remove() untuk menghapus file Python yang bermasalah:

import os
os.remove('main.py')

Untuk mengonfirmasi file mana yang masih ada di sistem file internal:

import os
os.listdir()

Factory Reset

Jika Anda tidak dapat mencapai REPL menggunakan metode di atas, opsi yang tersisa adalah factory reset: menghapus seluruh isi sistem file flash internal. Ini juga merupakan solusi jika sistem file internal telah rusak.

OpenMV IDE memiliki beberapa cara bawaan untuk melakukan ini. Pertama masukkan kamera ke dalam mode pemulihan/bootloader-nya — metode ini berbeda per board, jadi lihat bagian Recovery and debug pins pada referensi cepat board Anda untuk cara memasukinya. Kemudian klik tombol connect di OpenMV IDE dan ikuti petunjuk untuk menghapus sistem file dan me-reflash firmware.

Peringatan

Me-reflash firmware tanpa menghapus sistem file biasanya tidak dapat memulihkan dari soft bricking, karena pembaruan firmware normal mempertahankan isi sistem file. Pastikan untuk memilih opsi hapus ketika OpenMV IDE meminta.

Jika Anda mengalami masalah, tanyakan di forum OpenMV.