14.1.1.3. סימולטורים#

שני ערכי TARGET בונים את הקושחה כדי לרוץ בתוך סימולטור על המארח שלכם, ללא חומרה מחוברת. הם קיימים כדי שניתן יהיה להריץ ולבדוק את הקושחה בכל מקום.

TARGET

ליבה

NPU

סימולטור

MPS2_AN500

Cortex-M7

ללא

QEMU

MPS3_AN547

Cortex-M55

Ethos-U55 (256 MACs)

Arm FVP – Corstone SSE-300

MPS2_AN500 הוא יעד ה-Cortex-M7 הבסיסי ללא NPU. הוא רץ תחת QEMU, אשר מהיר להפעלה ומהווה את הדרך הקלה להריץ את הקוד הבלתי-תלוי-בפלטפורמה ואת ערכת הבדיקות.

MPS3_AN547 הוא Cortex-M55 עם ה-NPU מסוג Ethos-U55, הרץ על Fast Models של Arm – ה-FVP, אשר מדמה את תת-המערכת הייחוס Corstone SSE-300. זהו היעד להרצת ה-NPU ונתיב מודל ה-ML בסימולציה.

שניהם מספקים את מערכת הקבצים ROM ושפע של RAM (ואת ה-NPU על ה-M55), כך שסקריפטים של ראייה ו-ML רצים ללא שינוי.

אין חיישן אמיתי, אך מודול ה-csi עדיין עובד מול חיישן וירטואלי – csi.CSI.snapshot() מחזיר תבנית בדיקה מלאכותית ומונפשת (לוח שחמט נגלל בגווני אפור, מפל צבע ב-RGB565), לא סצנה חיה. כדי לעבד תוכן תמונה אמיתי, טענו אותו מקובץ במקום זאת: image.Image ממתקן בדיקה במערכת הקבצים ROM, או זרם image.ImageIO עבור פריימים מוקלטים.

14.1.1.3.1. בנייה והרצה#

כל סימולטור הוא כלי מארח שאתם מתקינים בעצמכם. אתם בונים יעד כמו כל יעד אחר (ראו בניית הקושחה), ואז run אותו תחת הסימולטור המתאים – run בונה את תמונת ה-ROMFS, מאתחל את הקושחה, ומשאיר אותה רצה עם חיבור טורי שאליו תוכלו להתחבר.

14.1.1.3.1.1. MPS2_AN500 (QEMU)#

QEMU מגיע ברוב מנהלי החבילות כאמולטור המערכת של Arm:

  • Linux (Debian / Ubuntu) – התקינו אותו עם apt:

    sudo apt install qemu-system-arm
    
  • macOS – התקינו אותו עם Homebrew:

    brew install qemu
    

לאחר מכן בנו והריצו את היעד:

make -j$(nproc) TARGET=MPS2_AN500
make TARGET=MPS2_AN500 run

14.1.1.3.1.2. MPS3_AN547 (Arm FVP)#

ה-FVP הוא ה-Fixed Virtual Platform של Arm עבור ה-Corstone SSE-300, המסופק כחלק מ-Arm Virtual Hardware. הוא זמין עבור Linux בלבד – ב-Mac, השתמשו ביעד QEMU שלמעלה במקום זאת.

הורידו את החבילה, חלצו אותה, והכניסו את ספריית ה-bin/ שלה ל-PATH

wget https://artifacts.tools.arm.com/avh/11.31.28/avh-linux-x86_11.31_28_Linux64.tar.gz
mkdir -p ~/fvp
tar --strip-components=1 -xzf avh-linux-x86_11.31_28_Linux64.tar.gz -C ~/fvp
export PATH="$HOME/fvp/bin:$PATH"

ה-FVP זקוק גם לספריות ה-Python של ה-SDK ב-LD_LIBRARY_PATH בעת הרצתו. ייצאו אותה פעם אחת לכל מעטפת משורש המאגר – קריאת SDK_VERSION שומרת עליה נכונה כאשר המאגר מעדכן את ה-SDK המוצמד:

export LD_LIBRARY_PATH="$HOME/openmv-sdk-$(cat SDK_VERSION)/python/lib:$LD_LIBRARY_PATH"

לאחר מכן בנו והריצו את היעד:

make -j$(nproc) TARGET=MPS3_AN547
make TARGET=MPS3_AN547 run

14.1.1.3.2. הרצת ערכת הבדיקות#

בדיקות היחידה נמצאות ב-scripts/unittest/tests/, עם תמונות המתקן והנתונים שלהן ב-scripts/unittest/data/. הן מורצות עם mpremote, אשר מעגן את scripts/unittest/ על הסימולטור הרץ ומריץ את run.py שלו.

קישור הסימולטור איטי עם mpremote רגיל, ולכן השתמשו בעותק המצורף במאגר עם תיקון הטורי המוחל (החילו אותו פעם אחת):

patch -N -p1 -d lib/micropython < tools/mpremote-qemu-serial.patch

עבור MPS2_AN500 תחת QEMU, הפעילו את היעד – הוא מדפיס את המסוף הפסאודו-טרמינל שעליו נמצא הפורט הטורי שלו (למשל /dev/pts/5):

make TARGET=MPS2_AN500 run

לאחר מכן, ממעטפת אחרת, כוונו את ה-mpremote המתוקן אל אותו התקן:

python3 lib/micropython/tools/mpremote/mpremote.py connect /dev/pts/5 \
    mount scripts/unittest/ run scripts/unittest/run.py

עבור MPS3_AN547 תחת ה-FVP, הפורט הטורי הוא שקע telnet על פורט 5555 במקום זאת:

make TARGET=MPS3_AN547 run
python3 lib/micropython/tools/mpremote/mpremote.py connect socket://localhost:5555 \
    mount scripts/unittest/ run scripts/unittest/run.py

run.py מגלה ומריץ כל בדיקה, ומדפיס שורת PASSED / FAILED לכל בדיקה עם תזמון וסיכום בסוף.

14.1.1.3.3. הוספת בדיקה#

בדיקות מתגלות אוטומטית. כדי להוסיף אחת, שימו קובץ ב-scripts/unittest/tests/ המגדיר פונקציית unittest(data_path, temp_path) המחזירה True כאשר הבדיקה עוברת ו-False כאשר היא נכשלת:

# scripts/unittest/tests/circles.py
def unittest(data_path, temp_path):
    import image

    img = image.Image(data_path + "/shapes.ppm", copy_to_fb=True)
    circles = img.find_circles(threshold=5000, x_margin=30, y_margin=30, r_margin=30)
    return len(circles) == 1 and circles[0][0:] == (118, 56, 22, 5856)

הארגומנטים data_path ו-temp_path מצביעים אל שתי מערכות הקבצים שהסימולטור רואה בזמן שערכת הבדיקות רצה:

נתיב

מגובה על ידי

/remote

ספריית ה-scripts/unittest/ של המארח, מעוגנת באופן חי על חיבור ה-mpremote. run.py וה-tests/ שהוא מגלה נמצאים כאן, כך שהוספה או עריכה של בדיקה נכנסת לתוקף בהרצה הבאה ללא בנייה מחדש. temp_path הוא /remote/temp על ההתקן, שהוא ה-scripts/unittest/temp/ של המארח שלכם – ספריית טיוטה ניתנת לכתיבה עבור בדיקות שיוצרות קבצים.

/rom

מערכת הקבצים ROM לקריאה בלבד של הלוח, הבנויה לתוך תמונת הקושחה מ-romfs_config.json: מתקני הבדיקה (מ-scripts/unittest/data/) ומודלי ה-ML המצורפים. data_path הוא /rom – הגיעו אל מתקן כ-data_path + "/<file>".

כך שבדיקה חדשה אינה זקוקה לבנייה מחדש, אך מתקן חדש כן: תמונת ה-ROM נקבעת לפי romfs_config.json ולא לפי קבצי הנתונים הבודדים, אז אלצו את הבנייה מחדש על ידי נגיעה ב-romfs_config.json של הלוח (או make TARGET=<TARGET> clean) והרצה מחדש.

ערכים צפויים נטענים ישירות (inline) בבדיקה, ולכן אין קובץ פלט-צפוי נפרד לתחזק. כדי לדלג על בדיקה בזמן ריצה – למשל כשהיא זקוקה לחומרה שהסימולטור אינו מדמה – זרקו חריגה שההודעה שלה מכילה "SKIPPED".