micropython — גישה ושליטה ברכיבים הפנימיים של MicroPython¶
פונקציות¶
- micropython.const(expr: int) int¶
משמש כדי להצהיר שהביטוי הוא קבוע כך שהמהדר יכול לבצע לו אופטימיזציה. השימוש בפונקציה זו צריך להיות כדלקמן:
from micropython import const CONST_X = const(123) CONST_Y = const(2 * CONST_X + 1)
קבועים שמוצהרים בדרך זו עדיין נגישים כמשתנים גלובליים מחוץ למודול שבו הם מוצהרים. מצד שני, אם קבוע מתחיל בקו תחתון אז הוא מוסתר, הוא אינו זמין כמשתנה גלובלי, ואינו תופס זיכרון כלשהו במהלך הביצוע.
פונקציית
constזו מזוהה ישירות על ידי המנתח של MicroPython ומסופקת כחלק מהמודולmicropythonבעיקר כדי שניתן יהיה לכתוב סקריפטים שרצים גם תחת CPython וגם תחת MicroPython, על ידי מעקב אחר התבנית שלעיל.
- micropython.opt_level(level: int | None = None) int | None¶
אם level ניתן אז פונקציה זו מגדירה את רמת האופטימיזציה להידור עתידי של סקריפטים, ומחזירה
None. אחרת היא מחזירה את רמת האופטימיזציה הנוכחית.רמת האופטימיזציה שולטת על תכונות ההידור הבאות:
טענות (Assertions): ברמה 0 משפטי טענה מאופשרים ומהודרים אל הbytecode; ברמות 1 ומעלה טענות אינן מהודרות.
המשתנה המובנה
__debug__: ברמה 0 משתנה זה מתרחב ל-True; ברמות 1 ומעלה הוא מתרחב ל-False.מספרי שורות בקוד המקור: ברמות 0, 1 ו-2 מספרי שורות הקוד נשמרים יחד עם הbytecode כך שחריגות יכולות לדווח על מספר השורה שבה הן התרחשו; ברמות 3 ומעלה מספרי שורות אינם נשמרים.
רמת האופטימיזציה המוגדרת כברירת מחדל היא בדרך כלל רמה 0.
- micropython.alloc_emergency_exception_buf(size: int) None¶
הקצו size בתים של RAM עבור חוצץ חריגות החירום (גודל טוב הוא בסביבות 100 בתים). החוצץ משמש ליצירת חריגות במקרים שבהם הקצאת RAM רגילה הייתה נכשלת (למשל בתוך מטפל פסיקה) ובכך לספק מידע traceback שימושי במצבים אלה.
דרך טובה להשתמש בפונקציה זו היא למקם אותה בתחילת הסקריפט הראשי שלכם (למשל
boot.pyאוmain.py) ואז חוצץ חריגות החירום יהיה פעיל עבור כל הקוד שאחריו.
- micropython.mem_info(verbose: Any | None = None) None¶
הדפיסו מידע על הזיכרון שבשימוש כעת. אם הארגומנט verbose ניתן אז מידע נוסף מודפס.
המידע שמודפס תלוי במימוש, אך כעת כולל את כמות המחסנית (stack) והערמה (heap) שבשימוש. במצב verbose הוא מדפיס את כל הערמה תוך ציון אילו בלוקים בשימוש ואילו פנויים.
- micropython.qstr_info(verbose: Any | None = None) None¶
הדפיסו מידע על מחרוזות מועצמות (interned) שבשימוש כעת. אם הארגומנט verbose ניתן אז מידע נוסף מודפס.
המידע שמודפס תלוי במימוש, אך כעת כולל את מספר המחרוזות המועצמות וכמות ה-RAM שהן משתמשות בה. במצב verbose הוא מדפיס את שמות כל המחרוזות המועצמות ב-RAM.
- micropython.stack_use() int¶
החזירו מספר שלם המייצג את כמות המחסנית (stack) שבשימוש כעת. הערך המוחלט של זה אינו שימושי במיוחד, אלא יש להשתמש בו לחישוב הפרשים בשימוש המחסנית בנקודות שונות.
- micropython.heap_lock() None¶
נעלו את הערמה (heap). בעוד שהיא נעולה, לא יכולה להתרחש הקצאת זיכרון ו-
MemoryErrorיועלה אם יבוצע ניסיון להקצאת ערמה כלשהי.נעילות מקוננות: קריאה ל-
heap_lock()מספר פעמים מגדילה את עומק הנעילה. הערמה נשארת נעולה עד ש-heap_unlock()נקראה אותו מספר פעמים.אם ה-REPL הופך לפעיל בעוד שהערמה נעולה אז היא תיפתח בכוח.
- micropython.heap_unlock() int¶
הפחיתו את עומק נעילת הערמה באחד והחזירו את העומק החדש כמספר שלם אי-שלילי. ערך החזרה של
0משמעו שהערמה אינה נעולה עוד והקצאות מותרות שוב.
- micropython.heap_locked() int¶
החזירו את עומק נעילת הערמה הנוכחי כמספר שלם אי-שלילי;
0משמעו שהערמה אינה נעולה.הערה: פונקציה זו אינה זמינה ב-OpenMV Cam.
- micropython.kbd_intr(chr: int) None¶
הגדירו את התו שיעלה חריגת
KeyboardInterrupt. כברירת מחדל זה מוגדר ל-3 במהלך ביצוע הסקריפט, התואם ל-Ctrl-C. העברת -1 לפונקציה זו תשבית את לכידת Ctrl-C, והעברת 3 תשחזר אותה.פונקציה זו יכולה לשמש למניעת לכידת Ctrl-C על הזרם הנכנס של תווים שמשמש בדרך כלל עבור ה-REPL, במקרה שהזרם הזה משמש למטרות אחרות.
- micropython.schedule(func: Callable[[Any], Any], arg: Any) None¶
תזמנו את הפונקציה func להתבצע ”בקרוב מאוד“. לפונקציה מועבר הערך arg כארגומנט היחיד שלה. ”בקרוב מאוד“ משמעו ש-MicroPython runtime יעשה כמיטב יכולתו לבצע את הפונקציה בזמן המוקדם ביותר האפשרי, בהינתן שהוא גם מנסה להיות יעיל, ושהתנאים הבאים מתקיימים:
פונקציה מתוזמנת לעולם לא תקדים (preempt) פונקציה מתוזמנת אחרת.
פונקציות מתוזמנות מתבצעות תמיד ”בין opcodes“ מה שאומר שכל פעולות Python הבסיסיות (כגון הוספה לרשימה) מובטחות להיות אטומיות.
port נתון עשוי להגדיר ”אזורים קריטיים“ שבתוכם פונקציות מתוזמנות לעולם לא יתבצעו. ניתן לתזמן פונקציות בתוך אזור קריטי אך הן לא יתבצעו עד שיוצאים מאזור זה. דוגמה לאזור קריטי היא מטפל פסיקה מקדים (IRQ).
בתוך פונקציות קוד מקורי (native), פונקציות מתוזמנות אינן נקראות אלא אם הקוד המקורי קורא לפונקציה שעושה זאת באופן ספציפי.
פונקציות מסוימות כולל
poll.poll,poll.ipoll,time.sleepו-time.sleep_ms(כולל שינה באורך אפס) יקראו לפונקציות מתוזמנות.
שימוש לפונקציה זו הוא לתזמן פונקציית callback מ-IRQ מקדים. IRQ כזה מטיל מגבלות על הקוד שרץ ב-IRQ (למשל הערמה עשויה להיות נעולה) ותזמון פונקציה לקרוא מאוחר יותר יסיר את המגבלות הללו.
ב-ports מרובי-תהליכונים, התנהגות הפונקציה המתוזמנת תלויה בשאלה האם ה-Global Interpreter Lock (GIL) מאופשר עבור ה-port הספציפי:
אם GIL מאופשר, הפונקציה יכולה להקדים כל תהליכון ולרוץ בהקשר שלו.
אם GIL מושבת, הפונקציה תקדים רק את התהליכון הראשי ותרוץ בהקשר שלו.
הערה: אם
schedule()נקראת מ-IRQ מקדים, כאשר הקצאת זיכרון אינה מותרת וה-callback שיועבר ל-schedule()הוא מתודה כבולה (bound method), העברתו ישירות תיכשל. הסיבה לכך היא שיצירת הפניה למתודה כבולה גורמת להקצאת זיכרון. פתרון הוא ליצור הפניה למתודה בבנאי המחלקה ולהעביר את ההפניה הזו ל-schedule(). הדבר נדון בפירוט כאן reference documentation תחת ”Creation of Python objects“.קיימת תור סופי להחזקת הפונקציות המתוזמנות ו-
schedule()תעלהRuntimeErrorאם התור מלא.
מחלקות¶
- class micropython.RingIO(size: int)¶
- class micropython.RingIO(buffer: bytes | bytearray | memoryview)
מספק ringbuffer בגודל קבוע עבור בתים עם ממשק זרם (stream). ניתן להתייחס אליו כווריאנט תור-FIFO של
io.BytesIO. שתי צורות הבנאי נבדלות רק באופן שבו החוצץ המגבה מסופק:RingIO(size)מקצה את החוצץ המגבה באופן פנימי. אלגוריתם ה-ringbuffer הקלאסי שומר בית אחד למעקב, כך שהחוצץ המוקצה גדול בבית אחד מ-sizeוהמופע יכול להחזיק את מלואsizeהבתים של נתונים. לדוגמה,RingIO(16)מקצה חוצץ בגודל 17 בתים ומחזיק 16 בתים של נתונים.RingIO(buffer)משתמש ב-bufferשסופק במקומו במקום להקצות אחד. מכיוון שבית אחד שמור למעקב, המופע יכול להחזיקlen(buffer) - 1בתים של נתונים. לדוגמה,RingIO(bytearray(16))מחזיק 15 בתים של נתונים.
מופע RingIO הוא בטוח לשימוש מ-IRQ/תהליכונים כאשר משמש להעברת נתונים בכיוון יחיד (למשל נכתב אליו מ-IRQ ונקרא מפונקציה שאינה IRQ, או להפך). זה אינו תקף אם מופע יחיד נכתב אליו הן מהקשרי IRQ והן מהקשרים שאינם IRQ, מה שלעתים קרובות יגרום לשחיתות נתונים.
- read(nbytes: int | None = None) bytes¶
קראו את התווים הזמינים. זו פונקציה לא-חוסמת. אם
nbytesמצוין אז קראו לכל היותר מספר זה של בתים, אחרת קראו כמה שיותר נתונים.ערך החזרה: אובייקט bytes המכיל את הבתים שנקראו. יהיה אובייקט bytes באורך אפס אם אין נתונים זמינים.
- readline(nbytes: int | None = None) bytes¶
קראו שורה, המסתיימת בתו שורה חדשה או return אם קיים כזה בחוצץ, אחרת החזירו את הבתים הזמינים בחוצץ. אם
nbytesמצוין אז קראו לכל היותר מספר זה של בתים.ערך החזרה: אובייקט bytes המכיל את השורה שנקראה.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
קראו את הבתים הזמינים אל ה-
bufשסופק. אםnbytesמצוין אז קראו לכל היותר מספר זה של בתים. אחרת, קראו לכל היותרlen(buf)בתים.ערך החזרה: ספירת מספר שלם של מספר הבתים שנקראו אל
buf.
- write(buf: bytes | bytearray | memoryview) int¶
כתיבה לא-חוסמת של בתים מ-
bufאל ה-ringbuffer, מוגבלת על ידי המקום הזמין ב-ringbuffer.ערך החזרה: ספירת מספר שלם של בתים שנכתבו.