הקדמה
בהמשך לפוסט הקודם, אני ממשיך עם כרטיס דמוי ארדואינו משלי שאני רוצה לייצר.אעדכן אתכם על ההתקדמות שלי בניסיונות לצרוב את ה-bootloader על המיקרובקר של הכרטיס.
מה זה Bootloader?
אתם בטח רגילים לחבר את כרטיס הארדואינו שלכם ל-USB של המחשב, לבחור את הפורט שנוצר בסביבת הפיתוח ולצרוב את התוכנה החדשה שלכם על הכרטיס.כדי שתוכלו לעשות את זה, המיקרובקר צריך לעשות כמה דברים, כמו להזדהות מול המחשב כהתקן התומך תקשורת טורית, לדעת לנהל את התקשורת מול סביבת הפיתוח שמעבירה לו את התוכנית שלכם בפורמט מסויים בזמן הצריבה, לצרוב את הנתונים שהוא מקבל בזיכרון ה-FLASH של הבקר במיקום הנכון, לעשות Reset בסוף, וכו'...
כל זה מתבצע ע"י תוכנית קטנה שנקראת Bootloader שמתחילה להתבצע מיד כשמיקרובקר מתעורר לחיים אחרי שמחברים את המתח לכרטיס. זוהי התוכנית הראשונית שצרובה בזיכרון הבקר בכתובת 0. בהתחלה ה-bootloader מחכה לסימנים מסוימים שמראים על הרצון של סביבת הפיתוח לבצע צריבה של התוכנית, אם הם לא מתקיימים, אז הוא פשוט קופץ לכתובת התחלתיתי של התוכנית הרגילה שצרבתם על הכרטיס.
בכרטיסי ארדואינו עם מיקרובקר ממשפחת SAMD21 הוקצו 8KByte ההתחלתיים של ה-FLASH לטובת ה-bootloader. התוכנית הרגילה נצרבת לכתובת הבאה אחרי מיקום ה-bootloader.
במיקרובקר SAMD21 יש אפילו אפשרות לנעול את האזור הזה לכתיבה ע"י מנגנון הפיוזים (Fuses) שאפשר לשנות עם צורב יעודי. בכמה כרטיסים שבדקתי האזור הזה לא היה נעול, כנראה כדי לאפשר למשתמשים לעדכן את ה-bootloader אם יש צורך.
למה אני צריך לצרוב Bootloader?
מכיוון שאני מייצר כרטיס חדש, זיכרון המיקרובקר מגיע ריק לגמרי מהמפעל, ואין עליו את ה-bootloader כדי שאוכל לצרוב תוכניות משלי.במקרים כאלה הדרך היחידה לצורב משהו היא להשתמש בצורב יעודי. מכיוון שאני משתמש במיקרובקר ATSAMD21G18 של Microchip, אני צריך צורב ICE התומך במשפחת הבקרים הזו. הצריבה מתבצעת דרך קווי SWDIO ו-SWDCLK של הבקר, שבדרך כלל מובאים למחבר SWD עם חיבורים 2x5, יחד עם עוד כמה קווים, כמו מתח, האדמה ו-Reset.
כמו שהסברתי בפוסט הקודם על VID ו-PID (העולם האכזר של USB), אני צריך לגרום כרטיס להזדהות כמוצר משלי ולא להשתמש בשמות של יצרנים אחרים. תהליך ההזדהות מתבצע מתוך ה-bootloader, מה שאומר שאני צריך לייצר אחד משלי עם שם הכרטיס החדש ו-VID/PID שהשגתי מ-Microchip.
אגב, הבקשה שלי ל-VID/PID מ-pid.codes עדיין לא התקדמה, כך שאני ממש לא בטוח אם זו אפשרות שעדיין קיימת.
הקוד של ה-bootloader מפורסם ע"י צוות ה-Arduino במסגרת ה-OpenSource של כל הפרוייקט, אז כביכול הכל קיים ולא אמור להיות מסובך מדי לקמפל אותו לצרכים שלי, במיוחד שזה רק שינוי השם ושני מספרים.
מי שרוצה לייצר bootloader משלו עם דברים מיוחדים, כמו למשל הרעיון ל-dual boot שחקרתי קודם, או להוריד ממנו דברים שלא נחוצים לכם כדי להקטין אותו ולפנות עוד קצת זיכרון, אז גם זה אפשרי.
בתור התחלה החלטתי לקחת bootloader של SparkFun לכרטיס פיתוח SAMD21 שלהם. כרטיס שלי דומה מאוד לכרטיס זה באזור המיקרובקר, כך שתיאורטית הכל אמור לעבוד… ואז התחלתי להיתקל בכל מני מכשולים בדרך…
הצורב הפוך, הקליפס הפוך…
הצורב מגיע עם כמה כבלים וכרטיס מתאם חיבורים שאמור להקל על החיבור.
על הכבל שמחבר בין הצורב לכרטיס מתאם (השני משמאל בתמונה) יש עוד איזה שהוא חיבור שאני לא צריך, אז חשבתי לעזוב אותו בינתיים ולקחת כבל שטוח 2x5 במרווח 1.27 מ"מ שיש לי במלאי.
בזמן שחיכיתי לצורב, מצאתי באינטרנט קליפס עם Pogo Pins המיועד בדיוק למה שאני צריך - חיבור זמני כדי שאפשר יהיה לצרוב את התוכנית ההתחלתית בתהליך ייצור מבלי שצריך להלחים מחבר על המעגל.
זהו קליפס דומה באתר של Adafruit:

שלי קצת שונה, אבל גם לו יש מחברי Pogo ומחבר עם פינים במרווח 2.54 מ"מ כדי שיהיה יותר קל להתחבר. למעשה, היה מולחם עליו מחבר 2x6 פינים, למרות שיש רק 10 מחברי Pogo. קיצצתי 2 פינים שלא בשימוש כדי שאפשר יהיה לחבר אליו מחבר כבל שטוח עם מחבר 2x5.
על כרטיס מתאם החיבורים יש גם מחבר 2x5 במרווח 2.54 מ"מ ומקבלים גם כבל שטוח עם שני מחברים כאלה בקצוות. מעולה… אני יכול לחבר את המתאם לצורב עם כבל 2x5 של 1.27 מ"מ, מהמתאם לקליפס עם כבל 2x5 של 2.54 מ"מ ויכול להתחיל עם הצריבה…
אבל שמתי לב שסדר החיבורים בין המחבר 2.54 מ"מ על הקליפס לבין ה-Pogo pins הוא הפוך… כלומר השורה הראשונה של מחברי ה-Pogo מחוברת לשורה השניה של מחבר ה-2x5 של 2.54 מ"מ. לא יודע אם זה טיפשות של מי שיצר את הקליפס, או שיש לזה הגיון כלשהו… אחרי קצת מחשבה, נראה שהסידור הזה מסתדר אם אני מנסה להתחבר מצידו התחתון של המעגל. רק שבמקרה שלי זה לא אפשרי כי הקליפס צריך לעבור מעל מחברים והמבנה שלו מכריח אותי לחבר אותו רק מהצד העליון.
פתרתי את זה די בקלות. לוח הלחמה קטן, מחבר שורה 2x5 נקבה ומחבר 2x5 זכר לכבל שטח. קצת חוט WireWrap והלחמות ויש לי מתאם שהופך את סדר השורות של הפינים.
רק שהחורים של חיבור ה-SWD אליו צריך לחבר את הקליפס קצת רחוקים מהקצה של המעגל, כך שהיה צריך להחזיק את הקליפס בזווית לא נוחה במיוחד, והצורב הראה דברים קצת לא הגיוניים. החלטתי בינתיים פשוט להלחים מחבר 2x5 זכר של 1.27 מ"מ על המעגל כדי שאפשר יהיה לחבר ישירות בין הצורב למעגל עם כבל שטוח.
היה לי חשד שהקליפס לא יגיע למחבר כי כשתכננתי את המעגל לא ידעתי שקיים מוצר כזה וכשהזמנתי את הקליפס המעגלים כבר היו מוכנים. לייצור הבא של המעגלים כבר הזזתי את המחבר למיקום קרוב יותר לקצה כדי שהקליפס יוכל להתחבר בקלות. בכל מקרה יש לי עוד כמה שינויים שדורשים Revision 2 של המעגל.
טוב… אז הצורב מחובר למעגל בצורה יפה עם הכבל השטוח…
תוכנת הצריבה בודקת את המתח על המעגל כדי להבין אם מתקיימים התנאים הדרושים לצריבת הבקר. ובמקרה שלי היא מראה לי כל הזמן 2.7V ולא מצליחה לתקשר עם הבקר…
בודק את המתחים (3.3V), בודק את הקווים מול המפרט של הבקר… הכל נראה תקין ולי אין מושג מה קורה כאן…
מתחיל לחפש ברשת אם מישהו דיווח על מקרה דומה… מגיע לאיזה שהוא דיון, בו מישהו התלונן על זה שהוא לא מצליח לצרוב כרטיסים חדשים, למרות שעשה את זה כבר מאות פעמים בעבר וגם אצלו התוכנה הראתה כל הזמן 2.7V. הבחור חשב שאולי שרף את הצורב שלו, או שאולי עדכון התוכנה הכפוי של הצורב הרס משהו. גם במקרה שלי תוכנת הצריבה חייבה אותי לעשות עדכון לצורב, אז התחלתי לדאוג.
אז מישהו בדיון הזה שאל שאלה "טיפשית" כהגדרתו: האם אתה משתמש בכבל המקורי שהגיע עם הצורב, או כבל אחר?
מסתבר שיוצרי הצורב בכוונה משתמשים בכבל הפוך ולא סטנדרטי! כל הכבלים השטוחים שתמצאו למכירה יהיו בנויים כך שסדר הקווים במחברים יהיה זהה, אלא אם זה כבל מיוחד שהופך כמה קווים, וזה יהיה כנראה מתועד. קו הראשון של הכבל (בדרך כלל מסומן בצבע שונה) יהיה בפין הראשון של המחבר. לא במקרה של כבל מקורי של הצורב הזה! בכבל שלהם קו הראשון יהיה בפין 1 של מחבר אחד ופין 10 במחבר השני. כלומר צד אחד הפוך מהמקובל…
במחברים של כבלים שטוחים יש בליטה שלא מאפשרת להפוך את המחבר. אם ממש מתעקשים, אפשר לשייף את הבליטה כדי שלא תפריע להפוך את המחבר.
האם עשו את זה בטעות? או בכוונה?
לא יודע… יודע להגיד רק שכבל מקורי נמכר ב-$37.40 ב-Digikey… לא זול במיוחד לכבל פשוט שאמור לעלות לא יותר מכמה דולרים בודדים, גם מחוץ לסין…
נכנעתי. חיברתי את הכבל המקורי שהגיע עם הצורב ו… הופה! הוא מזהה את ה-3.3V על המעגל וגם מצליח לזהות את הבקר… יש סימני חיים!
עכשיו אני יכול סוף סוף לצרוב את ה-bootloader…
לפני שאנסה לקמפל גרסה משלי, מנסה לצרוב את הגרסה של SparkFun שמפורסמת ב-repo שלהם כאן.
הם שמו שם רק את הבינארי של ה-bootloader. לפני כמה שבועות שלחתי להם אימייל עם שאלה איפה אני מוצא את קובץ ההגדרות שהם השתמשו כדי לייצר את הבינארי. יש שם כל מני הגדרות של תדרים, אילו קווים הולכים לאן, כמו למשל איזה קו מחובר ללד ברירת מחדל שניגשים אליו עם קבוע LED_BUILTIN ועוד כל מני דברים מתקדמים. רשמתי להם שציפיתי למצוא שם את הקוד של ה-bootloader ולא רק את קובץ ה-BIN.
התשובה שקיבלתי הפתיע אותי מאוד. שאלו את המהנדס שטיפל בזה, והוא ענה שהוא זוכר שהוא עשה התאמות מסוימות לקומפילציה כדי להתאים את הקוד למוצר שלהם, אבל הוא כנראה עשה את זה על המחשב שלו ולא דחף את הקבצים ל-GitHub. אז אם אני רוצה, אני יכול להסתכל על תכנון המעגל שלהם כדי לראות מה שונה שם בהשוואה לכרטיס SAMD21 אחר ולפי זה לייצר את קובץ ההגדרות

עניתי להם שכאחת החברות שדוחפת כל כך חזק את תחום ה-OpenSource הייתי מאוד מופתע לראות את קבצי ה-BIN ולא את הקוד המקור של ה-bootloader, ועוד יותר הייתי מופתע לקבל תשובה כזו…
אבל עשיתי עוד חיפושים ב-GitHub שלהם ונראה שמצאתי את הקוד של ה-bootloaders שהם משתמשים לכרטיסים. שאלתי אותם אם זה הקוד הנכון. קיבלתי תשובה לא הכי ברורה עם קישורים שונים, אבל המיקום הזה נתן לי את הכיוון הראשוני, היה שם קובץ ההגדרות שחיפשתי.
טוב, אז יש לי את קובץ ה-BIN של ה-bootloader של SparkFun שאפשר להתחיל ממנו כדי לראות סימני חיים של הבקר על הכרטיס שלי…
צורב… ו… כלום… הכרטיס לא מזדהה ב-USB, לא מהבהב ולא כלום…
מצב מבאס כי אני לא יודע איפה יכולה להיות הבעיה. כבר מתחיל לחשוב על לחבר את הסקופ, לראות אם יש פולסים על קו השעון… משהו שיראה סימני חיים כלשהם…
למזלי עדיין לא צללתי כל כך עמוק, החלטתי לשמור את תוכן הזכרון של כרטיס SparkFun שהיה לי על השולחן ולצרוב אותו על הכרטיס שלי. ונחשו מה? זה עבד! הלד התחיל להראות "נשימה" שמאפיינת את ה-bootloader שעל הכרטיס והוא הופיע ברשימת ההתקנים ככרטיס SparkFun SAMD21! סימני חיים מובהקים!
אבל מרוב הבלגן שהיה לי על השולחן באותו רגע, כמה כרטיסים, חוטים, כמה כבלי USB שהייתי צריך להעביר בין הכרטיסים, מייצב מתח חיצוני שהייתי צריך להעביר בין כרטיס לכרטיס… כנראה קיצרתי משהו וכרטיס שלי שבק חיים לגמרי…
למזלי הרכבתי 2 כרטיסים כאלה בשלב הניסיונות של מכונת ה-Pick-n-Place, כך שהיה לי עם מה להמשיך. ניקיתי את השולחן, צרבתי את תוכן הזכרון מהכרטיס של SparkFun (שכולל את אזור ה-bootloader ותוכנית כלשהי שהייתה צרובה על הכרטיס, שאני כבר לא זוכר מה היא עשתה), וגם הכרטיס הזה הראה סימני חיים.
מעודד מהמצב צרבתי תוכנית blink המפורסמת כמו שעושים עם כל כרטיס ארדואינו, והלד הבהב כמו גדול…
כמובן שלחתי אימייל ל-SparkFun שיבדקו מה הם שמו ב-repository שלהם. Bootloader זה כנראה לא.
שלב הבא: לקמפל bootloader משלי עם שם הכרטיס שלי וגם VID/PID שקיבלתי לשימוש מ-Microchip.
לקמפל bootloader
איך עושים את זה?בגלל הבלאגן סביב ה-bootloader של SparkFun, החלטתי ללכת על המקור ולהסתמך על ה-repository של צוות Arduino עצמו. בסופו של דבר כל כרטיסי ה-SAMD21 שקיימים בשוק מסתמכים על הקוד של כרטיס Arduino Zero. גם הקוד של SparkFun וגם של Adafruit נגזר משם.
עושה clone ל-repository שכולל bootloader, מכין קובץ הגדרות עם הפרמטרים הרלוונטיים לכרטיס שלי, מריץ make עם כמה פרמטרים ואמור לקבל קובץ BIN ו-HEX עם ה-bootloader.
זה בתאוריה… בפועל כמובן ששום דבר לא עובד…
ב-README של ה-repository אומרים שצריך להתקין כלים של ARM לקומפילציה. יש אפילו קישור מה צריך להוריד ולהתקין. ל-Linux יש שם קובץ דחוס שצריך לפתוח וכנראה להעתיק למיקום כלשהו. לא רשום לאן. ניחשתי לפי הספריות ב-Makefile של סביבת ה-bootloader איפה קצבים אלה אמורים להיות ממוקמים.
לבסוף הסתבר שהקישור ב-README מוביל לגרסה ישנה יותר, ולא זו שה-Makefile מצפה לה (שוב ניחוש לפי שמות הספריות שבמקרה כוללות גם גרסה של הכלים). מצאתי את הגרסה הנכונה של הכלים, העתקתי לספריה הנכונה.
מריץ שוב את ה-make… עכשיו חסר קובץ הגדרות של המעבד sam.h.
ברור לי שחסרה איזו ספריה שצריך להתקין… מחפש ברשת, מוצא שהתשובה לזה היא להתקין את התמיכה של כרטיסי SAMD דרך הממשק של Arduino IDE. אבל אצלי זה כבר מותקן. מנסה להסיר, להתקין שוב, אבל עדיין הקבצים הנחוצים לא מותקנים. קצת מוזר…
מצאתי חלק מהקבצים ב-github של Arduino, אבל לא את כולם. אז להעתיק אותם כמו שזה גם לא יעזור.
מחפש עוד קצת ומוצא שכלי ה-arduino-cli שמאפשר לעשות קומפילציות וצריבות משורות הפקודה (command line), מסוגל גם להתקין ספריות שונות, אחת מהן היא דברים הנחוצים לפיתוח על כרטיסי SAMD21. עשיתי את זה וקיבלתי את כל מה שהייתי צריך. make נוסף ויש לי את ה-BIN וה-HEX שהייתי צריך. צריבת bootloader נוספת עם הקצבים שנוצרו ואני רואה את נשימת הלד של ה-bootloader. צריבת ה-blink דרך ה-USB גם עובדת והלד מהבהב כמצופה.
אפשר לסמן V גם על השלב הזה.
מה הלאה?
אני מתכנן להרכיב עוד 2 כרטיסים לטובת ניסויים. גם כדי להשתפשף עוד קצת בתהליך הייצור, וגם בגלל שכרטיס אחד שבק חיים והכרטיס השני אומנם מראה סימני חיים מבחינת הבקר, אבל רוב המחברים שעל הכרטיס נשרפו והתעוותו בגלל טמפרטורה גבוהה מדי בתנור ההלחמות, כך שתהיה לי בעיה לבדוק שכל החיבורים מתפקדים כמו שתכננתי אותם. את הטמפרטורה של התנור כבר כיילתי, אבל עדיין לא ניסיתי להלחים עם ההגדרות החדשות…אחרי זה אוכל לבדוק את כל החיבורים, לצרוב את ה-eeprom בעזרת תוכנית ראשונית שתצרב יחד עם ה-bootloader.
יש לכם הערות או שאלות?
מוזמנים לשאול ולהגיב כתגובה לפוסט זה בפייסבוק. אל תשלחו הודעות פרטיות, זה לא עובד לי משום מה.