Secvența de resetare și pornire

Un dispozitiv care rulează MicroPython urmează o anumită secvență de pornire pentru a porni și a se inițializa după o resetare.

Notă

Secvența _boot.pyboot.pymain.py → REPL descrisă mai jos este ceea ce execută firmware-ul la fiecare resetare, indiferent de modul în care vă conectați — deci se aplică întotdeauna. Când rulați un script din OpenMV IDE, IDE-ul întrerupe main.py care rulează în acel moment și execută în locul lui scriptul deschis în editor, prin propriul protocol de depanare. Acesta nu folosește REPL de pe dispozitiv, așa că referințele specifice REPL de pe această pagină (promptul interactiv, Ctrl-D / Ctrl-C la un terminal serial etc.) se aplică funcționării autonome și sesiunilor directe de terminal serial — însă secvența de pornire în sine se aplică în toate cazurile.

Resetare hardware

Pornirea de la o resetare hardware este ceea ce se întâmplă când o placă este alimentată pentru prima dată, o pornire la rece. Aceasta este o resetare completă a hardware-ului MCU.

Codul de port MicroPython inițializează tot hardware-ul esențial (inclusiv ceasurile încorporate și regulatoarele de tensiune, UART-ul serial intern etc.), iar apoi pornește mediul MicroPython. Configurația RTC existentă poate fi păstrată după o resetare hardware, dar toate celelalte stări hardware sunt șterse.

Aceeași secvență de pornire prin resetare hardware poate fi declanșată de o serie de evenimente, precum:

  • Cod Python care execută machine.reset().

  • Utilizatorul apasă un buton fizic de Reset de pe placă (acolo unde este disponibil).

  • Trezirea din somn profund (pe majoritatea porturilor).

  • Resetare prin watchdog-ul hardware al MCU.

  • Detectorul hardware de cădere de tensiune (brown out) al MCU.

Detaliile declanșatoarelor de resetare specifice hardware-ului depind de port și de hardware-ul asociat. Funcția machine.reset_cause() poate fi folosită pentru a determina mai exact cauza unei resetări.

Resetare software

Când MicroPython rulează deja, este posibil să declanșați o resetare software prin tastarea Ctrl-D în REPL sau prin executarea machine.soft_reset().

O resetare software curăță interpretorul Python, eliberează toată memoria Python și pornește din nou mediul MicroPython.

Starea care este ștearsă de o resetare software include:

  • Toate variabilele, obiectele, modulele importate Python etc.

  • Majoritatea perifericelor configurate folosind modulul machine. Există excepții foarte limitate; de exemplu, modurile machine.Pin (adică dacă un pin este intrare sau ieșire, high sau low) nu sunt resetate pe majoritatea porturilor. Configurațiile mai avansate, precum Pin.irq(), sunt întotdeauna resetate.

  • Bluetooth.

  • Socket-uri de rețea. Socket-urile TCP deschise sunt închise curat în raport cu cealaltă parte.

  • Fișiere deschise. Sistemul de fișiere este lăsat într-o stare validă.

O parte din starea sistemului rămâne aceeași după o resetare software, inclusiv:

  • Orice conexiuni de rețea existente (Ethernet, Wi-Fi etc.) rămân active la nivelul de rețea IP. Interogarea interfeței de rețea din cod poate indica faptul că interfața de rețea este încă activă, cu o adresă IP configurată etc.

  • Un REPL activ pare continuu înainte și după resetarea software, cu excepția unor cazuri neobișnuite:

    • Un REPL pe UART serial își va restaura configurația hardware implicită (rată baud etc.).

  • Viteza de ceas a CPU de obicei nu este modificată de o resetare software.

  • Configurația RTC (adică setarea orei curente) nu este modificată de resetarea software.

Secvența de pornire

Când MicroPython pornește în urma unei resetări hardware sau software, urmează această secvență de pornire în ordine:

_boot.py

Acesta este un script intern înghețat în firmware-ul MicroPython. Este furnizat de MicroPython pe multe porturi pentru a efectua inițializarea esențială.

De exemplu, pe majoritatea porturilor _boot.py va detecta prima pornire a unui dispozitiv nou și va formata sistemul de fișiere din memoria flash internă, pregătindu-l pentru utilizare.

Cu excepția cazului în care creați o versiune MicroPython personalizată sau adăugați un port nou, probabil nu trebuie să vă preocupe _boot.py. Cel mai bine este să nu îi modificați conținutul decât dacă știți cu adevărat ce faceți.

boot.py

Un fișier numit boot.py poate fi copiat în sistemul de fișiere intern al plăcii folosind mpremote.

Dacă boot.py este găsit, atunci este executat. Puteți adăuga cod în boot.py pentru a efectua o inițializare unică personalizată (de exemplu, pentru a configura hardware-ul plăcii).

O practică obișnuită este configurarea conexiunii de rețea a unei plăci în boot.py, astfel încât aceasta să fie întotdeauna disponibilă după resetare pentru utilizare cu REPL, mpremote etc.

Atenționare

boot.py ar trebui să se încheie întotdeauna și să nu ruleze la nesfârșit.

În funcție de placă, o parte din inițializarea hardware este amânată până după încheierea boot.py. Aceasta include inițializarea USB pe camerele OpenMV Cam bazate pe STM32. Pe aceste plăci, mesajele afișate din boot.py pot să nu fie vizibile pe portul serial USB încorporat până după ce boot.py termină de rulat.

Scopul acestei inițializări întârziate este de a face posibilă preconfigurarea unui anumit hardware în boot.py, astfel încât acesta să pornească apoi cu configurația corectă.

Notă

Uneori este mai simplu să nu aveți un fișier boot.py și să plasați orice cod de inițializare la începutul main.py.

main.py

Similar cu boot.py, un fișier numit main.py poate fi copiat în sistemul de fișiere intern al plăcii. Dacă este găsit, atunci este executat în continuare în procesul de pornire.

main.py este pentru orice cod Python pe care doriți să îl rulați de fiecare dată când dispozitivul pornește.

Câteva sfaturi pentru utilizarea main.py:

  • main.py nu trebuie neapărat să se încheie; puteți pune fără probleme o buclă infinită while True în el.

  • Pentru aplicații Python complexe nu trebuie să puneți tot codul în main.py. main.py poate fi un simplu punct de intrare care importă aplicația dvs. și pornește execuția:

    import my_app
    my_app.main()
    

    Acest lucru poate ajuta la menținerea clară a structurii aplicației dvs. De asemenea, facilitează instalarea mai multor aplicații pe o placă și comutarea între ele.

  • Este o practică bună, atunci când scrieți aplicații robuste, să încadrați codul din main.py cu un gestionar de excepții pentru a lua măsuri adecvate în cazul în care codul se blochează. De exemplu:

    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()
    

    În caz contrar, MicroPython va trece la REPL după orice blocaj sau dacă main se încheie (vezi mai jos).

  • Orice variabile globale care au fost setate în boot.py vor fi în continuare setate în contextul global al main.py.

  • Pentru a optimiza pe deplin utilizarea memoriei flash și consumul de memorie, puteți copia în sistemul de fișiere fișierele precompilate main.mpy și/sau boot.mpy, sau le puteți chiar îngheța în versiunea de firmware.

  • Execuția main.py este omisă atunci când o resetare software este inițiată din modul raw REPL (de exemplu, când mpremote sau un alt program interacționează direct cu MicroPython).

Interpretor interactiv (REPL)

Dacă main.py nu este găsit, sau dacă main.py se încheie, atunci Modul interpretor interactiv MicroPython (cunoscut și ca REPL) va porni imediat.

Notă

Chiar dacă main.py conține o buclă infinită, tastarea Ctrl-C pe portul serial REPL va injecta un KeyboardInterrupt. Dacă niciun gestionar de excepții nu îl prinde, atunci main.py se va încheia și REPL-ul va porni.

Orice variabile globale care au fost setate în boot.py și main.py vor fi în continuare setate în contextul global al REPL.

REPL-ul continuă să execute până când codul Python declanșează o resetare hardware sau software.

Blocare software (eșec la pornire)

Este rar, dar posibil, ca MicroPython să devină nereceptiv în timpul pornirii, o stare numită uneori „soft bricked” (blocat software). De exemplu:

  • Dacă execuția boot.py se blochează și portul serial USB nativ nu se inițializează niciodată.

  • Dacă codul Python reconfigurează interfața REPL, făcând-o inaccesibilă.

Fiți liniștit, recuperarea este posibilă!

Dacă folosiți OpenMV IDE, simpla conectare este adesea suficientă — IDE-ul oprește main.py care rulează și preia controlul. Dacă camera nu se conectează deloc, folosiți Factory Reset de mai jos. Metoda Ctrl-C descrisă în continuare este pentru sesiuni directe de terminal serial — se bazează pe REPL-ul de pe dispozitiv, pe care OpenMV IDE nu îl folosește.

KeyboardInterrupt

În multe cazuri, deschiderea portului serial REPL și tastarea Ctrl-C va injecta KeyboardInterrupt și poate face ca scriptul care rulează să se încheie și un REPL să pornească. Din REPL, puteți folosi os.remove() pentru a elimina fișierul Python care se comportă necorespunzător:

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

Pentru a confirma ce fișiere sunt încă prezente în sistemul de fișiere intern:

import os
os.listdir()

Factory Reset

Dacă nu puteți ajunge la un REPL folosind metoda de mai sus, opțiunea rămasă este o resetare la valorile din fabrică: ștergerea întregului conținut al sistemului de fișiere din memoria flash internă. Aceasta este și soluția în cazul în care sistemul de fișiere intern s-a corupt.

OpenMV IDE are mai multe modalități încorporate de a face acest lucru. Mai întâi puneți camera în modul de recuperare/bootloader — metoda diferă de la o placă la alta, așa că consultați secțiunea Recovery and debug pins din referința rapidă a plăcii dvs. pentru a afla cum să intrați în el. Apoi faceți clic pe butonul de conectare din OpenMV IDE și urmați instrucțiunile pentru a șterge sistemul de fișiere și a reflasha firmware-ul.

Atenționare

Reflasharea firmware-ului fără a șterge sistemul de fișiere de obicei nu va recupera dispozitivul dintr-o blocare software, deoarece o actualizare normală de firmware păstrează conținutul sistemului de fișiere. Asigurați-vă că alegeți opțiunea de ștergere atunci când OpenMV IDE vă solicită acest lucru.

Dacă rămâneți blocat, întrebați pe forumurile OpenMV.