מה המהירות האמתית של Serial?

חקירה קצרה שמוכיחה כי בעולם המיקרו-בקרים, אסור להניח שום הנחות ואי אפשר לסמוך על אף אחד.

כמה נמוך אפשר לרדת?

אחד הדברים הראשונים שלומדים לעשות עם ארדואינו הוא להשתמש בחיבור הסריאלי: מגדירים בקוד את קצב השידור (המספר שנשלח ל-Serial.begin), פותחים במחשב את הסריאל מוניטור ובוחרים בו קצב זהה, והמידע יכול לזרום באופן חופשי הלוך ושוב.

הסריאל מוניטור של ארדואינו במחשב מאפשר רק בחירה מוגבלת, בין מספר קצבי שידור מוגדרים מראש. עם תוכנות משוכללות קצת יותר, כמו Serial Monitor Deluxe שכתבתי (להלן "SMD") או תוכנות הדמיית טרמינל למיניהן, אפשר לבחור כל ערך שרוצים – בגבולות הסביר כמובן. אבל איפה בדיוק עוברים הגבולות האלה?

ב-SMD, הערך המינימלי שמותר לציין הוא 110 באוד, מכיוון שכאשר כתבתי את התוכנה זה היה הערך המוכר הכי נמוך שמצאתי בתיעוד כלשהו. אם כותבים קוד בארדואינו עם הגדרה כזו:

Serial.begin(110);

השידור והקליטה עובדים בלי בעיה בינו לבין SMD. האם אפשר לרדת לקצבי שידור נמוכים עוד יותר?

תקשורת בלתי אפשרית

כשכתבתי את הערך בוויקי ל-Serial.begin, חשבתי שיהיה מעניין ונכון להוסיף את ערכי המינימום והמקסימום שהארדואינו תומך בהם בפועל. אך בחיפוש ברשת לא הצלחתי למצוא מידע מהימן בנושא, ולכן פניתי לקוד המקור ול-datasheet של ATmega328, כדי להבין מה בדיוק Serial.begin עושה עם חומרת ה-UART של המיקרו-בקר, ואיך הוא עושה את זה.

ושם התגלה משהו מוזר. בחומרה של ה-UART, שעון המערכת (16MHz, בארדואינו טיפוסי) יכול להתחלק ב-16, ולאחר מכן במספר נוסף לבחירתנו בין 1 ל-4096. המספר הנוסף הזה נקבע באמצעות 12 ביטים שמתפרסים על פני שני רגיסטרים של 8 ביט כל אחד. ארבעת הביטים הנותרים אינם בשימוש וחייבים להישאר 0. אם תחלקו את המספרים כמו שצריך תגיעו לתדר שעון סופי (מעוגל למעלה) של 245 הרץ, או ביטים לשניה – במקרה הזה המשמעות זהה. אז אם התדר המינימלי שהחומרה מאפשרת הוא 245 באוד, איך יכול להיות שהצלחתי לעבוד ב-110 באוד?

הלכתי לברר את העניין בפורום המיקרו-בקרים ב-arduino.cc, ואחרי התברברות קצרה עם הסקופ הסתכלתי על התקשורת היוצאת מהארדואינו בעזרת לוג'יק אנלייזר כדי למדוד אותה במדויק. הסתבר שכאשר שלחתי את הערך 110 ל-Serial.begin, בפועל התקשורת הטורית יצאה מהארדואינו במהירות של יותר מ-1000 באוד!

זה היה הגיוני מהבחינה של החישוב הקודם: אי אפשר לרדת מתחת ל-245, וכל מספר נמוך יותר יגרום לשיבוש ברגיסטרים ולמהירויות לא צפויות. אבל זה עדיין לא היה הגיוני מבחינת התקשורת עם המחשב – איך הגדרתי לו קצב של 110 באוד והוא בכל זאת הסתדר בלי בעיה עם השידור המשובש?

סמוך על סמוך

ההשערה שהועלתה בפורום בעניין זה היתה מאירת עיניים ממש. התקשורת ב-110 באוד נראית לנו בלתי אפשרית כי אנחנו מניחים – אוקיי, לפחות אני הנחתי – שלמחשב יש שעון משלו ואמצעים משלו לקרוא את הסיגנלים. אבל זה ממש לא עובד ככה. הרי האות הסריאלי לא עובר כמות שהוא אל המחשב אלא בתיווך של פרוטוקול USB – וההמרה מסריאל ל-USB מתרחשת בארדואינו עצמו. יותר מזה, בלוח הארדואינו שבו השתמשתי (מסוג Uno R3), ההמרה בוצעה על ידי שבב ATmega16U2 מתוצרת Atmel – שבנוי בדיוק באותה ארכיטקטורה כמו ה-ATmega328, ושסביר להניח שגם ה-UART שלו בנוי באותה צורה!

זה אומר שכאשר אני מורה לתוכנה במחשב לעבוד ב-110 באוד, היא לא באמת מתאימה את עצמה לקצב הזה. במקום זאת, היא פונה לדרייבר ה-COM PORT ואומרת דרכו לג'וק המתאם "מעכשיו אתה עובד בשבילי ב-110, בסדר?" הג'וק, בגלל תכנות לא זהיר, לא שם לב שזהו ערך נמוך מדי, אומר "בסדר" ובפועל מתחיל לעבוד בקצב אחר לגמרי. אבל אותו שיבוש בדיוק הרי קיים גם ברכיב הבא בתור, אז כולם עובדים אחד על השני ומספרים לעולם שהם עובדים ב-110 באוד אף על פי שקצב התקשורת בפועל הוא יותר מפי עשרה. אם היה אלמנט אחר במערכת שהיה תלוי בתזמון המדויק של אותות התקשורת, הסיפור הזה היה יוצר באגים נוראיים, שכנראה היה גם קשה מאד לאתר.

ההשערה הזו קיבלה תמיכה נוספת כשניסיתי את אותו התרגיל עם לוח ארדואינו Duemilanove, ששבב התקשורת בו הוא לא של Atmel. כצפוי, התקשורת ב"110" באוד לא עבדה כלל.

הגבול העליון

כדי למצוא את קצב התקשורת המרבי, כבר לא סמכתי על מדידות מול המחשב. לפי ה-datasheet, הערך המרבי (שעון מערכת חלקי 8 חלקי 1) הוא שני מיליון – וכששלחתי ל-Serial.begin את הערך הזה, הזמנים שהתקבלו בלוג'יק אנלייזר היו הגיוניים. מעבר לזה, כמו מתחת ל-245, הכל יכול לקרות – חוץ מאשר, כמובן, תקשורת מהירה יותר…

להרשמה
הודע לי על
2 Comments
מהכי חדשה
מהכי ישנה לפי הצבעות
Inline Feedbacks
הראה את כל התגובות

מעניין מאוד.
רק מוכיח שטעויות של מתכנת חאפר יכולות להשמר לדראון עולם בקוד פופולארי.
אני לא רוצה לחשוב בכלל כמה טעויות של חאפרים היו בקוד המקור של DOS, וכמה הרבה הרבה יותר קשה יהיה לשים עליהן יד. וכמה זה גרע מהיציבות של גרסאות מתקדמות יותר של חלונות (95,98 על מסכיהן הכחולים. את me אני אפילו לא אוסיף לרשימה).

חשבת לנסות לעבוד אצל החבר'ה של הארדואינו? נראה לי שיועיל להם מישהו קצת יותר דקדקן ויסודי 😉