מי אמר זיכרון ולא קיבל?

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

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

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

Arduino nano and the 23K256
ארדואינו נאנו ושבב הזיכרון הסריאלי הזעיר

אנחנו מדברים על רכיב בשם 23K256 של חברת Microchip. זהו ג'וק קטן בעל שמונה רגליים בלבד, מותאם למהירות שעון מרבית של 20 מגהרץ, שמחזיק בתוכו 32 קילובייט של נתונים. מה שמייחד אותו מרוב רכיבי הזיכרון שיש (למיטב ידיעתי) בשוק הוא שזהו רכיב סריאלי, כלומר מעביר את הנתונים ביט אחרי ביט, ולא מקבילי. מצד אחד, זה חוסך המון חיבורים לארדואינו – ומצד שני מחייב קצת יותר השקעה בתכנות.

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

שתיים מרגלי הג'וק הן עבור המתח החשמלי (חשוב לשים לב – עד 4.5 וולט לכל היותר! לא לחבר ליציאת 5V של הארדואינו!) והאדמה. יש לו כניסת נתונים אחת ויציאת נתונים אחת, כניסת שעון, כניסת "בורר שבב" (Chip Select – CS) וכניסת "המתנה" (Hold) שאינה חיונית. מה עם הרגל השמינית? NC, כלומר No Connection. סדר הפעולות המינימלי פשוט מאד:

  1. מורידים את המתח מרגל CS כדי להודיע לשבב שהתקשורת מתחילה
  2. תוך כדי "תקתוק" של השעון, משדרים לשבב ביט אחרי ביט אחת משתי פקודות – קריאה או כתיבה (כל אחת היא בייט יחיד, מוגדר מראש)
  3. עדיין בתקתוק, משדרים את ששה-עשר הביטים של כתובת הבייט הרצויה. הג'וק מתעלם מהביט הראשון, מה שמשאיר 32,768 כתובות בעלות משמעות (0-32,767)
  4. כעת, כמובן תוך כדי תקתוק, מפמפמים פנימה את בייט הנתונים דרך הכניסה או קוראים את הבייט דרך היציאה, בהתאם לפקודה שנתנו קודם
  5. מעלים שוב את המתח ב-CS כדי להודיע לשבב שזהו, הפעולה הנוכחית הסתיימה.

המימוש של הפרוצדורה הזו קצת פחות טריוויאלי, מכיוון שהביטים נשלחים מהחשוב ביותר (MSB) לפחות חשוב (LSB), וצריך להתחשב בסידור הבייטים בתוך משתנים מסוג int שמשמשים לכתובות. אף על פי כן, מדובר בסך הכל בקוד פשוט, וכעת יש לנו 32 קילובייטים שלמים בגישה מהירה, לאחסון מדידות לאורך זמן, תוצאות חישובים ועוד. עם קצת מאמץ אפשר לשרשר מספר רכיבים כאלה ולהגדיל את הזכרון כמה שרק רוצים.

בעתיד, מן הסתם, אשכלל את הפונקציות כך שיכסו את מלוא היכולות של השבב ואולי אף אצור מהן ספריה. בינתיים, הנה לכם הקוד, וסרטון שלו עם הג'וק בפעולה:

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

לא ציינת איך הורדת את המתח מ-5 וולט למתח של 4.5 וולט?
או שסיפקת לו 3.3 וולט.
כמו שציינתי קודם חבל שאין שרטוט.

[עריכה: נכתב כתגובה ל-https://www.idogendel.com/whitebyte/archives/207#comment-59 -עידו]

מערכת הפעלה…
זאת אומרת תוכנה שתנהל את הזיכרון עצמו, ותדע להעתיק קטעי קוד של תוכניות אחרות משבבי זכרון אל המעבד. זה נראה לי מסובך בטירוף, אבל ככה פועל מחשב, לא?

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

תודה

מה קורה אם התוכנה עצמה גדולה מדי בשביל הזכרון של הארדואינו?