רצף איפוס ואתחול¶
התקן שמריץ MicroPython עוקב אחר רצף אתחול מסוים כדי לעלות ולאתחל את עצמו לאחר איפוס.
הערה
הרצף _boot.py ← boot.py ← main.py ← REPL המתואר להלן הוא מה שהקושחה מריצה בכל איפוס, ללא קשר לאופן שבו אתם מתחברים — ולכן הוא תמיד חל. כאשר אתם מריצים סקריפט מתוך OpenMV IDE, ה-IDE מפסיק את ה-main.py הרץ כעת ומריץ במקומו את הסקריפט הפתוח בעורך, באמצעות פרוטוקול הניפוי שלו. הוא אינו משתמש ב-REPL שעל ההתקן, ולכן ההפניות הייחודיות-ל-REPL בעמוד זה (השורה האינטראקטיבית, Ctrl-D / Ctrl-C במסוף טורי וכו«) חלות על פעולה עצמאית ועל הפעלות מסוף טורי ישירות — אך רצף האתחול עצמו חל בכל המקרים.
איפוס קשיח¶
אתחול מאיפוס קשיח הוא מה שקורה כאשר לוח מופעל לראשונה, אתחול קר. זהו איפוס מלא של חומרת ה-MCU.
קוד הפורט של MicroPython מאתחל את כל החומרה החיונית (כולל שעונים מובנים ומווסתי מתח, UART טורי פנימי וכו«), ולאחר מכן מפעיל את סביבת MicroPython. תצורת RTC קיימת עשויה להישמר לאחר איפוס קשיח, אך כל שאר מצב החומרה מנוקה.
אותו רצף אתחול של איפוס קשיח יכול להיות מופעל על ידי מספר אירועים כגון:
קוד Python המבצע
machine.reset().המשתמש לוחץ על לחצן איפוס פיזי בלוח (היכן שרלוונטי).
התעוררות משינה עמוקה (ברוב הפורטים).
איפוס של שעון השמירה (watchdog) של חומרת ה-MCU.
גלאי נפילת מתח (brown out) של חומרת ה-MCU.
הפרטים של גורמי איפוס ספציפיים לחומרה תלויים בפורט ובחומרה המשויכת. ניתן להשתמש בפונקציה machine.reset_cause() כדי לקבוע ביתר דיוק את הגורם לאיפוס.
איפוס רך¶
כאשר MicroPython כבר רץ, ניתן להפעיל איפוס רך על ידי הקלדת Ctrl-D ב-REPL או ביצוע machine.soft_reset().
איפוס רך מנקה את מפרש Python, משחרר את כל זיכרון Python, ומפעיל מחדש את סביבת MicroPython.
מצב שמנוקה על ידי איפוס רך כולל:
כל משתני Python, האובייקטים, המודולים המיובאים וכו«.
רוב ההתקנים ההיקפיים שהוגדרו באמצעות מודול machine. ישנם חריגים מעטים מאוד, לדוגמה מצבי machine.Pin (כלומר אם פין הוא קלט או פלט, גבוה או נמוך) אינם מאופסים ברוב הפורטים. תצורה מתקדמת יותר כגון
Pin.irq()תמיד מאופסת.Bluetooth.
שקעי רשת. שקעי TCP פתוחים נסגרים בצורה מסודרת ביחס לצד השני.
קבצים פתוחים. מערכת הקבצים נותרת במצב תקין.
חלק ממצב המערכת נשאר זהה לאחר איפוס רך, כולל:
כל חיבורי הרשת הקיימים (Ethernet, Wi-Fi וכו«) נשארים פעילים בשכבת רשת ה-IP. תשאול ממשק הרשת מתוך קוד עשוי להצביע על כך שממשק הרשת עדיין פעיל עם כתובת IP מוגדרת וכו«.
REPL פעיל נראה רציף לפני ואחרי איפוס רך, למעט במקרים יוצאי דופן מסוימים:
REPL טורי על UART ישחזר את תצורת החומרה המוגדרת כברירת מחדל (קצב בָּאוּד וכו«).
מהירות שעון ה-CPU בדרך כלל אינה משתנה על ידי איפוס רך.
תצורת RTC (כלומר הגדרת הזמן הנוכחי) אינה משתנה על ידי איפוס רך.
רצף אתחול¶
כאשר MicroPython עולה בעקבות איפוס קשיח או רך, הוא עוקב אחר רצף האתחול הזה לפי הסדר:
_boot.py¶
זהו סקריפט פנימי מוקפא לתוך קושחת MicroPython. הוא מסופק על ידי MicroPython בפורטים רבים כדי לבצע אתחול חיוני.
לדוגמה, ברוב הפורטים _boot.py יזהה את האתחול הראשון של התקן חדש ויפרמט את מערכת הקבצים בזיכרון הפלאש הפנימי כך שתהיה מוכנה לשימוש.
אלא אם אתם יוצרים גרסת בנייה מותאמת של MicroPython או מוסיפים פורט חדש, כנראה שאינכם צריכים לדאוג לגבי _boot.py. עדיף לא לשנות את התוכן אלא אם אתם באמת יודעים מה אתם עושים.
boot.py¶
ניתן להעתיק קובץ בשם boot.py אל מערכת הקבצים הפנימית של הלוח באמצעות mpremote.
אם boot.py נמצא, הוא מורץ. ניתן להוסיף קוד ב-boot.py כדי לבצע אתחול חד-פעמי מותאם (לדוגמה, להגדיר את חומרת הלוח).
נוהג נפוץ הוא להגדיר את חיבור הרשת של הלוח ב-boot.py כך שיהיה זמין תמיד לאחר איפוס לשימוש עם REPL, mpremote וכו«.
אזהרה
boot.py צריך תמיד לצאת ולא לרוץ ללא הגבלת זמן.
בהתאם ללוח, חלק מאתחול החומרה נדחה עד לאחר ש-boot.py יוצא. זה כולל אתחול של USB ב-OpenMV Cams המבוססים על STM32. בלוחות אלה, פלט שהודפס מ-boot.py עשוי שלא להיות גלוי ביציאת ה-USB הטורית המובנית עד לאחר ש-boot.py מסיים לרוץ.
מטרת האתחול המאוחר הזה היא לאפשר להגדיר מראש חומרה מסוימת ב-boot.py, ולאחר מכן לאתחל אותה עם התצורה הנכונה.
הערה
לעיתים פשוט יותר לא להחזיק קובץ boot.py ולמקם כל קוד אתחול בראש main.py במקום זאת.
main.py¶
בדומה ל-boot.py, ניתן להעתיק קובץ בשם main.py אל מערכת הקבצים הפנימית של הלוח. אם הוא נמצא, הוא מורץ בשלב הבא בתהליך ההפעלה.
main.py מיועד לכל קוד Python שאתם רוצים להריץ בכל פעם שההתקן שלכם מתחיל לפעול.
כמה טיפים לשימוש ב-main.py:
main.pyאינו חייב לצאת, אתם מוזמנים לשים בו לולאה אינסופיתwhile True.עבור יישומי Python מורכבים אינכם צריכים לשים את כל הקוד שלכם ב-
main.py.main.pyיכול להיות נקודת כניסה פשוטה שמייבאת את היישום שלכם ומתחילה את הריצה:import my_app my_app.main()
זה יכול לעזור לשמור על מבנה ברור של היישום שלכם. זה גם מקל על התקנת מספר יישומים בלוח ומעבר ביניהם.
זהו נוהג טוב בעת כתיבת יישומים יציבים לעטוף את הקוד ב-
main.pyבמטפל חריגות כדי לנקוט בפעולה מתאימה אם הקוד קורס. לדוגמה: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()
אחרת MicroPython יעבור ל-REPL בעקבות כל קריסה או אם main יוצא (ראו להלן).
כל המשתנים הגלובליים שהוגדרו ב-
boot.pyעדיין יהיו מוגדרים בהקשר הגלובלי שלmain.py.כדי לייעל באופן מלא את השימוש בזיכרון הפלאש ואת צריכת הזיכרון, ניתן להעתיק קבצי
main.mpyו/אוboot.mpyמהודרים מראש אל מערכת הקבצים, או אפילו להקפיא אותם לתוך גרסת הבנייה של הקושחה.ריצת
main.pyמדולגת כאשר איפוס רך מופעל ממצב raw REPL (לדוגמה, כאשר mpremote או תוכנית אחרת מתקשרת ישירות עם MicroPython).
מפרש אינטראקטיבי (REPL)¶
אם main.py אינו נמצא, או אם main.py יוצא, אז מצב המפרש האינטראקטיבי של MicroPython (המכונה גם REPL) יתחיל מיד.
הערה
גם אם main.py מכיל לולאה אינסופית, הקלדת Ctrl-C ביציאה הטורית של ה-REPL תזריק KeyboardInterrupt. אם אף מטפל חריגות לא תופס אותה, אז main.py ייצא וה-REPL יתחיל.
כל המשתנים הגלובליים שהוגדרו ב-boot.py וב-main.py עדיין יהיו מוגדרים בהקשר הגלובלי של ה-REPL.
ה-REPL ממשיך לרוץ עד שקוד Python מפעיל איפוס קשיח או רך.
הלבנה רכה (כשל באתחול)¶
זה נדיר אך אפשרי ש-MicroPython יהפוך ללא מגיב במהלך ההפעלה, מצב שנקרא לעיתים ”הלבנה רכה“ (soft bricked). לדוגמה:
אם ריצת
boot.pyנתקעת ויציאת ה-USB הטורית המקורית אף פעם לא מאותחלת.אם קוד Python מגדיר מחדש את ממשק ה-REPL, והופך אותו לבלתי נגיש.
אל דאגה, שחזור אפשרי!
אם אתם משתמשים ב-OpenMV IDE, פעמים רבות עצם ההתחברות מספיקה — ה-IDE עוצר את ה-main.py הרץ ומשתלט. אם המצלמה לא מתחברת כלל, השתמשו באיפוס למצב יצרן שלהלן. שיטת ה-Ctrl-C המתוארת בהמשך מיועדת להפעלות מסוף טורי ישירות — היא מסתמכת על ה-REPL שעל ההתקן, שבו OpenMV IDE אינו משתמש.
KeyboardInterrupt¶
במקרים רבים, פתיחת היציאה הטורית של ה-REPL והקלדת Ctrl-C תזריק KeyboardInterrupt ועשויה לגרום לסקריפט הרץ לצאת ול-REPL להתחיל. מתוך ה-REPL, ניתן להשתמש ב-os.remove() כדי להסיר את קובץ Python הבעייתי:
import os
os.remove('main.py')
כדי לוודא אילו קבצים עדיין נמצאים במערכת הקבצים הפנימית:
import os
os.listdir()
איפוס למצב יצרן¶
אם אינכם מצליחים להגיע ל-REPL בשיטה שלעיל, האפשרות הנותרת היא איפוס למצב יצרן: מחיקת כל התוכן של מערכת הקבצים בזיכרון הפלאש הפנימי. זהו גם הפתרון אם מערכת הקבצים הפנימית נפגמה.
ל-OpenMV IDE יש מספר דרכים מובנות לעשות זאת. ראשית הכניסו את המצלמה למצב השחזור/מאתחל (bootloader) שלה — השיטה שונה מלוח ללוח, אז עיינו בסעיף Recovery and debug pins של עיון מהיר של הלוח שלכם כדי לדעת כיצד להיכנס אליו. לאחר מכן לחצו על לחצן ההתחברות ב-OpenMV IDE ועקבו אחר ההנחיות כדי למחוק את מערכת הקבצים ולצרוב מחדש את הקושחה.
אזהרה
צריבה מחדש של הקושחה ללא מחיקת מערכת הקבצים בדרך כלל לא תשחזר מהלבנה רכה, מכיוון שעדכון קושחה רגיל משמר את התוכן של מערכת הקבצים. הקפידו לבחור באפשרות המחיקה כאשר OpenMV IDE מנחה לכך.
אם נתקעתם, שאלו בפורומים של OpenMV.