← Drivers Development on STM32 Microcontrollers

שיעור 0 — היכרות, הקמת סביבת העבודה וממשקי ה-MCU

טוען נגן…

תמלול

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

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

## הצגת המרצה

ברוכים הבאים לקורס Drivers Development on STM32 Microcontrollers.

שמי אור פוקס. יש לי 10 שנות ניסיון טכני בתעשייה, מתוכן 7 שנים בפיתוח תוכנה. עבדתי על Low-Level Embedded ב-Linux. יש לי בסיס באלקטרוניקה מגף 108 בחיל האוויר.

יצא לי לעבוד על כמה Network Stacks, גם על TCP/IP ל-Satellite Communication וגם על LTE eNodeB (של 4G). ההתמחות העיקרית שלי היא High-Performance Multi-Threaded Real-Time ב-C/C++ ב-Embedded Linux.

עבדתי ועובד על מעבדי ARM מסידרת Cortex-M3 ו-Cortex-M4 עבור כמה פלטפורמות שונות. הידע העיקרי שלי כולל Yocto, Kernel, ו-Driver Development.

בקורס הזה אנחנו נדבר על איך מפתחים דרייברים לרכיבים ולמעבדים מסידרת Cortex-M3 ו-M4 של ARM עבור מכשירי IoT, ונדבר על Low-Level Development. יצא לי לעבוד הרבה על Hardware Bring-up ו-Board-Level Communication.

## סבב היכרות

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

**אילון:** נעים מאוד, קוראים לי אילון אסרף, נשוי פלוס שלושה, מירושלים. סיימתי תואר בהנדסת אלקטרוניקה לפני כ-10 שנים. כיום עובד ב-Mobileye במשרת הנדסאי. הכיוון שלי הוא יותר ל-Chip Design, ASIC או FPGA. בתל אביב עובד כרגע ב-ASIC.

**אור:** מגניב. כן, יש אצלכם הרבה ASIC ו-Logic Design, במיוחד למצלמות ולרדארים. דרייברים ב-Linux ראיתי שיש ב-Mobileye, פחות על Bare Metal, אבל אפשר לקחת את הידע הזה ולהחיל אותו על כל סוגי הדרייברים, גם ל-Windows וגם ל-Linux. עידן, תרגיש חופשי.

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

**אור:** מעולה. עידן עשה איתנו את הקורס Bare Metal. שר, תרגיש חופשי.

**שר:** אלן, אני סטודנט שנה אחרונה בהנדסת מכונות. לקחתי מגמה של בקרה ומכטרוניקה, יצא לי להתעסק קצת עם STM ב-Windows, בפלטפורמת PlatformIO. אני מכיר GPIO ו-Analog-to-Digital, אבל לא עברנו על פרוטוקולי תקשורת, וזה נושא שמאוד מעניין אותי.

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

**דן:** אני דן, מתעסק בפיתוח תוכנה מ-2014. עברתי ל-Embedded ב-2021. באתי לקורס כי מדי פעם אני מקבל בעיות עם הדרייברים של STM וצריך לחפור בקוד שלהם כדי לפתור את הבאגים. רציתי להכיר את זה לעומק.

**אור:** מצוין. אבי, תרגיש חופשי.

**אבי:** סיימתי ללמוד הנדסת חשמל ואני מתעסק בתחום ה-RF.

**אור:** RF זה מגניב. יצא לי לעבוד על RF ב-4G ובאנטנות מכ"ם.

אוקיי, סבבה. אתם רואים את המסך המשותף שלי, נכון? מצוין.

## סקירת סילבוס הקורס

מה נעשה בקורס?

1. **Introduction:** יסודות הקורס ומושגי יסוד בדרייברים.

2. **GPIO Deep Dive:** קונפיגורציה של פינים, שליטה ואופטימיזציה.

3. **I2C Driver Development:** מימוש תקשורת Master/Slave.

4. **SPI Driver Development:** תקשורת טורית במהירות גבוהה.

5. **UART Introduction:** בסיס לתקשורת טורית אסינכרונית (כולל RS-232 ו-RS-485).

6. **Working with STM32 HAL:** עבודה עם שכבת ה-Hardware Abstraction Layer.

7. **Low Power Modes:** ניהול צריכת חשמל ואופטימיזציה (כדי לא לעבוד ב-100% CPU ולא לבזבז אנרגיה).

8. **Personal Projects:** מימוש דרייבר אישי.

9. **Wrapping Up Projects:** אינטגרציה ובדיקות.

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

## פילוסופיית הקורס ומטרותיו

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

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

המטרות הן לקבל את הידע וה-Skills כדי לתכנן ולממש דרייברים לכל פלטפורמות ה-MCU. ה-Native שלי למשל הוא Silicon Labs (עם Simplicity Studio), אבל ברגע שיודעים לעבוד עם פלטפורמה אחת (כמו TI, Silicon Labs או STM32), יודעים לעבוד עם כולן. בייחוד כשמדובר בארכיטקטורת ARM Cortex-M.

המטרה היא להבין איך אנחנו שולטים ב-Microcontroller, בדרייברים ובפריפריאליים ברמת ה-Low-Level: איך מקנפגים שעונים, איך עושים Interrupt Handling, ואיך עובדים עם ארכיטקטורת הזיכרון ומבני נתונים כדי לשלוט בהם כראוי.

## נושאי השיעור והקמת סביבת העבודה

מה נעשה היום?

* נעשה Recap של הקורס הקודם.

* נסביר מהם דרייברים ומה השלבים לפיתוח ממשק דרייבר (Driver Interface Example).

* נסביר מהי שכבת הדרייבר (Driver Layer).

* נלמד איך לבחור רכיבים שמתאימים ל-MCU Integration Guide.

* נדבר על הכנה לאינטגרציה.

* נכיר MCU Bus Interfaces.

* נדבר על MCU Interrupts (של היצרן ופסיקות EXTI של STM32).

מבחינת סביבת עבודה: נשתמש ב-STM32CubeIDE. למה? זה לא הכי נוח לכתוב שם קוד, אבל זו סביבת הפיתוח עם האינטגרציה הכי טובה ל-STM32. היא מבוססת Eclipse (כמו Simplicity Studio של יצרנים אחרים).

נשתמש ב-Git Bash עבור משתמשי Windows. מומלץ להתקין Git. לגבי Mac - אין מניעה לעבוד על Mac, פשוט מתקינים את STM32CubeIDE ל-Mac ומשתמשים ב-Terminal הרגיל במקום Git Bash.

מבחינת החומרה: אני עובד עם לוח STM32F411E-DISCO. אתם יכולים לעבוד עם כל לוח STM32, רק תעשו התאמות לפי ה-Reference Manual של הלוח שלכם. בנוסף נשתמש ב-Arduino (כמו Arduino Uno) לצורך סימולציה של צד Slave/Master בתקשורת.

## כלי Git ופקודות בסיסיות

מבחינת Git, הפקודות הבסיסיות שטרם הכרתם:

* `git clone` - לשכפול ה-Repository.

* `git status` - לבדיקת מצב הקבצים.

* `git fetch --all` - למשיכת עדכונים מהשרת.

* `git checkout -b <branch_name>` - ליצירת Branch חדש עבור המטלות שלכם.

אתם יכולים ליצור Branch משלכם, לדחוף אליו קוד, ואני אוכל לעבור על המטלות שלכם ב-GitHub.

ה-Repository של הקורס זמין ב-GitHub. תמצאו שם קובץ `README.md` עם הסברים על הקורס, דרישות החומרה, והכלים הנדרשים.

## חזרה על קורס היסודות (Bare Metal)

נחזור בקצרה על מה שלמדנו בקורס היסודות:

* **Bare Metal Foundation:** עבודה ישירה מול הרכיב ללא מערכת הפעלה (OS).

* **ארכיטקטורת ARM Cortex-M:** עבודה מול מעבדים מסדרת Cortex-M3/M4.

* **Exception Handling & Interrupts:** טיפול באירועים אסינכרוניים שהמעבד מקבל ומקפיצים אותו לקוד ספציפי.

* **Multitasking Implementation:** מימוש מנגנוני Multitasking ללא מערכת הפעלה - Task Scheduling, Context Switching, ו-Stack Organization.

* **Real-Time Design & Timers:** עבודה מול טיימרים ושימוש ב-Schedulers.

* **Optimization Techniques:** אופטימיזציות קומפיילר, Bit Manipulation, ודפוסי גישה לזיכרון.

## מהו דרייבר? (Driver Architecture)

דרייבר הוא שכבת אפסטרקציה (Hardware Abstraction) בין קוד האפליקציה (הלוגיקה של המערכת) לבין הפריפריאלים בחומרה (Hardware Peripherals).

למה נדרש דרייבר?

1. **חציצה והפרדה:** האפליקציה לא צריכה לדעת איזה אוגר (Register) מדויק מפעיל את הפין. היא קוראת לפונקציה כמו `send_byte` או `set_pin`.

2. **API אחיד:** מתן ממשק קבוע וסטנדרטי להפעלת החומרה.

3. **ניהול משאבים (Resource Management):** אתחול (Init) ושחרור (Deinit) של הפריפריאל.

4. **Error Handling:** זיהוי שגיאות חומרה (כמו טיימאאוט או כשל בתקשורת) והחזרת קודי שגיאה מתאימים לאפליקציה.

5. **Portability:** היכולת להעביר את קוד האפליקציה למיקרו-בקר אחר על ידי החלפת הדרייבר בלבד.

## שלבים לפיתוח ממשק דרייבר

כשניגשים לפתח דרייבר חדש, עובדים לפי השלבים הבאים:

1. **ניתוח תיעוד החומרה:** קריאת ה-Datasheet וה-Reference Manual של הפריפריאל והמיקרו-בקר.

2. **הגדרת דרישות ומגבלות:** תזמונים, מתיחים, קצבי העברת נתונים.

3. **תכנון ממשק הדרייבר (Driver Interface Design):**

* הגדרת קובצי Header (`.h`).

* הגדרת מבני נתונים (Structures) ו-Enums עבור קונפיגורציה.

* הגדרת חותמות פונקציות (Function Prototypes) - API.

* הגדרת קודי שגיאה (Error Codes).

4. **מימוש פונקציות הליבה (Core Implementation):**

* פונקציות אתחול ושחרור (`init`, `deinit`).

* פונקציות קריאה וכתיבה (`read`/`receive`, `write`/`transmit`).

* פונקציות שליטה וקונפיגורציה (`control`, `set_mode`).

5. **טיפול בפסיקות (Interrupts):** כתיבת ISR (Interrupt Service Routine) ו-Callbacks.

6. **בדיקות (Testing):** כתיבת קוד בדיקה ואימות מול החומרה באמצעות סקופ או לוג'יק אנלייזר.

### דוגמה לממשק דרייבר (RS-485 Example)

בקובץ ה-Header נגדיר את המבנים ופונקציות ה-API. למשל:

```c

typedef enum {

RS485_OK = 0,

RS485_ERROR,

RS485_BUSY,

RS485_TIMEOUT

} RS485_Status_t;

typedef enum {

RS485_MODE_RECEIVE = 0,

RS485_MODE_TRANSMIT

} RS485_Mode_t;

typedef struct {

uint32_t baud_rate;

RS485_Mode_t mode;

// Additional configuration fields

} RS485_Config_t;

RS485_Status_t RS485_Init(RS485_Config_t *config);

RS485_Status_t RS485_DeInit(void);

RS485_Status_t RS485_Transmit(const uint8_t *data, uint16_t size, uint32_t timeout);

RS485_Status_t RS485_Receive(uint8_t *buffer, uint16_t size, uint32_t timeout);

RS485_Status_t RS485_SetMode(RS485_Mode_t mode);

```

האפליקציה תשתמש אך ורק בפונקציות האלה ולא תיגש ישירות לרגיסטרים של ה-UART או ה-GPIO המנוהלים על ידי הדרייבר.

## בחירת רכיבים ואינטגרציה ל-MCU

כשבוחרים רכיב חיצוני (חיישן, מסך, רכיב תקשורת) לעבודה מול ה-MCU, יש לבדוק:

1. **רמות מתח (Voltage Levels):** האם ה-MCU עובד ב-3.3V והרכיב ב-5V או 1.8V? האם נדרש ממיר רמות מתח (Level Shifter)?

2. **צריכת זרם (Current Consumption):** האם ה-MCU יכול לספק את הזרם הנדרש מפיני ה-GPIO/המתח, או שנדרש ספק מתח/טרנזיסטור חיצוני?

3. **ממשק תקשורת (Communication Interface):** האם הרכיב עובד ב-I2C, SPI, UART? האם ל-MCU יש פריפריאל פנוי מתאים?

4. **פינים ופונקציות אלטרנטיביות (Alternate Functions):** לוודא שאין התנגשות בפינים (Pin Conflict) בין פריפריאלים שונים ב-MCU.

5. **דרישות תזמון (Timing Requirements):** האם קצב התקשורת של הרכיב נתמך על ידי ה-MCU?

## ארכיטקטורת STM32 ומסמכי התיעוד

כשעובדים עם STM32, יש שני מסמכים מרכזיים שחובה להכיר:

1. **Datasheet:** מפרט חומרה ספציפי למשפחת המעבדים/הג'וק (Pinout, Electrical Characteristics, Memory Size, Package).

2. **Reference Manual:** מסמך מקיף המתאר את כל הרגיסטרים, הפריפריאלים, ואופן התפעול שלהם ברמת התוכנה.

במפת הזיכרון (Memory Map) של STM32, כל הרגיסטרים של הפריפריאלים ממופים לכתובות זיכרון ספציפיות. לכל פריפריאל (GPIO, USART, SPI וכו') יש כתובת בסיס (Base Address), והרגיסטרים שלו מוגדרים לפי Offset מכתובת הבסיס.

## אפיקי תקשורת פנימיים (MCU Buses)

בתוך ה-MCU, הרכיבים והפריפריאלים מחוברים למעבד דרך מערכת אפיקים (Buses):

* **AHB (Advanced High-performance Bus):** אפיק מהיר המחבר את ה-CPU, ה-SRAM, ה-Flash, ה-DMA, ופתיחות מהירות כמו GPIO (בסדרות STM32F4 למשל).

* **AHB1 / AHB2:** חלוקה תת-אפיקית לפי מהירויות וציוד היקפי.

* **APB (Advanced Peripheral Bus):** אפיק איטי יותר המיועד לפריפריאלים סטנדרטיים.

* **APB1 (Low-Speed APB):** מוגבל בתדר (למשל עד 42MHz ב-F4), מחבר I2C, UART, SPI איטיים, טיימרים בסיסיים.

* **APB2 (High-Speed APB):** עובד בתדר גבוה יותר (עד 84MHz ב-F4), מחבר USART מהיר, SPI מהיר, ADC, EXTI, וטיימרים מתקדמים.

כדי שפריפריאל יעבוד, חובה להפעיל את קלוק האפיק שלו ב-RCC (Reset and Clock Control). ברירת המחדל ב-STM32 היא שהקלוק לכל הפריפריאלים כבוי לחיסכון באנרגיה.

## שכבת הדרייבר ואינטראקציה עם האפליקציה

הארכיטקטורה הרב-שכבתית בנויה כך:

* **Application Layer:** לוגיקת ה-Business, מקבלת החלטות, קוראת ל-API של הדרייבר.

* **Driver Layer (HAL / Bare Metal Driver):** מנהל את הפריפריאל, מקנפג רגיסטרים, מטפל בפסיקות.

* **Hardware Layer:** ה-MCU והרכיבים הפיזיים.

אינטראקציה בין דרייבר לאפליקציה יכולה להתבצע בשתיצורות:

1. **Blocking (Polling):** האפליקציה קוראת לפונקציה וממתינה עד לסיום הפעולה (למשל שידור בייט ב-UART בלולאה).

2. **Non-blocking (Interrupt / DMA Driven):** האפליקציה מפעילה שידור/קליטה ואינה נחסמת. כשהפעולה מסתיימת, הדרייבר מודיע לאפליקציה באמצעות פונקציית Callback.

## מנגנוני פסיקות (MCU Interrupts & EXTI)

* **NVIC (Nested Vectored Interrupt Controller):** המנגנון בתוך ליבת ה-ARM Cortex-M המנהל את כל הפסיקות במערכת, כולל עדיפויות (Priority) וקדימויות (Nesting).

* **EXTI (External Interrupt/Event Controller):** רכיב ב-STM32 המקשר בין פיני ה-GPIO לפסיקות המעבד.

* פינים בעלי אותו מספר (مثلاً PA0, PB0, PC0) ממופים לאותו קו פסיקה (EXTI0). ניתן לבחור רק פורט אחד בו-זמנית עבור קו EXTI ספציפי.

* EXTI מאפשר הגדרת טריגר: עליית מתח (Rising Edge), ירידת מתח (Falling Edge), או שניהם.

* בתוך ה-ISR (Interrupt Service Routine) חובה לנקות את ה-Pending Bit ברגיסטר ה-EXTI, אחרת הפסיקה תופעל בלולאה אינסופית.

## משימת בית וסיכום השיעור

**משימת הבית לשבוע הבא:**

1. לבחור רכיב/פריפריאל תקשורת (למשל חיישן, ממשק UART/SPI/I2C, או דרייבר GPIO).

2. לתכנן את קובץ ה-Header (`.h`) עבור הדרייבר:

* הגדרת Enums ו-Structures לקונפיגורציה ושגיאות.

* הגדרת פונקציות ה-API (`Init`, `DeInit`, `Write`, `Read`, `Control`).

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

4. להעלות את הקוד ל-Branch האישי ב-Git.

בשיעור הבא נמשיך ונבצע Deep Dive לתוך עולם ה-GPIO והפסיקות החיצוניות (EXTI).

שיהיה בהצלחה לכולם, ונתראה בשבוע הבא!

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

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

## הקדמה והצגת הקורס

אני אור פוקס (סולימני). יש לי כ-10 שנים של ניסיון טכני, מתוכן כ-7 שנים בפיתוח תוכנה. עבדתי על Low-Level Embedded Code ב-Linux, ויש לי גם בסיס באלקטרוניקה מהשירות הצבאי ביחידה 8200. יצא לי לעבוד על מספר Network Stacks, כולל TCP/IP לתקשורת לוויינית ו-LTE eNodeB עבור 4G.

ההתמחות העיקרית שלי היא High-Performance Multi-threaded Real-Time ב-C ו-C++. אני עובד לרוב על Linux, אך עבדתי גם על מעבדים מסדרת ARM Cortex-M3 ו-Cortex-M4 בפלטפורמות שונות. הידע שלי כולל Yocto, Kernel ו-Driver Development. הקורס הזה יתמקד בפיתוח דרייברים למעבדי ARM Cortex-M3/M4 עבור רכיבי IoT ותכנות Low-Level.

## סבב הכרות

**אילון אסרף:** נשוי פלוס 3, מירושלים. סיימתי תואר בהנדסת אלקטרוניקה. כיום עובד ב-Mobileye במשרת הנדסאי/סטודנט. השאיפה שלי היא להתקדם לכיוון Chip Design, ASIC או FPGA.

**מרצה:** מעולה. יש אצלכם הרבה עבודת ASIC ו-Logic Design, במיוחד למצלמות ולרכיבי Lidar. הדרייברים שילמדו פה יעזרו בהבנת הממשק בין החומרה לתוכנה.

**סער:** סטודנט שנה אחרונה בהנדסת מכונות, במגמת בקרה ומכטרוניקה. יצא לי להתעסק קצת עם STM32 ב-Windows, ברמת ה-GPIO וה-ADC, אבל לא עברנו על פרוטוקולי תקשורת, וזה נושא שמאוד מעניין אותי.

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

**דן:** מפתח תוכנה, עובד כערך שנה בתחום ה-Embedded והרובוטיקה. רוצה להרחיב את האופקים ולחזור לתעשייה בתחום הזה.

**מרצה:** מעולה. איתנו גם אבי, בעל רקע בהנדסת חשמל ו-RF, ואריה.

## סביבת העבודה והכלים

במהלך הקורס נעבוד עם הכלים הבאים:

1. **STM32CubeIDE:** סביבת הפיתוח הרשמית מבית ST, המבוססת על Eclipse. זוהי הסביבה המומלצת לעבודה עם STM32.

2. **Git Bash:** כלי שורת פקודה לניהול גרסאות ב-Windows.

3. ** STM32F411E-DISCO:** בורד הפיתוח (Discovery Board) שעליו נרצה להריץ ולבחון את הקוד שלנו.

4. **Arduino:** ישמש אותנו לסימולציה של רכיבי Slave/Master בתקשורת.

5. **Logic Analyzer / Oscilloscope:** כלי ניתור לאותות חשמליים ולפרוטוקולי תקשורת (אופציונלי אך מומלץ מאוד).

נשתמש בפקודות Git בסיסיות כמו `git clone`, `git status`, `git fetch`, ו-`git checkout -b` לניהול המשימות והתרגילים.

## חזרה על יסודות Bare-Metal

בקורס הקודם עסקנו ביסודות ה-Bare-Metal:

* **Direct Register Manipulation:** גישה ישירה לאוגרים ללא תיווך של מערכת הפעלה.

* **Memory Architecture:** ניהול ה-Stack, זיכרון ממופה קלט/פלט (Memory-Mapped I/O), וטכניקות אופטימיזציה.

* **Bus Interfaces:** הבנת ארכיטקטורת האוטובוסים AHB ו-APB והגישה לרכיבים היקפיים (Peripherals).

* **ARM Cortex-M Core:** שימוש באוגרים, רמות הרשאה (Privilege levels), ומצבי עבודה.

* **Exception Handling:** טבלאות וקטורים (Vector tables), ניהול תקלות, וקונפיגורציה של רכיב ה-NVIC.

* **Real-Time Design:** הגדרת טיימרים, טיפול בפסיקות (Interrupt handling), וסנכרון.

## מהו דרייבר? (Driver Architecture)

דרייבר הוא שכבת הפשטת תוכנה (Software Abstraction Layer) המקשרת בין קוד האפליקציה לבין הרכיבים ההיקפיים בחומרה (Hardware Peripherals).

### מאפיינים מרכזיים של דרייבר:

* **Hardware Abstraction:** הסתרת פרטי הגישה לאוגרים ברמת ה-Low-Level מקוד האפליקציה.

* **Consistent Interface:** אספקת קריאות פונקציה אחידות (API) עבור החומרה.

* **Error Handling:** החזרת קודי שגיאה וניהול מצבי תקלה.

* **Resource Management:** אתחול (Initialization) ושחרור (Deinitialization) של משאבי החומרה.

* **Performance Optimization:** כתיבת קוד יעיל לגישה מהירה לחומרה.

* **Portability:** אפשרות להעביר את קוד האפליקציה בין פלטפורמות חומרה שונות תוך שינוי מינימלי בדרייבר.

במסגרת הדרייבר נגדיר קובץ Header (`.h`) שיכיל את מבני הנתונים (Structures), ה-Enums והצהרות הפונקציות (Function Prototypes), וקובץ C (`.c`) שיכיל את הממשק והמימוש בפועל מול האוגרים.

## שלבים בפיתוח דרייבר ואינטגרציית חומרה

כשניגשים לפיתוח דרייבר לרכיב חדש, יש לבצע את השלבים הבאים:

1. **למידת ה-Datasheet וה-Reference Manual:** הבנת אופן הפעולה של הרכיב ההיקפי, מיפוי הזיכרון (Memory Map), תדר העבודה, ומצבי ההפעלה.

2. **הגדרת ארכיטקטורה ו-API:** תכנון הפונקציות שהאפליקציה תצטרך לקרוא להן, כגון: `init`, `deinit`, `transmit`, `receive`, `set_mode`, ו-`get_status`.

3. **מימוש הקוד (Implementation):** כתיבת הקוד הפועל מול האוגרים של ה-MCU, הגדרת שעונים (Clock Control באמצעות RCC) וביצוע קונפיגורציה לפינים (GPIO Alternate Functions).

4. **טיפול בפסיקות ו-DMA:** שילוב מנגנוני פסיקות (Interrupts) או גישה ישירה לזיכרון (DMA) במידת הצורך לשם עבודה אסנכרונית.

5. **בדיקות ואימות (Verification):** הברזת אותות ובדיקה באמצעות Logic Analyzer או אוסצילוסקופ על גבי החומרה.

### שיקולי אינטגרציה בחומרה:

* **Voltage Levels:** לוודא התאמת מתחים (למשל 3.3V מול 5V) בין ה-MCU לרכיב.

* **Current Consumption & Power:** הבנת דרישות הזרם ומצבי ה-Power Saving.

* **Bus Interfaces:** חיבור נכון לאוטובוסים הרלוונטיים (AHB, APB1, APB2).

* **Timing Constraints & Latency:** עמידה בזמני התגובה הנדרשים בפרוטוקול.

## השוואה בין שכבת האפליקציה לשכבת הדרייבר ומשימות לבית

שכבת האפליקציה (Application Layer) מתמקדת בלוגיקה העסקית של המוצר (Business Logic), עיבוד הנתונים וממשק המשתמש, בעוד שכבת הדרייבר (Driver Layer) מתמקדת בתקשורת הישירה מול החומרה, אתחול הרכיבים, וניהול הגישה לאוגרים.

**משימה לבית:**

יש לבחור רכיב היקפי (Peripherals) או פרוטוקול תקשורת, לקרוא את ה-Reference Manual הרלוונטי, ולתכנן את קובץ ה-Header (`.h`) עבור הדרייבר שלו, כולל הגדרת מבני הנתונים וחתימות הפונקציות הנדרשות.

נצא להפסקה של 5 דקות ונמשיך לאחר מכן.

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

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

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

אני רואה שלכולכם יש גישה למצגת ואני רואה גם שלא מעט התחברו, כל הכבוד.

אז ברוכים הבאים לקורס, אנחנו עושים את הקורס על STM32, בגלל זה הוא גם נקרא Driver Development on STM32 Microcontrollers או יותר נכון Cortex-M4.

הסבר עליי: אור פוקס. אתם תראו אור סולימני, אור פוקס, זה לא שיניתי את השם מזמן. יש לי 10 שנים ניסיון טכני, 7 שנים מתוכם ב-software development. עבדתי על low-level embedded code ל-Linux. יש גם בסיס של אלקטרוניקה מהצבא, שירתתי ב-108 אם מישהו מכיר. יצא לי לעבוד על כמה network stacks, גם על TCP/IP ל-satellite communication וגם LTE eNodeB שזה 4G ושילוב של שניהם.

ההתמחות העיקרית שלי היא high-performance multi-threaded real-time ב-C ו-C++. אני עובד לרוב על Linux, אבל יצא לי לעבוד ועברתי גם על מעבדים של Cortex-M3 ו-M4 לכמה פלטפורמות שונות.

הידע העיקרי הוא Yocto, kernel ו-driver development. אנחנו ניקח את ה-driver development ואנחנו בעצם נדבר על איך מפתחים דרייברים לרכיבים, למעבדים מסדרת Cortex-M3 ו-M4 של ARM, למכשירי IoT ולדבר על low-level development. זה הידע שלי, אנחנו נדבר קצת על דברים נוספים, כן נעבור על כל מיני תקשורות on-board רגילות. יצא לי לעבוד על הרבה hardware bring-up ו-board-level communication, ואלה הפלטפורמות שאני בעיקר מתמחה בהן.

## סבב היכרות

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

[אלון]: היי, נעים מאוד. קוראים לי אלון עסרף, נשוי פלוס 3, מירושלים. ממש עכשיו סיימתי תואר בהנדסת אלקטרוניקה, וכיום עובד ב-Mobileye במשרת הנדסאי, עדיין משרת סטודנט. הכיוון הוא יותר ל-chip design, ASIC או FPGA. אם זה בחברה אצלנו אז זה ASIC מן הסתם. זהו, בגדול.

[מרצה]: מגניב. יש אצלכם הרבה ASIC ו-logic design, במיוחד למצלמות וללידארים שפיתחו. דרייברים – ראיתי שיש דרייברים ב-Linux ב-Mobileye, פחות על Bare-Metal. אבל אפשר לקחת את הידע הזה ולעשות לו אפליקציה, להפעיל אותו על כל סוגים של דרייברים, גם ל-Windows לא עלינו וגם ל-Linux.

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

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

[מרצה]: מעולה. עידן עשה איתנו את ה-Bare-Metal. שר, ראיתי שגם אתה פתחת מצלמה.

[שר]: כן, אהלן. אני סטודנט שנה אחרונה בהנדסת מכונות. לקחתי מגמה של בקרה ומכטרוניקה, אז יצא לי להתעסק קצת עם STM, אבל ב-Windows, בפלטפורמת PlatformIO. סיימתי... אני מכיר כאילו GPIO ואת ה-Analog-to-Digital, אבל לא עברנו על פרוטוקולי תקשורת וזה כן משהו שמאוד מעניין אותי. וזהו.

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

[דן]: כן, אז אני דן. אני מתעסק בפיתוח תוכנה מ-2014, עברתי ל-embedded ב-2021, ובאתי לקורס הזה כי מדי פעם אני מקבל בעיות עם הדרייברים של ST וצריך לחפור בקוד שלהם ולא להתבלבל שם. אז רציתי להכיר את זה לעומק.

## מבנה הקורס

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

שיעור הבא אנחנו כבר נעשה GPIO deep dive, איך אנחנו מקנפגים GPIO-ים, איך אנחנו עובדים ואופטימיזציות.

שיעורים 3, 4 ו-5 נדבר יותר על תקשורות on-board שהן מאוד נפוצות: I2C או I-square-C, תלוי מאיפה באתם, כל אחד קורא לזה בשם אחר. I2C development, SPI שזה Standard Peripheral Interface, לא נזכור לגמרי את השם, שזה עוד תקשורת מאוד סטנדרטית, UART שזה גם בסיס של כל מיני תקשורות שעליהן אנחנו מתבססים, אז UART יש לנו עליה את ה-RS-ים.

לאחר מכן נדבר על איך אנחנו עובדים עם ה-STM Hardware Abstraction Layer, בעצם השכבה של דרייברים ש-ST מספקים לנו.

ובשיעור לאחר מכן נדבר על Low Power modes, איך אנחנו בעצם עובדים במצבים של Low Power, ככה שאנחנו לא עובדים ב-100% CPU ולא תמיד מזלזלים באנרגיה של המיקרו-קונטרולר.

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

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

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

המטרות הן לקבל את הידע וה-skills כדי לתכנן ולעשות אימפלמנטציה של דרייברים לכל MCU platforms. ה-native שלי בכלל זה Silicon Labs, אבל זה בערך אותם דברים. אז במקום HAL היה להם את ה-Simplicity Studio והדרייברים שלהם. כל חברה בעצם זה אותו דבר. ברגע שיודעים לעבוד עם אחת, אתם יכולים לדעת עם כולן, אם זה TI, Silicon Labs, מה שתרצו.

מיקרו-קונטרולרים, במיוחד אם זה ARM-M, אז אנחנו יכולים לעבוד איתם, כי הרבה מהמיקרו-קונטרולר מוגדר גם על ידי הארכיטקטורה וגם על ידי היכולות של המיקרו-קונטרולר.

ובסוף אני רוצה שתבינו איך אנחנו שולטים במיקרו-קונטרולר, בדרייברים ובכל הפריפריאלים ברמת ה-low-level, איך מקנפגים שעונים, איך אנחנו עושים interrupt handling ו-memory architecture design, בעצם איך אנחנו עובדים עם זיכרונות ואיך אנחנו משתמשים במבני נתונים כדי לשלוט בהם כמו שצריך.

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

אני רואה שאבי סיים ללמוד הנדסת חשמל ומתעסק בתחום ה-RF. RF זה מגניב, יצא לי לעבוד על RF ב-4G וברשתות אנטנה של מכ"ם.

[אלון]: שכחתי לשאול אותך, סביבת העבודה מתאימה למחשבי Mac?

[מרצה]: אני לא רואה סיבה שלא, פשוט בשלב של ההתקנה תתקין את ה-STM ל-Mac. אני חושב שאתה לא צריך Git Bash, במקרה הזה אתה עובד פשוט עם Git שהוא מובנה לך כי זה Unix. אני חושב שבאחד הקורסים היה אחד שעשה את זה, אני לא זוכר אם הוא ויתר או לא, אני לא לגמרי זוכר. אבל אמורה להיות תמיכה.

[אלון]: אוקיי, תודה.

[מרצה]: עוד דברים שנעשה היום: איך אנחנו בוחנים רכיבים שיתאימו ל-MCU. MCU זה Microcontroller Unit. ל-MCU שלנו, איך אנחנו מתכוננים לקראת אינטגרציה, כלומר או אם אנחנו מדברים על bring-up או אינטגרציה כללית של רכיב חדש לתוך המכלול שלנו, ל-device שלנו. נדבר על bus interfaces שאנחנו הולכים לעבוד איתם, ונסיים עם MCU interrupts. אז נתחיל עם ה-manufacturer set interrupt ונסיים עם ה-XTI interrupts שזה ה-interrupts של ST.

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

## סביבת העבודה והכלים

מבחינת הסביבה שאנחנו נעבוד עליה, אנחנו נעבוד על STM32CubeIDE. למה? זה לא הכי נוח לכתוב שם קוד, זה נכון, אבל זו סביבת הפיתוח הכי נוחה, האינטגרציה הכי טובה ל-STM32 והסביבה הכי טובה, אנחנו נראה היום. וזה גם ילמד אותנו את הבסיס של איך לעבוד עם Eclipse-based IDE. אז Eclipse זה איזשהו open source של IDE שכולם משתמשים בו ומוסיפים לו פלאגינים. כל manufacturer מוסיף לו פלאגינים כדי להתאים אותו ל-MCU שלו. אז לנו יש את STM32CubeIDE, לחברות אחרות יש את Simplicity Studio וכולי, אני לא זוכר עוד. לרוב אנחנו לא עובדים עם Eclipse ונילה, אבל היו לי פרויקטים בעבר.

Git Bash – למחשבי Windows, לרוב אין לנו native Git, אז צריך להתקין Git Bash. יש התקנה בסלייד הבא, וה-breakout board. אני עובד עם STM32F411VE Disco. ה-Disco זה Discovery, אבל יש לו גם ארבעה לדים, ככה שזה גם עושה דיסקו. לא משנה, סתם בדיחה.

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

כאשר אנחנו נעשה כל מיני סימולציות, אנחנו ניקח איזשהו Arduino ונעשה לו או slave או master side simulation. יש Arduino Uno, אנחנו נגיע לזה כבר בשיעורים הבאים, לא בשיעור הבא אבל עוד שני שיעורים.

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

התקנה של Git Bash וכמה basic commands:

בגדול, אתם לא צריכים לדעת יותר מדי מהקומנדים האלה חוץ מ-fetch, כי אני כל שיעור מעדכן, וזה כבר אפשר להגיע ישר ל-repository שלי. בסוף המצגת, בגדול, אתם יכולים ליצור לעצמכם branch שלכם ל-assignments שאתם רוצים לשלוח לי. אתם יוצרים branch ואז אתם דוחפים ואני יכול לעבור לכם על ה-assignments ב-GitHub, זה ממש נוח. ואתם יכולים גם לשלוח לי קבצים, זה קצת יהיה פחות נוח, הקומנטים שלי יהיו פחות מובנים, אבל זה גם דרך לעבוד.

אז הפקודות, אם אתם לא מכירים: `git clone` ל-repository עצמו, שפה תחליפו במקום repo_name, אז אני אתן לכם פשוט את השם.

זה השם, אם אתם צריכים, אני אשלח את זה עכשיו בצ'אט של ה-WhatsApp, ובבהמשך תוכלו פשוט להגיע לכאן. אנחנו נעשה איזשהו walk-through עליו. יש גם הסבר על הקורס עצמו, על ה-hardware requirements, על הכל. Tools – אז סקופ או logic analyzer זה אופציונלי, אני מקווה שאני אצליח לגרום לשלי לעבוד ואני אוכל להראות לכם את הכל כמו שצריך. אבל זה לא חובה.

פה כבר יש לנו את ה-topics, בעצם כל מה שאמרנו, את המבנה תיקיות, ואת כל הדברים, איך אנחנו עובדים איתו ואיך אתם יכולים להגיש מטלות. אלה ה-references, המייל שלי, מה שאתם צריכים, יש לכם את הכל פה. אז יש לכם את זה עכשיו ב-WhatsApp. תוכלו לראות ולשאול שאלות. יש גם את הדוקומנטים שעבדתי איתם, הם גם נמצאים כאן. אם אתם לא מבינים מה זה ה-gitkeep, זה פשוט כדי שיהיה אפשר להעלות תיקיות ריקות.

סבבה. זה ה-Git שלנו. אז מבחינתכם, `git fetch` זה כל מה שמניע אתכם, ואם אתם יוצרים לעצמכם branch, אז `git checkout -b` ותתחילו עם השם שלכם ואז השם של ה-branch.

התקנה של STM32Cube, זה אפילו מופיע ב-README של ה-repository, וזה ממש פשוט להתקין, רק אני חושב שצריך איזושהי הרשמה, זה הכל.

שאלות עד לכאן?

[תלמיד]: האמת שבשבילי זה היה חצי סינית כל מה שדיברת עד עכשיו, אבל נראה לי שזה פשוט התקנות אז אני אתמודד עם זה אחר כך.

[תלמיד נוסף]: בשבילי גם כן, אני ככה עוד...

[מרצה]: אוקיי, אז דבר ראשון אתם יכולים לעצור אותי, כדי שלא נגיע למצב שאני מדבר סינית ואתם לא מבינים, אז אתם יכולים לעצור אותי ולהגיד. דבר שני, יש לכם ב-WhatsApp את ה-repository. repository זה המקום שבו נמצא הקוד של הקורס. בעצם פה יש קובץ של README, הקובץ של README יש עליו את כל המידע. מה אנחנו צריכים? קצת בסיס ב-C, הבנה קצת של digital electronics. אני מסביר הכל, שום דבר לא באמת הכרחי, אני לא אכתוב משהו ב-C שהוא לא ברור או שלא תהיה הסבר. ואם כן, שוב, אתם יכולים לעצור אותי.

דרישות – אז זה הלוח שאני עובד איתו. אתם יכולים לבחור כל לוח של STM32. אם אתם רוצים, יש לי רשימה של MCUs שאתם יכולים לעבוד איתם והם יהיו לי הכי נוחים לתמוך, אבל באמת לא קריטי.

Arduino – Arduino זה איזשהו dumbed-down board, שאפשר לעשות איתו... אפשר לכתוב באיזשהו סטודיו ממש פשוט ולכתוב כל מיני בלוקים של דאטה או כל מיני בלוקים של קומנדים במקום ממש ברמת הרגיסטר. טוב, זה לא צריך.

אלה ה-tools: בעצם STM32Cube זה ה-IDE, זו סביבת פיתוח. עוד שנייה אני אפתח אותה אצלי ואתם תוכלו לראות איך זה נראה. Git Bash – אז להתקנה, אחרי שאתם תתקינו, אז תהיה לכם אפשרות לעבוד עם GUI או עם ה-terminal. אם אתם יודעים לעבוד עם ה-GUI, סבבה, אני לא יודע. ואז יפתח לכם ה-terminal. שנייה, אני פשוט עובד עם שני מסכים פעם ראשונה, אז אני עוד לא יודע לגמרי איך זה עובד.

אז זה הקורס, זה של הקורס. אם אתם עושים `git status`, אתם יכולים לראות שיש כל מיני קבצים שהם לא שהם לא committed ל-branch, אבל אם אתם מסתכלים טוב, זה כל מיני קבצים של metadata, אז לא משהו שבאת מעניין אותנו. ואתם יכולים להסתכל שזה לא ה-repository הנכון, אז אני מתנצל. ה-repository שלנו זה drivers development microcontroller. אתם יכולים ממש ללכת לנתיב הנכון, ועכשיו אנחנו ב-main.

פה אפשר לעשות `git status` שוב, `git status`, ואז אנחנו רואים שאנחנו על ה-main ואין שום דבר לדחוף. אם אני דוחף מידע חדש או מכניס דוגמאות חדשות ואתם רוצים לעבוד איתם במהלך הקורס, אז לפני הקורס תעשו `git fetch`. אפשר לעשות גם `--all --prune` כדי שגם יעשה fetch להכל וגם יעיף לכם קבצים שהם untracked ואתם לא צריכים אותם. וגם ינקה את התיקייה של ה-metadata שהיא לא רלוונטית, אבל זה חוסך. אז זו הפקודה, הכי נוח לעשות, ואז הוא הולך ל-remote, שה-remote שלנו זה כאן, ומביא את כל המידע שהתעדכן, כל המידע שאני דחפתי אצלי. ואז אתם יכולים תמיד להיות מעודכנים לשיעור. אז זה ה-Git ככה בשתי מילים.

בנוגע לכלים: אז יש לנו scope ו-logic analyzer, נכון? זה עוד שני מילים בסינית שזרקתי. אז scope זה איזשהו ציוד בדיקה שהוא מדפיס רמות מתח ביחס לזמן. הוא יוצר לנו כל מיני גלים חשמליים יפים כאלה, וזה כל מה שהוא עושה. logic analyzer הוא ספציפי לרמות מתחים של מיקרו-קונטרולרים ספציפיים, אני חושב שיש לו 1.8V, 3.3V ו-5V. המיקרו-קונטרולר שלנו עובד ב-3.3V. אז יש לי איזה מיקרו-קונטרולר סיני שהגיע מ-AliExpress ואני עדיין לא הצלחתי לגרום לו לעבוד, אולי אני אצליח בימים הקרובים ואז אני אוכל להציג לכם. את הדאטה אפשר ממש לקנפג אותו שהוא יראה לנו את המידע שנשלח.

סביבת פיתוח – זה האתר ומשם אפשר להוריד, מכאן מורידים את ה-IDE.

וזה ה-README, זה בעצם הקובץ של ה-repository שמסביר את כל מה שיש ב-repository.

## סקירת תכני הקורס הקודם (Bare-Metal)

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

דיברנו קצת על Bare-Metal Foundations, על עבודה מול device בלי מערכת הפעלה. איך אנחנו בעצם עובדים ישירות על המיקרו-קונטרולר ללא מערכת הפעלה, עבודה עם אינטרפטים בצורה ישירה, עבודה עם באסים, עם הבאסים היותר... נדבר על הבאסים עצמם, וגם בצורה: איך ה-stack עובד מבחינת ה-MCU, ה-call stack, בעצם הקריאה והדחיפה של הפונקציות לתוך ה-stack והפרמטרים עצמם.

דיברנו על הארכיטקטורה של מיקרו-בקרים, היו לנו הרבה מאוד שיעורים על הארכיטקטורה של Cortex-M. הארכיטקטורה של המיקרו-בקר שאני עובד איתו ובכללי של הקורס זה ARM Cortex-M. Cortex-M4, אתם יכולים לבחור כל דבר, רק שימו לב שחלק מהפונקציונליות תהיה קצת שונה. ב-M4 יש לנו floating-point unit, יש לנו עוד כל מיני דברים שאין ב-M3, יש לנו גם קאשינג ועוד הרבה דברים. אז אם אנחנו מדברים על פיצ'רים כאלה, לא כזה פחות רלוונטיים לדרייברים. אם אנחנו מדברים על פיצ'רים כאלה, אז תדעו שזה מגיע מכל מיני מקומות. ויש גם את M7 שזו הארכיטקטורה היותר חזקה של ARM. אז ה-M זה לדעתי Microcontroller או סתם מתאים. אז זו הארכיטקטורה עצמה, יש ארכיטקטורות יותר מתקדמות של ARM שזה ה-A ולמיקרו-מעבדים וכולי וכולי, אבל ה-M היא הבסיסית.

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

לקראת סוף הקורס התחלנו לדבר על multitasking implementations. אם אין לנו מערכת הפעלה, אז אנחנו צריכים לעשות אימפלמנטציה של multitasking: איך אנחנו עושים task scheduling, context switching ו-stack organization, איך אנחנו מחלקים את ה-stack לכמה אזורים, מחלקים לכמה stack-ים.

בסוף, שני דברים אחרונים: דיברנו על real-time design, דיברנו על עבודה עם schedulers, עבודה עם timer configuration ואיך אנחנו יוצרים לעצמנו task scheduler כדי לעבוד בצורה לבד. וגם יצאנו לדבר לא מעט על optimization techniques של הקומפיילר, bit-manipulation, memory access patterns וכל מה שעוזר לתוכנית שלנו להיות קלה ומהירה. אז זה הקורס של ה-Bare-Metal.

למישהו יש שאלות על זה? אתם מוזמנים. אבל יותר מדי על הקונספטים אלה אנחנו לא נעמיק, זה לא רלוונטי לקורס שלנו. שאלות?

[דן]: מה היה היוטיוב הזה?

[מרצה]: אה, מישהו עם איזה קורס על ה-Git בעברית, אתה רוצה להסתכל אחר כך? מגניב. יש לי גם סיכום שאני תמיד שולח, הוא די ישן, אבל אולי אני... אולי אנשים אחרים שלחתי את זה, אני יכול לשלוח לכם גם.

## מהו דרייבר (Driver)?

סבבה. אז מה זה בעצם דרייבר? דרייבר זה בעצם איזושהי שכבת אפסטרקציה שבין ה-application code, שזה הלוגיקה עצמה שאנחנו צריכים לעשות, כמו "תשלח בייט", "תביא לי כתובת" וכו', לבין ה-hardware peripheral. בעצם ה-hardware peripheral, למה זה נקרא peripheral? זו השכבה שהיא הפריפריה של ה-CPU. אז יש לנו את ה-MCU, ה-MCU עצמו מורכב מ-CPU ומעוד חלקים. החלקים האלה הם הפריפריאלים. דוגמה: GPIO. GPIO זה peripheral, General Purpose Input/Output, שזה peripheral ל-CPU, והוא מגיע ממש אל הפינים, אל הפינים של השבב. הפינים האלה, זה מה שיוצא בסוף על ה-GPIO-ים. יכולים להיות גם GPIO-ים לוגיים, ואם דיברנו על ה-RF, אז יכולים להיות GPIO-ים שיגיעו לתוך איזשהו מתנפ ויצרו לנו גלי רדיו. אז בעצם הדרייבר הוא שכבת אפסטרקציה שעושה לנו, נותנת לנו גישה בין האפליקציה, בין שכבת האפליקציה, שזו השכבה שבה קורית הלוגיקה, לבין ה-hardware peripheral, ויוצרת לנו איזשהו אינטרפייס סטנדרטי כדי ליצור אינטראקציה עם החומרה.

אם יצא לכם לעבוד במערכות הפעלה קצת יותר מתקדמות כמו Linux או Windows, אין לנו גישה ישירה לחומרה. אז יש לנו system calls או איזשהו service call שהוא יוצר לנו את הבקשה הזאת מהשכבה של החומרה, ויש הפרדה לגמרי. ב-Bare-Metal או במיקרו-קונטרולרים אין לנו את ההפרדה הזאת, אבל אנחנו עדיין רוצים ליצור איזושהי שכבה סטנדרטית כדי שלא נצטרך כל פעם מחדש לכתוב ישירות לחומרה, להגיד לברגיסטר הזה "תזוז לפה", אז בשביל זה המציאו דרייבר.

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

מה אנחנו מכניסים בתוך דרייבר?

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

- Consistent Interface: אם אנחנו נממש system calls, אז אנחנו עובדים עם system calls בצורה הזאת. אבל במיקרו-קונטרולרים אין לנו את כל המקום ל-overhead הזה, אז אנחנו עובדים עם איזשהו standard API שאנחנו משאירים אותו קבוע לכל ה-hardware implementations. זה בעצם כמו VFS אם אתם מכירים, בעצם הכל נעשה באותה צורה, לא עבודה מול קבצים, אבל הכל נעשה באותה צורה. וככה המפתח יודע לכתוב יותר מהר. זה אחת הסיבות שאנחנו עובדים ככה, כי המפתח יכול לכתוב עם הדרייברים האלה אפליקציות יותר מהירות ויותר חזקות ויותר ברורות, ולא יצטרך כל פעם לנחש מה ה-API אומר.

- Error Handling: מנהלים error codes ו-fault conditions, איך אנחנו יודעים מתי לא הצליחה לנו טרנזקציה וכולי.

- Resource Management: איך אנחנו מאתחלים ו-de-initialize פריפריאלים בצורה טובה מספיק, להתחיל את הפינים בצורה שאנחנו צריכים, ומחזירים את המערכת למצב יציב כמו לפני, כאילו איך אנחנו מנקים את החומרה.

- Performance Optimization: ככה שאנחנו יכולים לעשות buffering, אנחנו יכולים לעשות עוד כל מיני דברים שלא היינו יכולים לעשות אם היינו כותבים ישירות לחומרה, או שכל אחד היה צריך לממש את זה. אז אם אנחנו מממשים דברים בתוך שכבה שמגינה על האפליקציה מכל הטורדנות והקושי של לעבוד מול החומרה, אז אנחנו יכולים גם לעשות caching, בופרים וכו'.

- Portability: כאשר עובדים עם דרייברים, אנחנו לא תמיד עובדים עם אותו MCU, לפעמים יש end of life. אז אנחנו כותבים קוד שיהיה פורטבילי, ואז אנחנו יכולים לשנות כמה defines ואנחנו יכולים לקחת את הקוד הזה ולהריץ אותו במקום אחר, או על MCU מאותה משפחה או מ-manufacturer אחר.

## שלבים ליצירת דרייבר ואינטרפייס

מה השלבים שאנחנו עושים כאשר אנחנו ניגשים ליצירה של דרייבר חדש?

1. Hardware Analysis:

- ללמוד את ה-peripheral datasheet וה-reference manual. זה לא רק אומר ללמוד את ה-datasheet של הרכיב שאיליו אנחנו רוצים להתחבר, אלא ללכת ל-MCU שלנו וללמוד את ה-datasheet וה-reference manual שלו.

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

- להבין את ה-timing requirements וה-constraints, אם יש לנו התנגשויות.

- להתחיל למפות את ה-pin assignment וה-alternate function של כל אחד.

2. Define Driver Architecture:

- יצירת הדר פייל (Header file) עם ה-function prototypes. לתכנן את ה-API שהדרייבר עובד איתו.

- לתכנן את ה-data structures שנרצה לעבוד ל-configuration. אם ב-C++ זה class, ב-C זה structure. אם נרצה לעבוד עם בופרים דינמיים, נוסיף circular buffers.

- ליצור error codes ו-return types שאנחנו מחזירים מכל אחד מהפונקציות.

- לתכנן את ה-initialization וה-configuration sequences.

דוגמה ל-API של דרייבר תקשורת (למשל RS-485):

הקובץ הדר (Header) הוא מה שיחשף לכל user שישתמש ב-include הזה. הפונקציות שנחשוף הן:

- `init`: פונקציה שמאתחלת ומחזירה את ה-struct של הקונפיגורציה.

- `deinit`: פונקציה שמבטלת את האתחול (destractor).

- `transmit`: שליחת מידע.

- `receive`: קבלת מידע.

- `set_mode`: קביעת המוד (receive או transmit) היות ו-RS-485 זו תקשורת half-duplex (לא יכולה לשלוח ולקבל בו-זמנית).

- `is_busy`: פונקציה שמחזירה האם ה-RS-485 עמוס כרגע.

הגדרת enums של סטאטוסים ומודים, ו-structs של קונפיגורציה והנדל.

פקודות Git לעבודה עם הקורס:

כשאתם רוצים לעדכן את הקוד אצלכם, הפקודה הכי נוחה היא `git fetch`.

אפשר גם להריץ `git fetch --all --prune` כדי לקבל את כל העדכונים מכל ה-branches וגם לנקות קבצים ישנים ו-untracked.

זה הולך ל-remote ב-GitHub ומביא את כל המידע שעדכנתי, כך שתוכלו תמיד להיות מעודכנים מול החומר של השיעור.

בתוך ה-repository תמצאו את המצגות, המטלות (assignments), קבצי הקוד והתיעוד.

כל הכלים הטכניים, הדרישות לחומרה והוראות ההתקנה מפורטים ב-README.

## בחירת רכיבים ואינטגרציה ל-MCU

חלק מרכזי מפיתוח דרייברים הוא לדעת לבחור רכיבים ולבצע להם אינטגרציה מול ה-MCU (Microcontroller Unit). להלן השיקולים המרכזיים:

1. רמות מתח (Voltage Levels):

- יש לוודא התאמה ברמות המתח בין ה-MCU לרכיב (למשל 3.3V מול 5V או 1.8V).

- אי-התאמה עלולה לגרום לשריפת פינים של GPIO או לכך שאותיות לוגיים (0 ו-1) לא יזוהו כראוי.

2. צריכת זרם (Current Consumption):

- יש לוודא שהלוח או המייצב של ה-MCU מסוגלים לספק את הזרם הנדרש לרכיב.

- במערכות Low-Power, יש לתכנן תקציב אנרגיה ולכבות רכיבים כשאינם בשימוש.

3. בחירת ממשק/אפיק תקשורת (Interface/Bus):

- I2C: אפיק סטנדרטי, חסכוני בפינים (2 קווים), מתאים לחיבור מרובה רכיבים.

- SPI: אפיק מהיר מאוד, דורש יותר פינים (לפחות 4 קווים + Select לכל רכיב).

- UART: תקשורת סריאלית נקודה-לנקודה, פשוטה אך מוגבלת במספר המכשירים.

4. כמות פינים ופונקציות אלטרנטיביות (Pin Count & Alternate Functions):

- לכל פין ב-MCU יש מספר פונקציות אלטרנטיביות (Alternate Functions).

- יש לוודא שאין התנגשויות (conflicts) בין רכיבים שונים שמנסים להשתמש באותם פינים או משאבים פנימיים.

5. תזמון וזמני תגובה (Timing & Latency):

- זמן העלייה של הרכיב (Start-up / Wake-up time).

- קצב העברת הנתונים באפיק וזמן התגובה לפסיקות (Interrupt Latency).

6. תיעוד ותמיכה (Documentation & Community Support):

- זמינות Datasheet מפורט וגיליון שגיאות חומרה (Errata sheet).

- קיומן של ספריות ייחוס או קהילת מפתחים.

## ארכיטקטורת האפיקים (Busses) ב-STM32

כדי לעבוד נכון עם פריפריאלים ב-STM32, חשוב להבין את ארכיטקטורת הבאסים הפנימית של ה-MCU:

1. אפיק AHB (Advanced High-Performance Bus):

- אפיק מהיר במיוחד המחבר בין ה-CPU, ה-SRAM, ה-Flash וה-DMA לרכיבים בעלי דרישות רוחב פס גבוהות (כמו GPIO-ים מהירים).

- במיקרו-בקרים מסדרת STM32F4 קיימים אפיקי AHB1 ו-AHB2.

2. אפיקי APB (Advanced Peripheral Bus):

- אפיקים אטיים יותר המחוברים באמצעות גשרים (Bridges) לאפיק ה-AHB העיקרי.

- APB1 (Low-speed): מיועד לפריפריאלים באטיות נמוכה/בינונית כגון I2C, UART, טיימרים בסיסיים וכו'.

- APB2 (High-speed): מיועד לפריפריאלים מהירים יותר כגון SPI, USART, ADC וטיימרים מתקדמים.

3. אפשור שעונים ב-RCC (Reset and Clock Control):

- כחלק מחיסכון באנרגיה, השעון (Clock) של כל פריפריאל מנותק ברירת מחדל.

- **כלל ברזל ב-STM32:** לפני שניגשים לרגיסטר של פריפריאל כלשהו (GPIO, SPI, I2C וכו'), חובה לאפשר את השעון של הבאס המתאים לו ברגיסטר ה-RCC! ללא אפשור השעון, קריאה או כתיבה לרגיסטר תיכשל או תגרום ל-Fault.

## מטלת הבית והמשך

לסיכום השיעור, עברו על מטלה 2 (Assignment 2) ב-repository:

- בחרו תקשורת או רכיב חומרה כלשהו.

- תכננו עבורו את קובץ ה-Header וה-API (פונקציות אתחול, שליחה, קבלה, בדיקת סטטוס).

- הגדירו את המבנים (structs) וה-enums הנדרשים.

- כתבו מסמך תכנון קצר שמסביר את הבחירות הארכיטקטוניות שלכם.

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

שאלות נוספות? אם אין, נצא להפסקה ונתראה בשיעור הבא.

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

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

## מבוא לקורס והצגת המרצה

ברוכים הבאים לקורס. אנחנו עושים את הקורס על STM32, בגלל זה הוא גם נקרא Driver Development on STM32 Microcontrollers.

קצת הסבר עליי: אור פוקס. יש לי 10 שנים של ניסיון בתחום טכני, 7 שנים מתוכן ב-software development. עבדתי על low-level embedded code ל-Linux. יש לי גם בסיס של אלקטרוניקה מהצבא, שירתתי ב-108 אם מישהו מכיר. יצא לי לעבוד על כמה network stacks, גם על TCP/IP ל-satellite communication וגם LTE eNodeB שזה 4G.

ההתמחות העיקרית שלי היא high-performance multi-threaded real-time ב-C ו-C++. אני עובד לרוב על Linux, אבל יצא לי לעבוד ועברתי גם על מעבדים של Cortex-M3 ו-Cortex-M4 לכמה פלטפורמות שונות.

הידע העיקרי הוא Yocto, kernel ו-driver development. אנחנו ניקח את ה-driver development ונדבר על איך מפתחים דרייברים למעבדים מסדרת Cortex-M3 ו-Cortex-M4 של ARM למכשירי IoT, ונדבר על low-level development. אנחנו נסקור תקשורות on-board רגילות, הרבה hardware bring-up ו-board-level communication, ואלה הפלטפורמות שאני בעיקר מתמחה בהן.

## היכרות עם המשתתפים

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

**אילון:** היי, נעים מאוד. קוראים לי אילון אסרף, נשוי פלוס 3, מירושלים. ממש עכשיו סיימתי תואר בהנדסת אלקטרוניקה. עבדתי בעבר ואני עובד כיום ב-Mobileye במשרת הנדסאי, עדיין במשרת סטודנט. בעיקרון הכיוון הוא יותר ל-chip design, ASIC או FPGA. אם זה בחברה אצלנו אז זה ASIC מן הסתם. זהו בגדול.

**מרצה:** מגניב. כן, יש אצלכם הרבה ASIC ו-logical design, במיוחד למצלמות ול-LiDAR-ים שנסגרו. אז כן, דרייברים, אני יודע שיש דרייברים ב-Linux ב-Mobileye פחות על bare-metal, אבל אפשר לקחת את הידע הזה ולעשות לו אפליקציה, להפעיל אותו על כל סוגים של דרייברים, גם ל-Windows וגם ל-Linux.

Next. עידו, ראיתי שפתחת מצלמה, תרגיש חופשי.

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

**מרצה:** מעולה, עידו עשה איתנו את ה-bare-metal. סער, ראיתי שגם אתה פתחת מצלמה.

**סער:** אהלן, אז אני סטודנט שנה אחרונה בהנדסת מכונות. לקחתי מגמה של בקרה ומכטרוניקה, אז כן יצא לי להתעסק קצת עם STM, אבל ב-Windows, בפלטפורמת I/O. אני מכיר כאילו GPIO ו-analog to digital, אבל לא עברנו על פרוטוקולי תקשורת וזה כן משהו שמאוד מעניין אותי.

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

יש לנו את דן ואת אריה ואבי. אריה בלי מיקרופון, אז דן תתחיל אתה ואז אבי.

**דן:** כן, אז אני דן, אני מתעסק בפיתוח תוכנה מ-2014. עברתי ל-embedded ב-2021. ובאתי לקורס הזה כי מדי פעם אני מקבל בעיות עם הדרייברים של ST, וצריך לחפור בקוד שלהם, אז הייתי רוצה להכיר את זה לעומק.

**מרצה:** יפה. אבי?

אוקיי, אבי אם יצטרך לפתוח את המיקרופון אז הוא יהיה איתנו, אם לא פשוט יוכל להשלים את זה אחר כך.

## סקירת תוכנית הלימודים והסילבוס

אז מה נעשה בעצם בקורס? זרקתי לכם פה ושם, אז היום קצת נעשה introduction לקורס foundation, מה זה בעצם דרייברים ואיך אנחנו מפתחים אותם. שיעור הבא אנחנו כבר נעשה GPIO dive deep, איך אנחנו מקנפגים GPIO-ים, איך אנחנו שולטים ואופטימיזציות.

שיעורים 3, 4 ו-5, אז אנחנו נדבר יותר על תקשורות on-board שהן מאוד נפוצות: I2C (או I2C development), SPI שזה standard peripheral interface, שזאת עוד תקשורת מאוד סטנדרטית, UART שזה גם בסיס של כל מיני תקשורות שעליהן אנחנו מתבססים, אז UART יש לנו עליה את ה-RS-ים.

לאחר מכן נדבר על איך אנחנו עובדים עם ה-STM Hardware Abstraction Layer, בעצם השכבה של דרייברים ש-ST מספקים לנו.

ובשיעור לאחר מכן נדבר על low power modes, איך אנחנו בעצם עובדים במצבים של low power, ככה שאנחנו לא עובדים ב-100% CPU ולא תמיד מזלזלים את האנרגיה של המיקרו-קונטרולר.

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

## מתודולוגיה ומטרות הקורס

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

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

אז המטרות זה בעצם לקבל את הידע ואת ה-skills כדי לתכנן ולעשות אימפלמנטציה של דרייברים לכל ה-MCU platforms. אני יכול להגיד לכם שה-native שלי בכלל זה Silicon Labs, אוקיי? אבל זה בערך אותם דברים. אז במקום HAL, אז היה להם את ה-Simplicity Studio ואת הדרייברים שלהם. כל חברה בעצם זה אותו דבר. ברגע שיודעים לעבוד עם אחת, אתם יכולים לדעת עם כולן. אז אם זה TI, Silicon Labs, whatever.

מיקרו-קונטרולרים, במיוחד אם זה ARM M, אז אנחנו יכולים לעבוד איתם, כי הרבה מהמיקרו-קונטרולר מוגדר גם על ידי הארכיטקטורה וגם על ידי היכולות של המיקרו-קונטרולר.

ובסוף אני רוצה שתבינו איך אנחנו שולטים במיקרו-קונטרולר, בדרייברים ובכל הפריפריאלים ברמת ה-low-level, איך מקנפגים שעונים, איך אנחנו עושים interrupt handling ו-memory architecture design, בעצם איך אנחנו עובדים עם זיכרונות ואיך אנחנו בעצם משתמשים במבני נתונים כדי לשלוט בהם כמו שצריך.

## סביבת העבודה והכלים الנדרשים

אז על מה אנחנו נעבור היום? היום אנחנו נעשה את... נעשה איזשהו recap של הקורס הקודם, גם כדי שמי שלא היה בקורס ידע מה למדנו שם וידע מה... על מה אנחנו מדברים כאשר אנחנו זורקים מושגים לאוויר.

מי שכן היה, אז זה תמיד חזרה טובה. נדבר על מה זה דרייברים, מה השלבים שאחנו עושים כדי בעצם לפתח דרייבר, ואיך אנחנו כותבים לו interface, ונעשה איזשהו driver interface example. נעשה את זה בכוונה לדרייב... לתקשורת שאנחנו לא הולכים לעשות לה אימפלמנטציה בשיעור.

אני רואה ש... סליחה, אני רואה שקפץ פה... אני רואה שאבי סיים ללמוד הנדסת חשמל ומתעסק בתחום RF. RF זה מגניב, יצא לי לעבוד על RF ב-4G ובאנטנות מכ"ם.

**אילון:** סליחה, שכחתי לשאול אותך, סביבת העבודה מתאימה למחשבי Mac?

**מרצה:** אני לא רואה סיבה שלא, אבל פשוט בשלב של ההתקנה תתקין את ה-STM ל-Mac. אני חושב שאתה לא צריך Git Bash, במקרה הזה אתה יכול לעבוד פשוט עם Git שהוא מובנה לך כי זה Unix. אני חושב שבאחד הקורסים היה אחד שעשה את זה, אני לא זוכר. לא זוכר אם הוא ויתר או שלא, אני לא לגמרי זוכר. אבל זה אמור להיות... אמורה להיות תמיכה.

אז עוד דברים שנעשה היום: איך אנחנו בוחרים רכיבים שיתאימו ל-MCU. MCU זה Microcontroller Unit. ל-MCU שלנו, איך אנחנו מתכוננים לקראת אינטגרציה, כלומר או אם אנחנו מדברים על bring-up, או אינטגרציה כללית של רכיב חדש ל-device שלנו. נדבר על bus interfaces שאנחנו הולכים לעבוד איתם, ונסים עם MCU interrupts. אז נתחיל עם המניפקטורר sets interrupts, ונסים עם ה-EXTI interrupts, שזה ה-interrupts של ST.

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

מבחינת הסביבה שאנחנו נעבוד עליה, אנחנו נעבוד על STM32Cube. למה? זה לא הכי נוח לכתוב שם קוד, זה נכון, אבל זו סביבת פיתוח הכי נוחה... האבסטרקציה הכי טובה ל-STM32 והסביבה הכי טובה, אנחנו נראה היום. וזה גם ילמד אותנו את הבסיס של איך לעבוד עם Eclipse-based IDE. אז Eclipse זה איזשהו open source של IDE שכולם משתמשים בו ומוסיפים לו פלאגינים. כל manufacturer מוסיף לו פלאגינים כדי להתאים אותו ל-MCU שלו. אז לנו יש את STM32Cube32, או STM32CubeIDE. לחברות אחרות יש את Simplicity Studio וכולי, אני לא זוכר עוד. לרוב אנחנו לא עובדים עם Eclipse vanilla, אבל לרוב לא נעבוד עם Eclipse.

Git Bash: למחשבי Windows לרוב כאילו אין לנו native Git, אז צריך להתקין Git Bash. יש התקנה בסלייד הבא.

וה-breakout board. אני עובד עם STM32F411RE Disco. ה-Disco זה Discovery, אבל יש לו גם 4 לדים, ככה שזה גם עושה דיסקו. לא משנה, סתם בדיחה. אז בעצם הקורס הוא קורס בעצם הוא יהיה ספציפית לבורד הזה. אתם יכולים לעשות אותו על כל בורד, רק תעשו התאמות. אם אני עושה reference ל-reference manual ספציפי ויש לכם בורד אחר, תעשו אותו עם זה. אם אין לכם בורד, אתם יכולים לדבר איתי, יש אפשרות לקנות מ-ST ישירות, זה מגיע ממש מהר במשלוח יחסית לא יקר. בכללי הבורד הזה לא יקר.

כאשר אנחנו נעשה כל מיני סימולציות, אנחנו ניקח איזשהו Arduino ונעשה לו... נעשה לו או slave או master side simulation. יש Arduino Uno, אנחנו נגיע לזה כבר בשיעורים הבאים. לא בשיעור הבא, אבל עוד שני שיעורים.

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

התקנה של Git Bash וכמה basic commands. בגדול אתם לא צריכים... בגדול אתם לא צריכים לדעת יותר מדי מהפקודות האלה חוץ מ-fetch, כי אני כל... כי אני כל שיעור מעדכן, וזה כבר... פה כבר אפשר להגיע ישר ל-repository שלי. בסוף המצגת... בגדול אתם יכולים ליצור לעצמכם branch שלכם ל-assignments שאתם רוצים לשלוח לי, אתם יוצרים branch ואז אתם דוחפים ואני יכול לעבור לכם על ה-assignments ב-GitHub, זה ממש נוח. ואתם יכולים גם לשלוח לי קבצים, זה קצת יהיה פחות נוח. ה-comments שלי יהיו פחות מובנים או משהו כזה, אבל זה גם דרך לעבוד. אז הפקודות, אם אתם לא מכירים, אז `git clone` ל-repository עצמו, שפה תחליפו את המקום של ה-repo name, אז אני אתן לכם פשוט את השם.

## עבודה עם מאגר הקוד (Git Repository)

זה השם, אם אתם צריכים אני אשלח את זה עכשיו בצ'אט של ה-WhatsApp, ובהמשך תכלו פשוט להגיע לכאן. אנחנו נעשה איזשהו walk-through עליו. יש גם הסבר על הקורס עצמו, על ה-hardware requirements, על הכל, tools, אז scope או logic analyzer זה אופציונלי. אני מקווה שאני אצליח לגרום לשלי לעבוד ואני אוכל להראות לכם את הכל כמו שצריך וזה עוזר, אבל זה לא חובה.

פה כבר יש לנו את ה-topics, בעצם כל מה שאמרנו. את המבנה תיקיות, את כל הדברים, איך אנחנו עובדים איתו ואיך אתם יכולים להגיש מטלות. אלה ה-references, המייל שלי, מה שאתם צריכים, יש לכם את הכל פה. אז יש לכם את זה עכשיו ב-WhatsApp, אתם תוכלו לראות, תוכלו לשאול שאלות, ויש גם את ה-Doc שלי שעבדתי איתם, הם גם נמצאים כאן. אם אתם לא מבינים מה זה ה-gitkeep, זה פשוט כדי שיהיה אפשר להעלות תיקיות ריקות.

סבבה, זה ה-Git שלנו, אוקיי? אז מבחינתכם `git fetch` זה כל מה שמעניין אתכם. ואם אתם יוצרים לעצמכם branch, אז `git checkout -b`, תתחילו עם השם שלכם ואז השם של ה-branch.

אז installation ל-STM32Cube, זה אפילו מופיע ב-README של ה-repository, וזה ממש פשוט להתקין, רק אני חושב שצריך איזושהי הרשמה, זה הכל. שאלות עד כה?

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

**עידו:** בשבילי האמת גם, אני ככה עוד עיקש.

**מרצה:** אוקיי. דבר ראשון, אתם יכולים לעצור אותי כדי שלא נגיע למצב שאני מדבר סינית ואתם לא מבינים, אז אתם יכולים לעצור אותי ולהגיד. דבר שני, יש לכם ב-WhatsApp את ה-repository. repository זה המקום שבו נמצא הקוד של הקורס, אוקיי?

בעצם פה יש קובץ של README, הקובץ של README יש עליו את כל המידע, אוקיי? מה אנחנו צריכים: קצת בסיס ב-C, הבנה קצת של digital electronics. אני מסביר הכל, שום דבר לא באמת הכרחי, אני לא אכתוב משהו ב-C שהוא לא ברור או שלא תהיה מספיק הסברה. ואם כן, שוב, אתם יכולים לעצור אותי.

הדרישות: אז זה הבורד שאני עובד איתו, אוקיי? אתם יכולים לבחור כל בורד של STM32, אם אתם רוצים יש לי רשימה של MCU-ים שאתם יכולים לעבוד איתם והם יהיו לי הכי נוחים לתמוך, אבל באמת לא קריטי, סבבה? Arduino: Arduino זה איזשהו dumbed down board שאפשר לעשות איתו... אפשר לכתוב באיזשהו סטודיו ממש פשוט ולכתוב כל מיני בלוקים של data, או כל מיני בלוקים של commands במקום ממש ברמת הריגסטר. טוב, זה לא צריך.

אלה ה-tooling: בעצם STM32Cube זה ה-IDE, סביבת פיתוח, עוד שנייה אני אפתח אותה אצלי ואתם תוכלו לראות איך זה נראה. Git Bash: אז למחשבי Windows לרוב כאילו אין לנו native Git, אז צריך להתקין Git Bash. יש התקנה בסלייד הבא, וה-breakout board, אוקיי?

אני עובד עם... אני אראה לכם אותו... עם STM32F411RE Disco. ה-Disco זה Discovery, אבל יש לו גם 4 לדים ככה שזה גם עושה דיסקו. לא משנה, סליחה על הבדיחה. אז בעצם הקורס הוא... הקורס בעצם הוא יהיה ספציפית לבורד הזה. אתם יכולים לעשות אותו על כל בורד, רק תעשו התאמות. אם אני עושה reference ל-reference manual ספציפי ויש לכם בורד אחר, תעשו אותו עם זה. אם אין לכם בורד, אתם יכולים לדבר איתי, יש אפשרות לקנות מ-ST ישירות, זה מגיע ממש מהר במשלוח יחסית לא יקר. בכללי הבורד הזה לא יקר.

כאשר אנחנו נעשה כל מיני סימולציות, אנחנו ניקח איזשהו Arduino ונעשה לו... נעשה לו או slave או master side simulation. יש Arduino Uno, אנחנו נגיע לזה בשיעורים הבאים. לא בשיעור הבא, אבל עוד שני שיעורים.

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

התקנה של Git Bash וכמה basic commands: בגדול אתם לא צריכים לדעת יותר מדי מהפקודות האלה חוץ מ-fetch, כי אני כל שיעור מעדכן, וזה כבר... פה כבר אפשר להגיע ישר ל-repository שלי.

בסוף המצגת... בגדול אתם יכולים ליצור לעצמכם branch שלכם ל-assignments שאתם רוצים לשלוח לי, אתם יוצרים branch ואז אתם דוחפים ואני יכול לעבור לכם על ה-assignments ב-GitHub, זה ממש נוח. ואתם יכולים גם לשלוח לי קבצים, זה קצת יהיה פחות נוח, ה-comments שלי יהיו פחות מובנים, אבל זה גם דרך לעבוד. אז הפקודות, אם אתם לא מכירים: `git clone` ל-repository עצמו, שפה תחליפו את המקום של ה-repo name.

## חזרה על מושגי יסוד מ-Bare-Metal

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

אז דיברנו קצת על bare-metal foundation, על עבודה מול device בלי מערכת הפעלה. איך אנחנו בעצם עובדים ישירות על המיקרו-קונטרולר ללא מערכת הפעלה, ככה אנחנו לא... איך עבודה עם אינטראפטים בצורה ישירה, עבודה עם באסים, ואיך ה-stack עובד מבחינת ה-MCU, ה-call stack, בעצם הקריאה והדחיפה של הפונקציות לתוך ה-stack והפרמטרים עצמם.

דיברנו על הארכיטקטורה של מיקרו-בקרים, הייתה לנו הרבה מאוד שיעורים על ארכיטקטורה של Cortex-M. הארכיטקטורה של המיקרו-בקר שאני עובד איתו ובכללי של הקורס זה ARM Cortex-M, אוקיי? Cortex-M משהו, אז אני עובד עם Cortex-M4, אתם יכולים לבחור כל דבר, רק שימו לב שחלק מהפונקציונליות יהיו קצת שונות, אוקיי? ב-M4 יש לנו floating point unit, יש לנו עוד כל מיני דברים שאין ב-M3, יש לנו גם קאש ועוד הרבה דברים. אז אם אנחנו מדברים על פיצ'רים כאלה, אלה לא כזה פחות רלוונטיים לדרייברים, אוקיי? אם אנחנו מדברים על פיצ'רים כאלה, אז תדעו שזה כאילו מגיע מכל מיני מקומות. ויש גם את M7 שזה הארכיטקטורה היותר חזקה של ARM, אז ה-M זה לדעתי micro-controller או סתם מתאים, אז זה הארכיטקטורה עצמה. יש ארכיטקטורות יותר מתקדמות של ARM שזה ה-A ולמיקרו-מעבדים וכולי וכולי, אבל ה-M היא הבסיסית.

לאחר מכן דיברנו על exception handling. Exception זה בעצם פעולה אסינכרונית שעושה לנו המעבד ומקפיצה אותנו לתוך... אנחנו נדבר על זה גם היום קצת... ומקפיצה אותנו לתוך קוד ספציפי כדי שנוכל להריץ אותו. אז זה exception, ובתוך exception יש interrupt. מה זה interrupt? זה בעצם חתיכת קוד שרצה גם בצורה אסינכרונית לפי אירועים שהמעבד יודע לאתר. נדבר על זה בעיקר היום.

לקראת סוף הקורס התחלנו לדבר על multi-tasking implementations אם אין לנו מערכת הפעלה, אז אנחנו צריכים לעשות אימפלמנטציה של multi-tasking: איך אנחנו עושים task scheduling, context switching ו-stack organization, איך אנחנו מחלקים את ה-stack לכמה אזורים.

ובסוף, שני דברים אחרונים: דיברנו על real-time design, דיברנו על עבודה עם סקדולרים, עבודה עם timer configuration ואיך אנחנו יוצרים לעצמנו task scheduler כדי לעבוד זה לבד. וגם יצא לנו לדבר לא מעט על optimization techniques של הקומפיילר, bit manipulation, memory access pattern וכל מה שעוזר לתוכנית שלנו להיות קלה ומהירה. אז זה הקורס של ה-bare-metal. למישהו יש שאלות על זה? אתם מוזמנים, אבל יותר מדי על הקונספטים האלה אנחנו לא נעמיק, זה לא רלוונטי לקורס שלנו. שאלות?

## מהו דרייבר (Driver)?

עוד דברים שנעשה היום: איך אנחנו בוחרים רכיבים שיתאימו ל-MCU. MCU זה Microcontroller Unit. ל-MCU שלנו, איך אנחנו מתכוננים לקראת אינטגרציה, כלומר או אם אנחנו מדברים על bring-up, או אינטגרציה כללית של רכיב חדש ל-device שלנו. נדבר על bus interfaces שאנחנו הולכים לעבוד איתם, ונסים עם MCU interrupts. אז נתחיל עם המניפקטורר sets interrupts, ונסים עם ה-EXTI interrupts, שזה ה-interrupts של ST.

אז מה זה בעצם דרייבר? דרייבר זה איזושהי שכבת אבסטרקציה שבין ה-application code (הלוגיקה עצמה שאנחנו צריכים לעשות, כמו "תשלח בייט", "תביא לי כתובת") לבין ה-hardware peripheral.

למה זה נקרא פריפריאל? זו השכבה שהיא הפריפריה של ה-CPU. ה-MCU מורכב מ-CPU ומעוד חלקים, החלקים האלה הם הפריפריאלים, כמו ה-GPIO (General Purpose Input Output) שהם הפריפריאל ל-CPU, והם מגיעים ממש אל הפינים של ה-צ'יפ. הפינים האלה מתחברים בסופו של דבר ל-GPIO-ים, הם יכולים להיות לוגיים, או להגיע לתוך מתנור וליצור גלי רדיו.

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

אם יצא לכם לעבוד במערכות הפעלה מתקדמות כמו Linux או Windows, אין לנו גישה ישירה לחומרה, יש לנו system call או service call שיוצר לנו את הבקשה הזו מהחומרה ויש הפרדה לגמרי. ב-bare-metal אין לנו את ההפרדה הזאת, אבל אנחנו עדיין רוצים ליצור איזושהי שכבה סטנדרטית ואבסטרקטית כדי שלא נצטרך כל פעם מחדש לכתוב ישירות לחומרה ולהגיד לריגסטר "תזוז לפה". בשביל זה המציאו דרייבר.

דרייבר, יש לו קצת abuse בארץ. יש דרייבר שזה הצורה לעבוד עם תקשורת, ויש דרייבר שזה הצורה לעבוד עם רכיב. מבחינתנו שניהם נקראים דרייבר.

מה אנחנו מכניסים בתוך דרייבר?

- Hardware abstraction: גישה ישירה לריגסטרים במקום שנעשה את זה מתוך האפליקציה. יש לנו ספרייה או interface/API שממנו האפליקציה יכולה לגשת אליו וככה היא משתמשת בחומרה.

- Interface קונסיסטנטי: אם אנחנו נממש system calls, אנחנו עובדים בצורה הזאת.

- Error handling: איך אנחנו מנהלים error codes ו-fault conditions, איך אנחנו יודעים מתי לא הצליחה לנו טרנזקציה.

- Resource management: איך אנחנו מאתחלים ומסיימים את אתחול הפריפריאלים בצורה טובה.

- Performance optimization: בתוך שכבת ה-דרייברים אנחנו עושים אופטימיזציה, עושים buffering, ועוד דברים שלא היינו יכולים לעשות אם היינו כותבים ישירות לחומרה.

- Portability: כותבים קוד שיהיה פורטבילי, ואז אפשר לשנות כמה define-ים ולעבוד על MCU מממשפחה אחרת או של manufacturer אחר.

## שלבים ליצירת Driver Interface

מה השלבים שאנחנו עושים כאשר אנחנו ניגשים ליצירה של דרייבר חדש?

1. ללמוד את ה-peripheral datasheet וה-reference manual. זה לא רק ללמוד את ה-datasheet של הרכיב שאנחנו רוצים להתחבר אליו, אלא ללכת ל-MCU שלנו וללמוד את ה-datasheet וה-reference manual שלו.

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

3. לאפיין מה הצריכים שלנו מבחינת הריגסטרים שאנחנו רוצים לעבוד איתם בתוך ה-reference manual.

4. Timing requirements ו-constraints.

5. להתחיל למפות את ה-pin assignment וה-alternate functions של כל אחד.

לדוגמה, נסתכל על ה-EXTI0 של PA0 ונבין למה נרצה לשים עליו את הפונקציה עם ה-priority הגבוה ביותר שלו, כי PA0 או PB0, לכל האינדקס 0 יש אינדקס 0 ב-interrupt-ים.

ואז אנחנו רוצים לבוא לעבוד עם ה-driver architecture: להתחיל ביצירה של header file, לתכנן את ה-API שהדרייבר עובד איתו.

אם אנחנו עובדים ב-C++ אז class, אם ב-C אז structure. אם רוצים לעבוד בצורה דינמית, לצרף circular buffers. לייצר error codes ו-return types שאנחנו מחזירים מכל אחד מה-API, ולתכנן את האתחול וה-configuration sequences.

דוגמה ל-interface (כמו RS-485):

ה-header file הזה מציג את מה שיחשף לכל user שישתמש ב-include הזה:

פונקציות כמו `init`, `de-init`, `transmit`, `receive`, `set_mode`, ופונקציה לבדיקת סטטוס.

אנחנו נרצה לתכנן את ה-API הזה. עבודה עם function pointers מוסיפה לנו גמישות ונוחות, ופחות נוחה ל-debug.

באתחול (init) עושים אתחול של הפריפריאל, אתחול של החומרה ואתחול של התוכנה (הקצאת זיכרון אם צריך ב-C עם `malloc`).

ב-de-init עושים את הביטול.

ב-transmit ו-receive עושים את השליחה והקבלה.

ב-handling של אינטראפטים, מבטיחים עבודה Thread-safe (למשל בעזרת סמפורים ב-FreeRTOS או עבודה אטומית).

## ארכיטקטורת תוכנית וחלוקה לשכבות

כאשר אנחנו עובדים, אנחנו עושים הפרדה לשתי שכבות עיקריות: שכבת ה-drivers ושכבת ה-application.

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

שכבת האפליקציה היא השכבה העליונה, שבה נמצאת הלוגיקה של המערכת (business logic), עבודה מול המשתמש, עיבוד נתונים, ניהול משימות ופרוטוקולים ברמה גבוהה (כמו HTTP, MQTT או פרוטוקולים ייעודיים).

ההפרדה הזו מאפשרת קוד שימושי חוזר (code reusability), תחזוקה קלה יותר, פיתוח מהיר יותר ואמינות גבוהה יותר.

## בחירת רכיבים והנחיות לאינטגרציה

איך אנחנו בוחרים רכיבים שיתאימו ל-MCU שלנו? (Integration Guide)

1. מתחים (Voltage levels): לוודא שהמתחים של הרכיב וה-MCU תואמים (למשל 3.3V, 5V, 1.8V) כדי לא לשרוף פינים או לגרום לחוסר זיהוי של אותות.

2. צריכת זרם (Current consumption): לוודא שהבורד וה-MCU מסוגלים לספק את הזרם שהרכיב דורש.

3. ממשק תקשורת (Communication interface): לבדוק זמינות של I2C, SPI, UART וכו', ולוודא שהקצבים (baud rate) נתמכים.

4. כמות פינים ופונקציות אלטרנטיביות (Pin count & alternate functions): לוודא שאין התנגשויות בין פינים שונים שנדרשים לרכיבים שונים.

5. דרישות זמן (Timing requirements & Real-time): לוודא שה-interrupt latency והזמנים מתאימים לדרישות ה-real-time. שימוש ב-DMA (Direct Memory Access) במידת הצורך להעברות נתונים מהירות.

6. ניהול אנרגיה (Power management): התחשבות ב-startup time ו-wake-up time של הרכיב בעת עבודה במצבי חיסכון באנרגיה.

7. תיעוד ו-Errata: בדיקת דפי הנתונים ומסמכי ה-errata (מסמכי התקלות הידועות של הרכיב/MCU).

## ארכיטקטורת באסים (AHB ו-APB)

מבנה הבאסים ב-STM32:

ישנם שני סוגי באסים מרכזיים:

1. AHB (Advanced High-performance Bus): באס מהיר המיועד לרכיבים שדורשים רוחב פס גבוה, כמו ה-CPU, DMA, SRAM, Flash ו-GPIO מהירים (AHB1/AHB2).

2. APB (Advanced Peripheral Bus): באס איטי יותר המיועד לפריפריאלים שלא דורשים מהירות גבוהה, כגון I2C, SPI, UART, טיימרים וכו'. APB מחולק ל-APB1 (איטי יותר) ו-APB2 (מהיר יותר).

כדי לעבוד עם פריפריאל מסוים (למשל GPIOA), חובה קודם כל לאפשר את השעון (clock enable) של הבאס שבו הוא יושב דרך רכיב ה-RCC (Reset and Clock Control). ללא הפעלת השעון ב-RCC, גישה לריגסטרים של הפריפריאל לא תעבוד.

בואו נעשה הפסקה של 5 דקות, נחזור ב-8:37 ונמשיך לדבר על ה-interface ונעמיק בדוגמאות.

## פתיחה והצגת הקורס

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

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

אני רואה שלכולכם יש גישה למצגת ואני רואה שגם לא מעט התחברו, כל הכבוד.

## הצגת המרצה

ברוכים הבאים לקורס. אנחנו עושים את הקורס על STM32, ובגלל זה הוא גם נקרא Driver Development on STM32 Microcontrollers.

קצת הסבר עליי: אור פוקס (או אור סולימני), יש לי 10 שנים של ניסיון טכני, 7 שנים מתוכן ב-Software Development. עבדתי על Low-Level Embedded Code ל-Linux. יש לי גם בסיס של אלקטרוניקה מהצבא (שירתתי ב-108). יצא לי לעבוד על כמה Network Stacks, גם על TCP/IP ל-Satellite Communication וגם LTE eNodeB של 4G.

ההתמחות העיקרית שלי היא High-Performance Multi-threaded Real-Time ב-C/C++. אני עובד לרוב על Linux, אבל יצא לי לעבוד גם על מעבדים של Cortex-M3 ו-M4 לכמה פלטפורמות שונות. הידע העיקרי הוא Yocto, Kernel ו-Driver Development. אנחנו ניקח את ה-Driver Development ונדבר על איך מפתחים דרייברים למעבדים מסדרת Cortex-M3 ו-M4 של ARM, למכשירי IoT ונדבר על Low-Level Development. יצא לי לעבוד על הרבה Hardware Bring-up ו-Board-Level Communication.

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

אילון, ראיתי שאתה פתחת מצלמה ראשון, תרגיש חופשי להתחיל.

## סבב היכרות

**אילון:** היי, נעים מאוד. קוראים לי אילון אסרף, נשוי פלוס 3, מירושלים. ממש עכשיו סיימתי תואר ראשון בהנדסת אלקטרוניקה. בתכלס עובד כיום ב-Mobileye במשרת הנדסאי, עדיין במשרת סטודנט. כעיקרון הכיוון הוא יותר לכיוון ה-Chip Design, ASIC או FPGA. אם זה בחברה אצלנו אז זה ASIC מן הסתם. זהו בגדול.

**מרצה:** מגניב. כן, יש אצלכם הרבה ASIC ו-Logical Design, במיוחד למצלמות ול-LiDARים למיניהם. דרייברים – ראיתי שיש דרייברים ב-Linux ב-Mobileye, פחות על Bare Metal, אבל אפשר לקחת את הידע הזה ולעשות לו אפליקציה, להפעיל אותו על כל סוגי הדרייברים, גם ל-Windows וגם ל-Linux.

Next. עידן, ראיתי שפתחת מצלמה, תרגיש חופשי.

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

**מרצה:** מעולה, עידן עשה איתנו את ה-Bare Metal. שער, ראיתי שגם אתה פתחת מצלמה.

**שער:** אהלן, אז אני סטודנט שנה אחרונה בהנדסת מכונות. לקחתי מגמה של בקרה ומכטרוניקה, אז כן יצא לי להתעסק קצת עם STM, אבל ב-Windows, בפלטפורמת I/O. אני מכיר את ה-GPIO ואת ה-Analog to Digital, אבל לא עברנו על פרוטוקולי תקשורת, וזה כן משהו שמאוד מעניין אותי.

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

דן ואריה ואבי – דן, תתחיל אתה ואז אבי.

**דן:** אני עידן, אני מתעסק בפיתוח תוכנה מ-2014, עברתי ל-Embedded ב-2021. באתי לקורס הזה כי מדי פעם אני מקבל בעיות עם הדרייברים של ה-SDR וצריך לחפור בקוד שלהם ולא לחפור בבלבל. אז הייתי רוצה להכיר את זה לעומק.

**מרצה:** יפה. אבי?

**אבי:** [מגיב בצ'אט]

**מרצה:** סבבה, אבי רושם שהוא בלי מיקרופון, הוא סים ללמוד הנדסת חשמל ומתעסק בתחום ה-RF. RF זה מגניב, יצא לי לעבוד על RF ב-4G ובאנטנות מכ"ם.

**אילון:** שכחתי לשאול אותך, סביבת העבודה מתאימה למחשבי Mac?

**מרצה:** אני לא רואה סיבה שלא, פשוט בשלב של ההתקנה תתקין את ה-STM ל-Mac. אני חושב שאתה לא צריך Git Bash, במקרה הזה אתה עובד פשוט עם Git שיהיה מובנה לך כי זה Unix. אני חושב באחד הקורסים היה אחד שעשה את זה. אבל זה אמור להיות נתמך.

היום נעשה קצת Introduction ל-Course Foundations: מה זה בעצם דרייברים ואיך אנחנו מפתחים אותם. שיעור הבא אנחנו כבר נעשה GPIO Deep Dive - איך אנחנו מקנפגים GPIOs, איך אנחנו שולטים ואופטימיזציות.

שיעורים 3, 4 ו-5 נדבר יותר על תקשורות On-board שהן מאוד נפוצות: I2C (או I²C), SPI שזה Standard Peripheral Interface, תקשורת מאוד סטנדרטית, ו-UART שזה גם בסיס של כל מיני תקשורות שעליהם אנחנו מתבססים.

לאחר מכן נדבר על איך אנחנו עובדים עם ה-STM Hardware Abstraction Layer, בעצם השכבה של דרייברים ש-ST מספקים לנו.

ובשיעור לאחר מכן נדבר על Low Power Modes - איך אנחנו בעצם עובדים במצבים של Low Power, כך שאנחנו לא עובדים ב-100% CPU ולא תמיד מבזבזים את האנרגיה של המיקרו-קונטרולר.

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

## פילוסופיית הלימוד והנחיות לקורס

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

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

המטרות הן לקבל את הידע וה-Skills כדי לתכנן ולעשות אימפלמנטציה של דרייברים לכל ה-MCU Platforms. אני יכול להגיד לכם שה-Native שלי בכלל זה Silicon Labs. אבל זה בערך אותם דברים. אז במקום HAL היה להם את ה-Simplicity Studio ואת ה-Driverים שלהם. כל חברה בעצם זה אותו דבר. ברגע שיודעים לעבוד עם אחת, אתם יכולים לדעתי עם כולן, אם זה TI, Silicon Labs, מה שזה לא יהיה.

מיקרו-קונטרולרים, במיוחד אם זה ARM M, אז אנחנו יכולים לעבוד איתם כי הרבה מהמיקרו-קונטרולרים מוגדרים גם על ידי הארכיטקטורה וגם על ידי היכולות של המיקרו-קונטרולר. ובסוף אני רוצה שתבינו איך אנחנו שולטים במיקרו-קונטרולר, בדרייברים ובכל הפריפריאלים ברמת ה-Low Level, איך מקנפגים שעונים, איך אנחנו עושים Interrupt Handling, ו-Memory Architecture Design - בעצם איך אנחנו עובדים עם זיכרונות ואיך אנחנו בעצם משתמשים במבני נתונים כדי לשלוט בהם כמו שצריך.

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

אני רואה שאבי סיים ללמוד הנדסת חשמל ומתעסק בתחום ה-RF. RF זה מגניב, יצא לי לעבוד על RF ב-4G ובאנטנות מכ"ם.

חזרה לשאלה של אילון: סביבת העבודה מתאימה למחשבי Mac. פשוט בשלב של ההתקנה תתקין את ה-STM ל-Mac. אני חושב שאתה לא צריך Git Bash, במקרה הזה אתה עובד פשוט עם Git שיהיה מובנה לך כי זה Unix. אני חושב שאחד הקורסים היה אחד שעשה את זה, זה אמור להיות נתמך.

עוד דברים שנעשה היום: איך אנחנו בוחרים רכיבים שיתאימו ל-MCU (MCU זה Microcontroller Unit), איך אנחנו מתכוננים לקראת אינטגרציה, כלומר, או אם אנחנו מדברים על Bring-up, או אינטגרציה כללית של רכיב חדש למכלול שלנו, ל-Device שלנו. נדבר על Bus Interfaces שאנחנו הולכים לעבוד איתם, ונסיים עם MCU Interrupts. אז נתחיל עם ה-Manufacturer Set Interrupts, ונסיים עם ה-EXTI Interrupts, שזה ה-Interrupts של ה-ST.

מבחינת סביבה: יש לכולכם גישה, נכון? מי שלא היה, פשוט תעברו על השקפים ותתקינו את מה שצריך. מבחינת הסביבה שנכתוֹב עליה, אנחנו נעבוד על STM32CubeIDE. למה? זה לא הכי נוח לכתוב שם קוד, זה נכון, אבל זו סביבת פיתוח עם האינטגרציה הכי טובה ל-STM32, והסביבה הכי טובה, אנחנו נראה היום. וזה גם ילמד אותנו את הבסיס של איך לעבוד עם Eclipse-based IDE. אז Eclipse זה איזשהו Open Source של IDE שכולם משתמשים בו ומוסיפים לו Plugins. כל Manufacturer מוסיף לו Plugins כדי להתאים אותו ל-MCU שלו. אז לנו יש את STM32CubeIDE (או STM32CubeIDE). חברות אחרות יש את Simplicity Studio וכולי. לרוב אנחנו לא עובדים עם Eclipse Vanilla, אבל היו לי פרויקטים בעבר.

Git Bash: למחשבי Windows לרוב אין לנו Native Git, אז צריך להתקין Git Bash. יש התקנה בסלייד הבא. וה-Breakout Board.

אני עובד עם STM32F411E-DISCO. ה-Disco זה Discovery, אבל יש לו גם 4 הילוכים, ככה שזה גם עושה דיסקו. סתם בדיחה. אז בעצם הקורס הוא ספציפית לבורד הזה. אתם יכולים לעשות אותו על כל בורד, רק תעשו התאמות. אם אני עושה Reference ל-Reference Manual ספציפי ויש לכם בורד אחר, תעשו אותו עם זה. אם אין לכם בורד, אתם יכולים לדבר איתי, יש אפשרות לקנות מ-ST ישירות, זה מגיע ממש מהר והמשלוח יחסית לא יקר.

כאשר אנחנו נעשה כל מיני סימולציות, אנחנו ניקח איזשהו Arduino ונעשה לו Slave או Master Side Simulation. יש Arduino Uno, אנחנו נגיע לזה כבר בשיעורים הבאים. עוד דבר אחד: יכול להיות שבהמשך אני אצליח לאפס את ה-Logic Analyzer ואז נוכל לראות את הכל בלוגיקה. אם לא, אני פשוט אציג לכם סכמות ואראה לכם איך נראית התקשורת, אז גם עשינו את זה בשיעורים של המועדון.

התקנה של Git Bash וכמה Basic Commands: בגדול אתם לא צריכים לדעת יותר מדי מה-Commands האלה חוץ מ-`fetch`, כי אני כל שיעור מעדכן, וזה כבר נמצא ב-Repository שלי. בסוף המצגת, בגדול, אתם יכולים ליצור לעצמכם Branch שלכם ל-Assignments שאתם רוצים לשלוח לי. אתם יוצרים Branch ואז אתם דוחפים ואני יכול לעבור לכם על ה-Assignments ב-GitHub, זה ממש נוח. ואתם יכולים גם לשלוח לי קבצים, זה קצת יהיה פחות נוח, ה-Comments שלי יהיו פחות מובנים, אבל זו גם דרך לעבוד. הפקודות אם אתם לא מכירים: `git clone` ל-Repository עצמו.

הנה השם, אם אתם צריכים אני אשלח את זה עכשיו בצ'אט של ה-WhatsApp, ובהמשך תכלו פשוט להגיע לכאן. נעשה איזשהו Walkthrough עליו, יש גם הסבר על הקורס עצמו, על ה-Hardware Requirements, על הכל. Tools, אז Scope או Logic Analyzer זה אופציונלי. אני מקווה שאני אצליח לגרום לשלי לעבוד ואני אוכל להראות לכם את הכל כמו שצריך. אבל זה לא חובה. פה כבר יש לנו את ה-Topics, בעצם כל מה שאמרנו, מבנה התיקיות, וכל הדברים, איך אנחנו עובדים איתו ואיך אתם יכולים להגיש מטלות. זה ה-References, המייל שלי, מה שאתם צריכים, יש לכם את הכל פה. אם אתם לא מבינים מה זה ה-GitKeep, זה פשוט כדי שיהיה אפשר להעלות תיקיות ריקות.

זה ה-Git שלנו, מבחינתכם `git fetch` זה כל מה שמציג אתכם. ואם אתם יוצרים לעצמכם Branch, אז `git checkout -b` ותתחילו עם השם שלכם ואז השם של ה-Branch.

Installation של STM32CubeIDE מופיע ב-Readme של ה-Repository, וזה ממש פשוט להתקין, רק אני חושב שצריך איזשהי הרשמה, זה הכל. שאלות עד כה?

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

**עידן:** בשבילי היגיון, אני ככה עוד יום.

**מרצה:** אוקיי, אז דבר ראשון אתם יכולים לעצור אותי כדי שלא נגיע למצב שאני מדבר סינית ואתם לא מבינים. אז אתם יכולים לעצור אותי ולהגיד. דבר שני, יש לכם ב-WhatsApp את ה-Repository, שבו נמצא הקוד של הקורס. קובץ ה-Readme מכיל את כל המידע. מה אנחנו צריכים? קצת בסיס ב-C, הבנה קצת של Digital Electronics. אני מסביר הכל, שום דבר הוא לא באמת הכרחי. אני לא אכתוב משהו ב-C שהוא לא ברור או שלא תהיה לו הסברה. ואם כן, אתם יכולים לעצור אותי.

הדרישות: זה הבורד שאני עובד איתו. אתם יכולים לבחור כל בורד של STM32. אם אתם רוצים, יש לי רשימה של MCUs שאתם יכולים לעבוד איתם והם יהיו לי הכי נוחים לתמוך, אבל באמת לא קריטי. Arduino זה איזשהו Dumbed Down Board שאפשר לעשות איתו, אפשר לכתוב באיזשהו סטודיו ממש פשוט ולכתוב כל מיני בלוקים של Data, או כל מיני בלוקים של Commands במקום ממש ברמת ה-Register. טוב, זה לא צריך. אלה ה-Tools: STM32CubeIDE זה ה-IDE, זו סביבת הפיתוח. עוד שנייה אני אפתח אותה אצלי ואתם תוכלו לראות איך זה נראה. Git Bash - אתם יכולים ממש, אחרי שיהיה תתקינו, אז תהיה לכם אפשרות לעבוד עם GUI או עם ה-Terminal. אם אתם יודעים לעבוד עם ה-GUI סבבה, אני לא יודע. ואז יפתח לכם ה-Terminal. שנייה, אני פשוט עובד עם שני מסכים פעם ראשונה, אז אני עוד לא יודע לגמרי איך זה עובד. אז זה הקורס. אם אתם עושים `git status`, אתם יכולים לראות שיש כל מיני קבצים שהם לא שהם לא Committed ל-Branch, אבל אם תסתכלו טוב, זה כל מיני קבצים של Metadata, אז לא משהו שבאמת מעניין אותנו. וגם אתם יכולים להסתכל שזה לא ה-Repository הנכון. ה-Repository שלנו זה Driver Development Microcontroller, אז אתם יכולים ממש ללכת ל-Path הנכון. עכשיו אנחנו ב-Main. ופה אפשר לעשות `git status` שוב, `git status` ואז אנחנו רואים שאנחנו על ה-Main ואין שום דבר לדחוק.

אם אני דוחף מידע חדש או מכניס דוגמאות חדשות ואתם רוצים לעבוד איתם במהלך הקורס, אז לפני הקורס תעשו `git fetch`. אפשר לעשות גם `git fetch --all --prune` כדי שגם יעשה Fetch לכל וגם יעיף לכם קבצים שהם Untracked ואתם לא צריכים אותם. וגם ינקה את התיקייה של ה-Metadata של ה-Git. לא רלוונטי, אבל זו הפקודה הכי נוחה לעשות, ואז הוא הולך ל-Remote, וה-Remote שלנו זה כאן, ומביא את כל המידע שעדכנתי, כל המידע שאני דחפתי אצלי. ואז אתם יכולים להיות תמיד מעודכנים לשיעור. אז זה ה-Git ככה בשתי מילים.

בנוגע לכלים: אז יש לנו Scope ו-Logic Analyzer. Scope זה איזשהו ציוד בדיקה שמדפיס רמות מתח ביחס לזמן. אז הוא יוצר לנו כל מיני גלים חשמליים יפים כאלה, וזה כל מה שהוא עושה. Logic Analyzer הוא ספציפי לרמות מתחים של מיקרו-קונטרולרים ספציפיים. אני חושב שיש לו 1.8V, 3.3V ו-5V. המיקרו-קונטרולר שלנו עובד ב-3.3V. אז יש לי איזה מיקרו-קונטרולר סיני שהגיע מ-AliExpress ואני עדיין לא הצלחתי לגרום לו לעבוד. אולי אני אצליח בימים הקרובים ואז אני אוכל להציג לכם את ה-Data. אפשר ממש לקנפג אותו שהוא יראה לנו את המידע שנשלח.

סביבת פיתוח: זה האתר ומפה אפשר להוריד, מכאן מורידים את ה-IDE. וזה ה-Readme, זה בעצם הקובץ של ה-Repository שמסביר את כל מה שיש ב-Repository.

## סיכום הקורס הקודם (Recap)

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

דיברנו קצת על Bare Metal Foundation, על עבודה מול Device בלי מערכת הפעלה. איך אנחנו בעצם עובדים ישירות על המיקרו-קונטרולר ללא מערכת הפעלה, ככה שאנחנו לא עבודה עם Interrupts בצורה ישירה, עבודה עם ה-Buses, וגם בצורה של איך ה-Stack עובד מבחינת ה-MCU, ה-Call Stack. בעצם הקריאה והדחיפה של הפונקציות לתוך ה-Stack והפרמטרים עצמם.

דיברנו על הארכיטקטורה של מיקרו-בקרי ARM. היו לנו הרבה מאוד שיעורים על ארכיטקטורה של Cortex-M. הארכיטקטורה של המיקרו-בקר שאני עובד איתו ובכללי של הקורס, זה ARM Cortex-M. אני עובד עם Cortex-M4, אתם יכולים לבחור כל דבר, רק שימו לב שחלק מהפונקציונליות תהיה קצת שונה. ב-M4 יש לנו Floating Point Unit, יש לנו עוד כל מיני דברים שאין ב-M3, יש לנו גם Caching ועוד הרבה דברים. אז אם אנחנו מדברים על Features כאלה, הם פחות רלוונטיים לדרייברים. אם אנחנו מדברים על Features כאלה, אז תדעו שזה כאילו מגיע מכל מיני מקומות. ויש גם את M7, שזו הארכיטקטורה היותר חזקה של ARM. ה-M זה לדעתי Microcontroller, או סתם זה מתאים. אז זו הארכיטקטורה עצמה. יש ארכיטקטורות יותר מתקדמות של ARM, שזה ה-A ולמיקרו-מעבדים וכולי וכולי, אבל ה-M היא הבסיסית.

אחר כך דיברנו על Exception Handling. Exception זה בעצם פעולה אסינכרונית שעושה לנו המעבד ומקפיצה אותנו לתוך – נדבר על זה גם היום קצת – ומקפיצה אותנו לתוך קוד ספציפי כדי שנוכל להריץ אותו. אז זה Exception. בתוך Exception יש Interrupt. מה זה Interrupt? זה בעצם חתיכת קוד שרצה גם בצורה אסינכרונית לפי Events שהמעבד יודע לזהות. נדבר על זה בעיקר היום.

לקראת סוף הקורס התחלנו לדבר על Multitasking Implementation אם אין לנו מערכת הפעלה: איך אנחנו צריכים לעשות אימפלמנטציה של Multitasking, איך אנחנו עושים Task Scheduling, Context Switching ו-Stack Organization (איך אנחנו מחלקים את ה-Stack לכמה אזורים).

בסוף שני דברים אחרונים: דיברנו על Real-Time Design, דיברנו על עבודה עם Schedulers, עבודה עם Timer Configuration ואיך אנחנו יוצרים לעצמנו Task Scheduler כדי לעבוד לבד. וגם יצא לנו לדבר לא מעט על Optimization Techniques של הקומפיילר, Bit Manipulation, Memory Access Pattern וכל מה שעוזר לתכנית שלנו להיות קלה ומהירה. אז זה הקורס של ה-Bare Metal. אם יש לכם שאלות על זה, אתם מוזמנים, אבל יותר מדי על הקונספטים האלה אנחנו לא נעמיק, זה לא רלוונטי לקורס שלנו. שאלות?

**עידן:** מה ה-YouTube הזה?

**מרצה:** מישהו אמר קורס על Git בעברית, אתה רוצה להסתכל אחר כך.

**עידן:** מגניב. יש לי גם סיכום שאני תמיד שולח, הוא די ישן, אבל אולי אנשים אחרים שלחתי את זה, אני יכול לשלוח לכם גם.

## מהו דרייבר (Driver)?

מה זה בעצם דרייבר? דרייבר זה בעצם איזשהי שכבת אבסטרקציה שבין ה-Application Code, שזה הלוגיקה עצמה שנזקקת לעשות, כמו "שלח בייט", "תביא לי כתובת", וכולי, לבין ה-Hardware Peripheral. בעצם Hardware Peripheral, למה זה נקרא Peripheral? זה השכבה שהיא הפריפריה של ה-CPU.

יש לנו את ה-MCU, ה-MCU עצמו מורכב מ-CPU ומעוד חלקים. החלקים האלה הם הפריפריאלים. דוגמה: GPIO, GPIO זה Peripheral. General Purpose Input Output, שזה Peripheral ל-CPU, והוא מגיע ממש אל ה-Pins, אל ה-Pins של ה-Chip. ה-Pins האלה, זה ממש מה שיוצא בסוף על ה-GPIOs. הם יכולים להיות גם GPIOs לוגיים ואם דיברנו על ה-RF שזרקנו, זה יכול להיות GPIOs שיגיעו לתוך איזשהו מתנעל ויצרו לנו גלי רדיו. זו אפשרות נוספת.

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

אם יצא לכם לעבוד במערכות הפעלה קצת יותר מתקדמות כמו Linux או Windows, אין לנו גישה ישירה לחומרה, אז יש לנו System Calls או איזשהו Service Call שהוא יוצר לנו את הבקשה הזאת מהשכבה של החומרה ויש הפרדה לגמרי. ב-Bare Metal או במיקרו-קונטרולרים אין לנו את ההפרדה הזאת, אבל אנחנו עדיין רוצים ליצור איזשהי שכבה סטנדרטית כדי שלא נצטרך כל פעם מחדש לכתוב ישירות לחומרה, להגיד ל-Register הזה תזוז לפה. בשביל זה המציאו דרייבר.

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

מה אנחנו מכניסים בתוך דרייבר?

1. **Hardware Abstraction:** גישה ישירה ל-Registers, ובמקום שנעשה את זה מתוך האפליקציה, אנחנו עושים את זה בתוך הדרייבר. אז יש לנו בעצם ספרייה או Interface (או יותר נכון API), שממנו האפליקציה יכולה ניגשת אליו וככה היא משתמשת בחומרה.

2. **Resource Management:** יש לנו איזשהו Interface עקבי. אם אנחנו נממש System Calls, אז אנחנו עובדים עם System Calls בצורה הזאת, אבל במיקרו-קונטרולרים אין לנו את כל המקום ל-Overhead הזה, אז אנחנו עובדים עם איזשהו Standard API שאנחנו משאירים אותו קבוע לכל ה-Hardware Implementations. זה בעצם כמו VFS אם אתם מכירים, בעצם הכל נעשה באותה צורה, לא עבודה מול קבצים, אבל הכל נעשה באותה צורה. וככה המפתח יודע לכתוב את זה יותר מהר. זו אחת הסיבות שאנחנו עובדים ככה, כי המפתח יכול לכתוב עם הדרייברים האלה אפליקציות יותר מהירות ויותר חזקות ויותר ברורות, ולא יצטרך כל פעם לנחש מה ה-API אומר או מה זה. אז יש לנו API שהוא קבוע. ואיזשהו יתרון שלא שמפתחי אפליקציה לא צריכים לדעת מה קורה בחומרה והם יכולים ללמוד מאוד מהר יותר לתכנת. אז בעצם הדרייבר זה איזשהו שירות לאפליקציה.

3. **Error Handling:** בעצם איך אנחנו מנהלים קודי שגיאה ואיך אנחנו מנהלים Fault Conditions, איך אנחנו יודעים מתי לא הצליחה לנו כל מיני, לא הצליחה לנו הטרנזקציה וכולי וכולי.

4. **Resource Management:** איך אנחנו מתחילים ו-De-initializing (אם יש כזאת מילה), את ה-Peripherals בצורה טובה מספיק. אז אתחול של Peripherals, אם יש לנו GPIOs, אז מתחילים את ה-Pins בצורה שאנחנו צריכים, ו-De-initialization, או Cleanup, שזה שם יותר טוב.

5. **Performance Optimization:** כשאנחנו עובדים ברמת הדרייבר, אז אנחנו עושים Performance Optimization. ככה שאנחנו יכולים לעשות Buffering, אנחנו יכולים לעשות עוד כל מיני דברים שלא היינו יכולים לעשות אם היינו כותבים ישירות לחומרה, או שכל אחד היה צריך לממש את זה. אז אם אנחנו מממשים דברים בתוך שכבה שמגינה על האפליקציה מכל התורדנות והקושי של לעבוד מול החומרה, אז אנחנו יכולים גם לעשות Caching, אנחנו יכולים לעשות הרבה דברים. אז זה בעצם אופטימיזציה שנעשה.

6. **Portability:** עוד חלק חשוב, כאשר עובדים עם דרייברים, אנחנו לא תמיד עובדים עם אותו MCU. לפעמים ל-MCU יש End of Life, לפעמים לרכיבים יש End of Life, אז אנחנו כותבים קוד שיהיה Portable, ואז אנחנו יכולים לשנות כמה `#define`ים ואנחנו יכולים לקחת את הקוד הזה ולהריץ אותו במקום אחר, או על MCU מאותה משפחה או על MCU ממשפחה אחרת או אפילו יצרן אחר אם אנחנו עושים את זה בצורה ממש טובה.

שאלות על מה זה דרייבר?

## שלבים ליצירת ממשק דרייבר (Driver Interface)

מה בעצם השלבים שאנחנו עושים כאשר אנחנו ניגשים ליצירה של דרייבר חדש, לעבודה מול Interface חדש?

**Step 1: Hardware Analysis**

הדבר הראשון: אנחנו צריכים ללמוד את ה-Peripheral Data Sheet ו-Reference Manual. מה זה אומר? זה לא רק אומר ללמוד את ה-Data Sheet של הרכיב שאנחנו הולכים להתחבר אליו או של התקשורת עצמה, אם אנחנו דוגמה עובדים ב-I2C, אז לא ללמוד מה זה אומר I2C, זה ללכת ל-MCU שלנו וממש ללמוד את ה-Data Sheet ואת ה-Reference Manual שלו.

**Step 2: Define Driver Architecture**

- זיהוי ה-Registers הנדרשים ותפקידם.

- הבנת ה-Timing, תדרים ומגבלות חומרה.

- מיפוי ה-Pins ופונקציות חלופיות (Alternate Functions).

- יצירת קובצי הדר (`.h`) עם ה-Function Prototypes - לתכנן את ה-API שהדרייבר עובד איתו. אם אנחנו כבר עובדים בחברה ויש איזשהו סגנון שעובדים איתו, אז אנחנו לא נצטרך להתחיל לחשב את הכל מאפס, אבל אם זה משהו שאנחנו עושים, אנחנו נחשוב איך אנחנו רוצים לעבוד עם ה-API בצורה הכי טובה. עושים את זה ככשכותבים גם ספריות, ודרייבר הרבה פעמים זה ספרייה.

- נתכנן את ה-Data Structure שאנחנו הולכים לעבוד, לקונפיגורציה, אם זה אם אנחנו עובדים ב-C++ אז Class, אם אנחנו עובדים ב-C אז איזשהו Structure, אם אנחנו רוצים לעשות אותה בצורה דינמית, אם אנחנו רוצים לצרף אליו Circular Buffers. אז אלה דרכים שאפשר לעבוד.

- ניצור Error Codes ו-Return Types שאנחנו מחזירים מכל אחד ואחד.

**Step 3: Implement Core Functions**

- כתיבת פונקציות אתחול (`init`) ושחרור (`deinit`).

- מימוש פעולות קריאה וכתיבה (`read`/`write`).

- כתיבת פונקציות שליטה וקונפיגורציה.

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

**Step 4: Interrupt Integration**

- הגדרת NVIC ו-Interrupt Priorities.

- מימוש ISR (Interrupt Service Routines).

- יצירת מנגנון Callback לשימוש האפליקציה.

- וידוא Thread-Safety (למשל הגנה על משאבים משותפים) - שלא יכולה להיות גישה כפולה לאותו משאב משני מקומות שונים. איך אנחנו מבטיחים את זה? או אימפלמנטציה של Semaphore, או עבודה בצורה אטומית.

**Step 5: Testing and Documentation**

- יצירת Test Cases לכל הדרייברים.

- לוודא שה-Timing Requirements וה-Performance באמת עובדים.

- עושים Test Error כדי לסמלט את ה-Error ולראות אם אנחנו, אם עשינו אימפלמנטציה של Recovery Mechanism, לראות שזה גם עובד.

- את כל זה אנחנו דוחפים בצורה יפה במסמך, שזה מאוד חשוב, מסמך שמסביר לנו את הדוגמאות ואת ה-Limitations. שום חומרה היא לא אידיאלית, וזה בסדר, יש מסמכים עצומים שנקראים Errata, שמה המסמכים של כל התקלות הידועות של דרייברים או של MCUs בפרט.

## דוגמה לממשק דרייבר (RS485 Communication Driver)

שימו לב שהממשק הוא הבסיס, אין פה את כל מה שצריך. תוכלו להסתכל על דוגמאות באינטרנט, אבל זה בעצם מה שזה, הבסיס של מה שאנחנו צריכים. כאשר אנחנו עובדים עם תקשורות, אז יש לנו את ה-`init`, את ה-`deinit`. יש לנו גם הרבה פעמים `reconfigure`. אפשר גם לעשות משהו כזה: `bool rs485_reconfigure(rs485_config_t *config)`. למה `reconfigure` ולא `configure`? כי הקונפיגורציה נעשית לנו ב-`init`.

זה בעצם הבסיס שאנחנו צריכים. יש לכם באחת המטלות שלכם לקחת איזשהו ממשק דמיוני (זה יכול להיות RS485, זה יכול להיות אחד הממשקים שאנחנו נעשה בהמשך הקורס, USB, Whatever), ותתכננו לו API. אחר כך תתכננו איך אתם הולכים לתקשר איתו ותכתבו לי את קובץ ה-Header, תכינו את ה-Design Principles איך אתם רוצים, תעבדו ממש לפי המדריך הזה, ואתם יכולים לשלוח. אתם יכולים להשתמש ברפרנס בדוגמה הזאת שיש בשיעור.

הקובץ Header הזה, זה מה שיחשף לכל User שישתמש ב-`#include` הזה. ומה זה בעצם? יש את הפונקציה `init` שתחזיר לו את ה-Struct הזה, יש לו את הפונקציה `deinit` שזה ה-Destructor, או אפשר לחשוב על זה שמבטל את האתחול שעשינו לו, יש את ה-`transmit` שזו השליחה על הקווים של ה-RS485, `receive`, ו-`set_mode`. ואז גם את המוד, יש לנו פה כמה מודים.

זה בעצם מה שיקבע לנו את המוד, האם זה Receive או Transmit. זה בעיקר יש לנו את הפונקציה הזאת כאשר אנחנו רוצים לקבוע את התקשורות שהן Half-Duplex, שהן לא יכולות לשלוח ולקבל בו-זמנית. RS485 היא תקשורת כזאת, אז היא או שולחת או מקבלת. תחשבו שהפה והאוזן נמצאים באותו איבר, אז אתם לא יכולים גם לדבר וגם לשמוע מאותו המקום, אז זה ה-Half-Duplex.

יש עוד API שהוא מחזיר האם ה-RS485, האם הקווים שלו הם Busy, אם הם שולחים או מקבלים מידע. אז זה בעצם כשאני אומר API, אז זה בעצם מה שמגיע אל ה-User. ובמקרה הזה גם ה-Structure הזה. למה ה-Structure הזה גם כן? כי הרבה פעמים ה-User (המשתמש הבא, ה-User שלנו יכול להיות גם המתכנת של רמת האפליקציה, או שזה יכול להיות גם אנחנו), רוצה לדעת במה להשתמש.

לא בחרתי איזשהו Interface שאנחנו נרצה לעבוד איתו, רציתי שתבינו את הקונספט. RS485 זה איזשהו Placeholder לתקשורת שאנחנו לא מכירים, תקשורת סריאלית בטור בצורה של Half-Duplex, זאת אומרת שהיא יכולה רק לקבל או לשלוח בפעם אחת, היא לא יכולה לעשות את זה בו-זמנית.

במבנה השכבות:

1. **Application Layer:** הלוגיקה העסקית.

2. **Driver Layer (API):** השכבה שאנו מפתחים, המקשרת בין האפליקציה ל-HAL/Registers.

3. **HAL / Low-Level Registers:** כתיבה ישירה ל-Registers או שימוש ב-HAL של היצרן.

4. **Hardware:** הרכיבים הפיזיים.

תכנון של אינטגרציה:

- **Hardware Analysis:** מעבר על ה-MCU, ה-Data Sheet וה-Peripherals, ותכנון ה-Pin Assignment.

- **Electrical Matching:** וידוא שהרמות מתחים תואמות. למשל, ש-GPIO של 3.3V לא יחובר לרכיב שדורש 5V ללא תיאום מתחים, ושצריכת הזרם (Current Consumption) מתאימה ליכולת אספקת הכוח.

- **Interface Selection:** בחירת הפרוטוקול המתאים (I2C, SPI, UART) לפי קצב העברת הנתונים הנדרש, כמות ה-Pins הזמינים ומורכבות המימוש.

- **Timing & Performance:** בדיקת ה-Timing Requirements וה-Latency, לוודא שהמערכת עומדת בדרישות ה-Real-Time.

- **Power Management:** תכנון מנגנוני הדלקה וכיבוי של הרכיב (Power-up, Wake-up time) לחיסכון באנרגיה.

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

אנחנו חוזרים ב-20:37.

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

יש איתנו חבר'ה חדשים ויש חבר'ה מהקורסים הקודמים. תרגישו חופשי לפתוח מצלמות ולשאול שאלות.

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

## סבב היכרות

הקורס מתמקד בפיתוח דרייברים עבור בקרים ממשפחת STM32, ובפרט ארכיטקטורת ARM Cortex-M4.

שמי אור פוקס (סולימני). יש לי מעל 10 שנות ניסיון טכני, מתוכן כ-7 שנים בפיתוח תוכנה. עבדתי על קוד Low-level Embedded ולינוקס, ויש לי רקע באלקטרוניקה עוד מהשירות הצבאי (יחידה 8100). יצא לי לעבוד על Network Stacks, TCP/IP, Satellite Communication ו-LTE eNodeB. התמחותי העיקרית היא High-Performance Multithreaded Real-Time ב-C ו-C++. אני עובד בעיקר על Linux, אך עבדתי גם על מעבדי ARM Cortex-M3 ו-Cortex-M4 בפלטפורמות שונות. הידע העיקרי שלי הוא Yocto, Kernel ו-Driver Development.

כעת אשמח לשמוע מעט עליכם.

**אילון:** נעים מאוד, אילון אסרף. הנדסאי אלקטרוניקה, עובד כיום ב-Mobileye במשרת סטודנט. הכיוון שלי הוא Chip Design, ASIC או FPGA.

**אור:** מצוין. ב-Mobileye יש עבודה רבה סביב ASIC ו-Logical Design, במיוחד למצלמות וליידארים. דרייברים ב-Linux משיקים מאוד לתחום הזה.

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

**אור:** מעולה. עידו עשה איתנו את הקורס ב-Bare-metal. סער, תרצה להציג את עצמך?

**סער:** אלן, אני סטודנט שנה אחרונה בהנדסת מכונות. לקחתי מגמה של בקרה ומכטרוניקה, ויצא לי להתעסק מעט עם STM32 בסביבת Windows. אני מכיר GPIO ו-ADC, אבל לא עברנו על פרוטוקולי תקשורת, וזה נושא שמאוד מעניין אותי.

**אור:** מעולה. יהיו לנו שלושה שיעורים שמוקדשים כולם לפרוטוקולי תקשורת, ואנחנו נעבור עליהם לעומק.

**דן:** אני דן, מתעסק בפיתוח תוכנה מ-2014, ועברתי ל-Embedded ב-2021. הגעתי לקורס כדי להבין לעומק בעיות בדרייברים של ST שאני נתקל בהן מדי פעם.

**אבי:** סייימתי לימודי הנדסת חשמל, מתעסק בתחום ה-RF.

**אילון:** אור, יש לי שאלה לגבי סביבת העבודה – האם היא מתאימה למחשבי Mac?

**אור:** כן, אין מניעה. בשלב ההתקנה תתקין את גרסת STM32CubeIDE עבור Mac. לגבי Git, ב-Mac יש סביבת Unix מובנית, אז אין צורך ב-Git Bash נפרד אלא ב-Git רגיל בטרמינל.

## תוכנית הקורס

מה נעשה בקורס?

- **שיעור 1:** מבוא ו-Foundations של הקורס – מהו דרייבר ואיך מפתחים אותו.

- **שיעור 2:** GPIO Deep Dive – קונפיגורציה, שליטה ואופטימיזציות.

- **שיעורים 3–5:** תקשורת On-board נפוצה: I2C (או I²C), SPI ו-UART/USART כולל תקשורת טורית כמו RS-485.

- **שיעור 6:** עבודה עם ה-HAL (Hardware Abstraction Layer) של ST.

- **שיעור 7:** מצבי צריכת חשמל נמוכה (Low Power Modes) וניהול אנרגיה ברמת המיקרו-בקר.

- **שיעורים 8–9:** פרויקט אישי (Personal Project) – אינטגרציה ובחירת רכיבים.

## פילוסופיית הלמידה והגשת מטלות

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

מטרת הקורס היא לתת לכם את הידע והכישורים לתכנן ולממש דרייברים עבור פלטפורמות MCU שונות. אף על פי שאנו עובדים עם STM32, העקרונות זהים גם בחברות אחרות כמו Silicon Labs או Texas Instruments. ברגע שלומדים לעבוד מול ארכיטקטורה אחת כמו ARM Cortex-M, הידע ניתק לעבודה מול יצרנים אחרים.

אנחנו נבין איך לשלוט במיקרו-בקר, בדרייברים ובפריפריאליות ברמת ה-Low-level, איך לקנפג שעונים (Clocks), לנהל פוסקים (Interrupts) ולעבוד מול זיכרון ומבני נתונים.

## סביבת העבודה והכלים

סביבת העבודה העיקרית שלנו היא **STM32CubeIDE**, המבוססת על Eclipse. היא מופצת כ-Open Source וכל יצרן מוסיף לה פלאגינים להתאמה לרכיבים שלו.

בנוסף נזדקק ל:

1. **Git Bash** (למשתמשי Windows) או טרמינל (למשתמשי Mac/Linux).

2. **כרטיס פיתוח (Breakout Board):** אנו עובדים עם **STM32F411E-DISCO** (Discovery board) הכולל מעבד STM32F411, אך ניתן לעבוד עם כרטיסים מקבילים.

3. **Arduino Uno:** ישמש אותנו בשיעורים המתקדמים לסימולציה של רכיב קצה (Master/Slave) מול ה-STM32.

4. **Logic Analyzer:** כלי רשות למדידת אותות חשמליים ופרוטוקולים על הקווים.

## עבודה עם מאגר הקוד (Git)

מאגר הקוד של הקורס זמין ב-GitHub.

פקודות Git בסיסיות שנדרש להכיר:

- `git clone <repository_url>` – להורדת המאגר למחשב האישי.

- `git fetch --all --prune` – לעדכון הענפים והמידע מהשרת.

- `git checkout -b <branch_name>` – יצירת ענף חדש עבור הגשת המטלות שלכם.

בתוך המאגר תמצאו קובץ `README.md` המפרט את מבנה התיקיות, הדרישות וסביבת העבודה.

## יסודות ה-Bare-Metal והארכיטקטורה

בפיתוח Bare-metal אין לנו מערכת הפעלה (OS) שמנהלת את הזיכרון או את התהליכים. הקוד שלנו רץ ישירות על החומרה.

נקודות מפתח בארכיטקטורת ARM Cortex-M:

- **Call Stack:** ניהול קריאות לפונקציות ואוגרים (Registers) בזמן ביצוע.

- **Interrupts & Exceptions:** מנגנון הקפצת הקוד לטיפול באירועי חומרה אסינכרוניים.

- **Register Access:** גישה ישירה לכתובות זיכרון הממופות לאוגרי הפריפריה (Memory-Mapped I/O).

- **Bit Manipulation:** ביצוע פעולות AND, OR, XOR ו-Shifting לצורך הגדרת ביטים באוגרים.

## מהו דרייבר? (Driver)

דרייבר הוא שכבת תוכנה המפקשטת (Abstracts) את הגישה לחומרה עבור שכבת האפליקציה.

מאפייני הדרייבר:

1. **Hardware Abstraction:** מתן ממשק אחיד לאפליקציה ללא תלות במימוש החומרי הספציפי.

2. **Resource Management:** אתחול הפריפריה, הגדרת קונפיגורציה ושחרור משאבים.

3. **Error Handling:** זיהוי שגיאות חומרה והחזרת קודי שגיאה סטנדרטיים לאפליקציה.

4. **Performance & Buffering:** ניהול חוצצים (Buffers) והעברת נתונים יעילה (למשל באמצעות DMA או Interrupts).

5. **Portability:** אפשרות להעביר את קוד האפליקציה בין רכיבי חומרה שונים תוך שינוי הדרייבר בלבד.

## אינטראקציה בין שכבת האפליקציה לשכבת הדרייבר

קיימת הפרדה ברורה בין השכבות:

- **שכבת האפליקציה (Application Layer):** מכילה את ה-Business Logic, ניהול המצבים (State Machines), מעבדת נתונים ומקבלת החלטות. היא קוראת ל-APIs של הדרייבר.

- **שכבת הדרייבר (Driver Layer):** מורכבת ממימוש פיזי של הגישה לאוגרים, ניהול הפריפריה וטיפול בפסיקות.

האפליקציה אינה ניגשת ישירות לאוגרי החומרה, אלא משתמשת בקריאות פונקציה מוגדרות מראש לקבלת שירותים.

## שלבי פיתוח דרייבר

תהליך הפיתוח כולל ארבעה שלבים עיקריים:

1. **Hardware Analysis:** קריאה וניתוח של ה-Data Sheet וה-Reference Manual (RM) של הרכיב והמיקרו-בקר.

2. **Interface Design:** הגדרת קובץ ה-Header (`.h`), כולל מבני נתונים (Structs), טיפוסי נתונים, Enums לקודי שגיאה ופרוטוטיפים של פונקציות ה-API.

3. **Core Implementation:** כתיבת קובץ ה-C (`.c`) הכולל פונקציות אתחול (`Init`), סגירה (`DeInit`), קריאה/כתיבה (`Read`/`Write`), טיפול בפסיקות (ISRs) ושמירה על Thread-Safety במידת הצורך.

4. **Testing & Verification:** כתיבת מקרי בדיקה (Test Cases), בדיקת תזמונים בעזרת סקופ או Logic Analyzer, ודימוי מצבי שגיאה.

## דוגמה לממשק דרייבר: RS-485

כדוגמה לממשק דרייבר לתקשורת טורית בכיסוי RS-485 (העובדת בתצורת Half-Duplex), נגדיר את הקובץ ה-Header הבא:

```c

/* rs485.h - RS485 Driver Interface */

typedef struct {

uint32_t baud_rate;

uint8_t word_length;

uint8_t stop_bits;

uint8_t parity;

} rs485_config_t;

typedef enum {

RS485_OK = 0,

RS485_ERROR,

RS485_BUSY,

RS485_TIMEOUT

} rs485_status_t;

rs485_status_t rs485_init(const rs485_config_t *config);

rs485_status_t rs485_deinit(void);

rs485_status_t rs485_transmit(const uint8_t *data, uint16_t length);

rs485_status_t rs485_receive(uint8_t *buffer, uint16_t max_length);

bool rs485_is_busy(void);

```

הממשק מספק פונקציות ברורות לאפליקציה, ומסתיר את הרישום הפיזי לאוגרי ה-UART וה-GPIO שמנהלים את כיוון התקשורת (Transmit/Receive Enable).

## עבודה עם Data Sheet ו-Reference Manual

בעבודה מול STM32 אנו נעזרים בשני מסמכים מרכזיים:

- **Data Sheet:** מפרט את המאפיינים החשמליים, פינאאוט (Pinout), מפת הזיכרון הכללית וחבילות הרכיב.

- **Reference Manual (RM):** המסמך המפורט המסביר את פעולת כל הפריפריאליות, מבנה האוגרים (Register Maps) והביטים הספציפיים בכל אוגר.

## ארכיטקטורת האוטובוסים (Bus Matrix): AHB ו-APB

המיקרו-בקר משתמש במטריצת אוטובוסים (Bus Matrix) לחיווט בין ה-CPU, ה-DMA והפריפריאליות:

- **AHB (Advanced High-Performance Bus):** אוטובוס מהיר המיועד לרכיבים הדורשים רוחב פס גבוה, כגון זיכרון ה-Flash, ה-RAM, מנגנון ה-DMA ו-GPIOs. ב-STM32 הוא מחולק ל-AHB1 ו-AHB2.

- **APB (Advanced Peripheral Bus):** אוטובוס איטי יותר המיועד לפריפריאליות סטנדרטיות. מחולק ל-APB1 (איטי יותר, למשל I2C, UART) ו-APB2 (מהיר יותר, למשל SPI, TIM1).

כדי לעבוד עם פריפריה מסוימת, חובה תחילה לאפשר את השעון (Clock) שלה באוגר ה-RCC (Reset and Clock Control) המתאים באוטובוס שלה (למשל `RCC_AHB1ENR` עבור GPIOA).

## קריטריונים לבחירת רכיבים ואינטגרציה

כשבאים לבחור רכיב חומרה חיצוני ולחבר אותו ל-MCU, יש לבחון:

1. **Electrical Compatibility:** תאימות מתחים (3.3V vs 5V) וצריכת זרם.

2. **Communication Interface:** זמינות הפריפריה ב-MCU (I2C, SPI, UART) ואפשרות חיווט הפינים (Alternate Functions).

3. **Timing Requirements:** עמידה בדרישות זמן אמת ושיהוי פסיקות (Interrupt Latency).

4. **Power Management:** זמני התעוררות (Wake-up time) ומצבי שינה.

5. **Software Support:** זמינות תיעוד ודרייברים קיימים.

## הנחיות למטלת הבית וסיכום

**מטלה לבית:**

1. בחרו פרוטוקול תקשורת או רכיב חומרה (לדוגמה: חיישן טמפרטורה ב-I2C, רכיב זיכרון ב-SPI, או תקשורת UART/RS-485).

2. תכננו את קובץ ה-Header (`.h`) עבור הדרייבר: הגדירו מבנה קונפיגורציה (`struct`), קודי שגיאה (`enum`) ופרוטוטיפים של הפונקציות הנדרשות.

3. דחפו את השינויים לענף האישי שלכם ב-Git.

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

Az, ברוכים הבאים לקורס דרייברים. אנחנו המחזור הראשון של הקורס הזה שיוצא, קורס המשך שהוא לאו דווקא קורס המשך ל-Bare Metal Programming, אבל הידע הוא חופף לחלוטין, כך שאפשר להתחיל אותו מהאמצע, ובלבד שהידע של Bare Metal לא חסר או שזה איזשהו חסך שאפשר להשלים.

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

## מבוא והצגת הקורס

ברוכים הבאים לקורס. אנחנו עושים את הקורס על STM32, בגלל זה הוא גם נקרא Driver Development on STM32 Microcontrollers.

הסבר עליי: אור פוקס (או אור סולימני, לא שיניתי את השם למזמן). יש לי 10 שנים של ניסיון טכני, 7 שנים מתוכן ב-Software Development. עבדתי על Low-Level Embedded Code ל-Linux, יש לי גם בסיס של אלקטרוניקה מהצבא (שירתתי ב-8200). יצא לי לעבוד על כמה Network Stacks, גם על TCP/IP ל-Satellite Communication וגם LTE eNodeB שזה 4G וסביבתם.

ההתמחות העיקרית שלי היא High-Performance Multi-threaded Real-time ב-C/C++. אני עובד לרוב על Linux, אבל יצא לי לעבוד גם על מעבדים של Cortex-M3 ו-M4 בכמה פלטפורמות שונות.

הידע העיקרי שלי זה Yocto, Kernel ו-Driver Development. אנחנו ניקח את ה-Driver Development ונדבר על איך מפתחים דרייברים למעבדים מסדרת Cortex-M3 ו-M4 של ARM, למכשירי IoT, ונדבר על Low-Level Development.

נעבור על כל מיני תקשורות On-board רגילות. עבדתי על הרבה Hardware Bring-up ו-Board Level Communication, ואלו הפלטפורמות שאני בעיקר מתמחה בהן.

## סבב היכרות

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

**אילון:** נעים מאוד, קוראים לי אילון עסרף, נשוי פלוס שלושה, מירושלים. ממש עכשיו סיימתי תואר בהנדסת אלקטרוניקה. בתכלס עובד כיום ב-Mobileye במשרת הנדסאי, עדיין במשרת סטודנט. וזהו, בעיקרון הכיוון הוא יותר ל-Chip Design, ASIC או FPGA. אם זה בחברה אצלנו אז זה ASIC מן הסתם. וזהו, בגדול.

**מרצה:** מגניב. כן, יש אצלכם הרבה ASIC ו-Logic Design, במיוחד למצלמות ול-LiDARים שנסגרו. דרייברים ב-Linux ב-Mobileye פחות נוגעים ב-Bare Metal, אבל אפשר לקחת את הידע הזה ולהפעיל אותו על כל סוגי הדרייברים, גם ל-Windows וגם ל-Linux.

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

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

**מרצה:** מעולה, תודה. עידן עשה איתנו את ה-Bare Metal. שר, ראיתי שגם אתה פתחת מצלמה.

**שר:** אהלן, אז אני סטודנט שנה אחרונה בהנדסת מכונות. לקחתי מגמה של בקרה ומכטרוניקה, אז כן יצא לי להתעסק קצת עם STM, אבל ב-Windows, בפלטפורמה של I/O. אני מכיר GPIO ו-Analog-to-Digital, אבל לא עברנו על פרוטוקולי תקשורת וזה כן משהו שמוד מעניין אותי.

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

**דן:** כן, אז אני דן, אני מתעסק בפיתוח תוכנה מ-2014. עברתי ל-Embedded ב-2021, ובאתי לקורס הזה כי מדי פעם אני מקבל בעיות עם הדרייברים של ST, וצריך לחפור בקוד שלהם ולא תמיד מבינים. אז הייתי רוצה להכיר את זה לעומק.

**מרצה:** יפה. אבי? אוקיי, אבי כנראה צריך לפתוח את המיקרופון, אז הוא יהיה איתנו בהמשך.

## סילבוס ומטרות הקורס

אז מה נעשה בעצם בצירי הקורס? היום נעשה קצת Introduction ל-Course Foundations: מה זה בעצם דרייברים ואיך אנחנו מפתחים אותם.

שיעור הבא אנחנו כבר נעשה GPIO Deep Dive - איך אנחנו מקנפגים GPIOs, איך אנחנו שולטים בהם ואופטימיזציות.

שיעורים 3, 4 ו-5 - אנחנו נדבר יותר על תקשורות On-board שהן מאוד נפוצות: I2C (או I-squared-C, תלוי מאיפה באתם), SPI שזה Standard Peripheral Interface - עוד תקשורת מאוד סטנדרטית, ו-UART שזה גם בסיס לכל מיני תקשורות שעליהן אנחנו מתבססים (כמו RS-485).

לאחר מכן נדבר על איך אנחנו עובדים עם ה-STM Hardware Abstraction Layer (HAL), בעצם שכבת הדרייברים ש-ST מספקים לנו.

בשיעור לאחר מכן נדבר על Low Power Modes - איך אנחנו בעצם עובדים במצבים של Low Power, ככה שאנחנו לא עובדים ב-100% CPU ולא תמיד מבזבזים את האנרגיה של המיקרו-קונטרולר.

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

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

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

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

המטרות הן בעצם לקבל את הידע וה-Skills כדי לתכנן ולעשות אימפלמנטציה של דרייברים לכל ה-MCU Platforms. אני יכול להגיד לכם שה-Native שלי בכלל זה Silicon Labs, אבל בערך אלה אותם דברים: במקום HAL היה להם את ה-Simplicity Studio ואת הדרייברים שלהם. בכל חברה בעצם זה אותו דבר. ברגע שיודעים לעבוד עם אחת, אפשר לדעת לעבוד עם כולן (TI, Silicon Labs, מה שזה לא יהיה).

מיקרו-קונטרולרים, במיוחד אם זה ARM Cortex-M, מוגדרים גם על ידי הארכיטקטורה וגם על ידי היכולות של המיקרו-קונטרולר. בסוף אני רוצה שתבינו איך אנחנו שולטים במיקרו-קונטרולר, בדרייברים ובכל הפריפריאלים ברמת ה-Low Level, איך מקנפגים שעונים, איך אנחנו עושים Interrupt Handling, ו-Memory Architecture Design - בעצם איך אנחנו עובדים עם זיכרונות ואיך אנחנו משתמשים במבני נתונים כדי לשלוט בהם כמו שצריך.

מה נעבור היום? היום נעשה איזשהו Recap של הקורס הקודם, גם כדי שמי שלא היה בקורס ידע מה למדנו שם ועל מה אנחנו מדברים כאשר אנחנו זורקים מושגים לאוויר. מדברים על מה זה דרייברים, מה השלבים שאנחנו עושים כדי לפתח דרייבר ואיך אנחנו כותבים לו Interface, ונעשה איזשהו Driver Interface Example. נעשה את זה בכוונה לתקשורת שאנחנו לא הולכים לעשות לה אימפלמנטציה בשיעור.

אני רואה שאבי סיים ללמוד הנדסת חשמל ומתעסק בתחום ה-RF. RF זה מגניב, יצא לי לעבוד על RF ב-4G ועל אנטנות מכ"ם.

**אילון:** סליחה, שאלתי אותך בצ'אט - סביבת העבודה מתאימה למחשבי Mac?

**מרצה:** אני לא רואה סיבה שלא, פשוט בשלב של ההתקנה תתקין את ה-STM ל-Mac. אני חושב שאתה לא צריך Git Bash, במקרה הזה אתה עובד פשוט עם Git שהוא מובנה לך כי זה Unix. אני חושב שבאחד הקורסים היה אחד שעשה את זה, הוא לא ויתר. אבל אמורה להיות תמיכה.

## סביבת העבודה והכלים

עוד דברים שנעשה היום: איך אנחנו בוחרים רכיבים שיתאימו ל-MCU (Micro Controller Unit), איך אנחנו מתכוננים לקראת אינטגרציה (בין אם מדובר על Bring-up או אינטגרציה כללית של רכיב חדש לתוך ה-Device שלנו), נדבר על Bus Interfaces שאנחנו הולכים לעבוד איתם, ונסיים עם MCU Interrupts - נתחיל עם ה-Manufacturer Set Interrupts ונסיים עם ה-EXTI Interrupts שזה ה-Interrupts של ה-ST.

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

מבחינת הסביבה שאנחנו נעבוד עליה - אנחנו נעבוד על STM32CubeIDE. למה? זה לא הכי נוח לכתוב שם קוד, זה נכון, אבל זו סביבת הפיתוח עם האינטגרציה הכי טובה ל-STM32. זה גם ילמד אותנו את הבסיס של איך לעבוד עם Eclipse-based IDE. אקליפס זה איזשהו Open Source של IDE שכולם משתמשים בו ומוסיפים לו פלאגינים, כל Manufacturer מוסיף לו פלאגינים כדי להתאים אותו ל-MCU שלו. לנו יש את STM32CubeIDE (או STM32CubeIDE). לחברות אחרות יש את Simplicity Studio וכולי. לרוב לא נעבוד עם Eclipse ואני לא עבדתי עם Eclipse Vanilla, אבל היו לי פרויקטים בעבר.

Git Bash - למחשבי Windows לרוב אין לנו Native Git, אז צריך להתקין Git Bash. יש התקנה בסלייד הבא, וה-Breakout Board.

אני עובד עם STM32F411RE-Nucleo (ה-Disco זה Discovery, אבל יש לו גם 4 לדים ככה שהוא עושה גם דיסקו). הקורס בעצם יהיה ספציפית ל-Board הזה. אתם יכולים לעשות אותו על כל Board, רק תעשו התאמות. אם אני עושה Reference ל-Reference Manual ספציפי ויש לכם Board אחר - תעשו אותו עם זה. אם אין לכם Board, יש אפשרות לקנות מ-ST ישירות, זה מגיע ממש מהר והמשלוח יחסית לא יקר.

כאשר נעשה כל מיני סימולציות, ניקח איזשהו Arduino ונעשה לו Slave או Master Side Simulation. יש Arduino Uno, נגיע לזה כבר בשיעורים הבאים.

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

התקנה של Git Bash וכמה Basic Commands: בגדול אתם לא צריכים לדעת יותר מדי מה-Commands האלה חוץ מ-`git fetch`, כי כל שיעור אני מעדכן וזה כבר מחובר ישר ל-Repository שלי. בסוף המצגת הוא נמצא שם.

בגדול, אתם יכולים ליצור לעצמכם Branch שלכם ל-Assignments שאתם רוצים לשלוח לי. אתם יוצרים Branch ואז אתם דוחפים ואני יכול לעבור לכם על ה-Assignments ב-GitHub, זה ממש נוח. ואתם יכולים גם לשלוח לי קבצים, זה קצת יהיה פחות נוח, הקומנטים שלי יהיו פחות מובנים על מה שזה, אבל זו גם דרך לעבוד.

הפקודות, אם אתם לא מכירים: `git clone` ל-Repository עצמו (פה תחליפו את המקום של Repo Name, אני אתן לכם פשוט את השם).

זה השם, אם אתם צריכים אני אשלח את זה עכשיו בצ'אט של ה-WhatsApp, ובהמשך תוכלו פשוט להגיע לכאן. נעשה איזשהו Walkthrough עליו. יש גם הסבר על הקורס עצמו, על ה-Hardware Requirements, על הכל. Tools: אוסקילוסקופ או Logic Analyzer זה אופציונלי. אני מקווה שאצליח לגרום לשלי לעבוד ואוכל להראות לכם את הכל כמו שצריך. פה כבר יש לנו את ה-Topics, את המבנה תיקיות, ואת כל הדברים: איך אנחנו עובדים איתו ואיך אתם יכולים להגיש מטלות. אלה ה-References, המייל שלי, מה שאתם צריכים - יש לכם את הכל פה.

אתם יכולים לראות, לשאול שאלות, ויש גם את ה-Documentation שעבדתי איתם, הם גם נמצאים כאן. אם אתם לא מבינים מה זה ה-Git Keep, זה פשוט כדי שיהיה אפשר להעלות תיקיות ריקות.

זה ה-Git שלנו, מבחינתכם `git fetch` זה כל מה שמניע אתכם. ואם אתם יוצרים לעצמכם Branch, אז `git checkout -b` מתחיל עם השם שלכם ואז השם של ה-Branch.

Installation של STM32Cube מופיע ב-Readme של ה-Repository, וזה ממש פשוט להתקין, רק שצריך איזשהי הרשמה.

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

**מרצה:** אוקיי, אז דבר ראשון אתם יכולים לעצור אותי כדי שלא נגיע למצב שאני מדבר סינית ואתם לא מבינים, אז אתם יכולים לעצור אותי ולהגיד. דבר שני, יש לכם ב-WhatsApp את ה-Repository (המיקום שבו נמצא הקוד של הקורס). הקובץ של Readme יש עליו את כל המידע.

מה אנחנו צריכים? קצת בסיס ב-C, הבנה קצת של Digital Electronics. אני מסביר הכל, שום דבר לא באמת הכרחי. אני לא אכתוב משהו ב-C שהוא לא ברור או שלא אקבל הסבר, ואם כן - עכשיו אתם יכולים לעצור אותי.

הדרישות: זה ה-Board שאני עובד איתו. אתם יכולים לבחור כל Board של STM32. אם אתם רוצים, יש לי רשימה של MCUs שאתם יכולים לעבוד איתם ויהיה לי הכי נוח לתמוך, אבל באמת לא קריטי.

Arduino זה איזשהו Dumbed Down Board שאפשר לעשות איתו, אפשר לכתוב באיזשהו Studio ממש פשוט ולכתוב כל מיני בלוקים של Data או כל מיני בלוקים של Commands במקום ממש ברמת ה-Register. אלה ה-Tooling: בעצם STM32Cube זה ה-IDE, זו סביבת הפיתוח. עוד שנייה אני אפתח אותה אצלי ותוכלו לראות איך זה נראה.

Git Bash - את זה אני כן אעשה, אתם יכולים ממש אחרי שתתקינו, תהיה לכם את האפשרות לעבוד עם GUI או עם ה-Terminal. אם אתם יודעים לעבוד עם ה-GUI סבבה, ואז יפתח לכם ה-Terminal.

זה הקורס, אם אתם עושים `git status` אתם יכולים לראות שיש כל מיני קבצים שהם לא Committed ל-Branch, אבל אם אתם מסתכלים טוב אלה כל מיני קבצים של Metadata, אז לא משהו שבאמת מעניין אותנו. וגם אתם יכולים להסתכל שזה לא ה-Repository הנכון, אז אני מתנצל. ה-Repository שלנו זה `driver-development-microcontroller`. אז אתם יכולים ממש ללכת ל-Path הנכון. עכשיו אנחנו ב-Main, ואם אנחנו עושים `git status` אנחנו רואים שאנחנו על ה-Main ואין שום דבר לדחוף.

אם אני דוחף מידע חדש או מכניס דוגמאות חדשות ואתם רוצים לעבור איתם במהלכו של הקורס, אז לפני הקורס תעשו `git fetch --all --prune` ככה שגם יעשה Fetch להכל וגם יעיף לכם קבצים שהם Untracked ואתם לא צריכים אותם. וגם ינקה את התיקייה של ה-Metadata, שזה לא רלוונטי אבל זה חוסך. אז זו הפקודה הכי נוחה לעשות, ואז הוא הולך ל-Remote ומביא את כל המידע שעדכנתי, את כל המידע שאני דחפתי אצלי, ואז אתם יכולים להיות תמיד מעודכנים לשיעור. זה ה-Git ככה בשתי מילים.

## מהו דרייבר? (Application vs Driver Layer)

בשביל מה נעשה כל מיני סימולציות? אנחנו ניקח איזשהו Arduino ונעשה לו Slave או Master Side Simulation.

נעבור לנושא הבא: מה זה בעצם דרייבר? דרייבר זה בעצם איזושהי שכבת אבסטרקציה שבין ה-Application Code (שזה הלוגיקה עצמה שאנחנו צריכים לעשות, כמו "תשלח בייט", "תביא לי כתובת" וכולי) לבין ה-Hardware Peripheral.

בעצם Hardware Peripheral (למה זה נקרא Peripheral?) - זו השכבה שהיא הפריפריה של ה-CPU. יש לנו את ה-MCU, ה-MCU עצמו מורכב מ-CPU ומעוד חלקים. החלקים האלה הם הפריפריאלים. דוגמה: GPIO. GPIO זה Peripheral, General Purpose Input Output, שזה Peripheral ל-CPU והוא מגיע ממש אל ה-Pins, אל ה-Pins של הצי'פ (כמו שאתם רואים בתמונה המג'ונרטת היפה הזאת).

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

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

אם יצא לכם לעבוד במערכות הפעלה קצת יותר מתקדמות כמו Linux או Windows, אין לנו גישה ישירה לחומרה, אז יש לנו System Calls או איזשהו Service Call שהוא יוצר לנו את הבקשה הזאת מהשכבה של החומרה ויש הפרדה לגמרי.

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

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

מה אנחנו מחניסים בתוך דרייבר? יש לנו Hardware Abstraction: גישה ישירה לריגסטרים ובמקום שנפעל מתוך האפליקציה, אנחנו עושים את זה בתוך הדרייבר. אז יש לנו בעצם ספרייה או Interface (או יותר נכון API) שממנו, שאותו האפליקציה יכולה לשתף וככה היא משתמשת בחומרה.

יש לנו איזשהו Interface קונסיסטנטי: אם אנחנו מימשנו System Calls, אז אנחנו עובדים עם System Calls בצורה הזאת. אבל במיקרו-קונטרולרים אין לנו את כל המקום ל-Overhead הזה, אז אנחנו עובדים עם איזשהו Standard API שאחנו משאירים אותו קבוע לכל ה-Hardware Implementations. זה בעצם כמו VFS אם אתם מכירים, בעצם הכל בצורה, הכל נעשה באותה צורה, לא עבודה מול קבצים, אבל הכל נעשה באותה צורה.

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

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

Error Handling: בעצם איך אנחנו מנהלים Error Codes ואיך אנחנו מנהלים Fault Condition, איך אנחנו יודעים מתי לא הצליחה לנו כל מיני, לא הצליחה לנו טרנזקציה וכולי.

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

עוד דבר אחד שאנחנו עושים ברמת הדרייבר, זה Performance Optimization: ככה שאנחנו יכולים לעשות Buffering, אנחנו יכולים לעשות עוד כל מיני עוד כל מיני דברים שלא היינו יכולים לעשות אם היינו כותבים ישירות לחומרה, או שכל אחד היה צריך לממש את זה. אז אם אנחנו מממשים דברים בתוך שכבה שמגינה על האפליקציה מכל התורדנות והקושי של לעבוד מול החומרה, אז אנחנו יכולים גם לעשות Caching, אנחנו יכולים לעשות הרבה דברים.

זה בעצם האופטימיזציה שאנחנו יכולים לעשות, ועוד חלק חשוב: כאשר עובדים עם דרייברים, אנחנו לא תמיד עובדים עם אותו MCU, לפעמים ל-MCU יש End of Life, לפעמים לרכיבים יש End of Life, אז אנחנו כותבים קוד שיהיה פורטבילי, ואז אנחנו יכולים לשנות כמה Defines ואנחנו יכולים לקחת את הקוד הזה ולהריץ אותו במקום אחר, או על MCU מאותה משפחה, או על MCU ממשפחה אחרת או אפילו מ-Manufacturer אחר אם אנחנו עושים את זה בצורה ממש טובה.

## חזרה על יסודות Bare Metal וארכיטקטורה

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

דיברנו קצת על Bare Metal Foundations: על עבודה מול Device ללא מערכת הפעלה. איך אנחנו בעצם עובדים ישירות על המיקרו-קונטרולר ללא מערכת הפעלה, עבודה עם Interrupts בצורה ישירה, עבודה עם Buses (נדבר על ה-Buses עצמם גם בצורה של איך ה-Stack עובד מבחינת ה-MCU, ה-Call Stack - בעצם הקריאה והדחיפה של הפונקציות לתוך ה-Stack והפרמטרים עצמם).

דיברנו על הארכיטקטורה של מיקרו-בקרים, היו לנו הרבה מאוד שיעורים על הארכיטקטורה של Cortex-M. הארכיטקטורה של המיקרו-בקר שאני עובד איתו (ובכללי של הקורס) זה ARM Cortex-M. ARM Cortex-M4, ספציפית. אתם יכולים לבחור כל דבר, רק שימו לב שחלק מהפונקציונליות תהיה קצת שונה. ב-M4 יש לנו Floating Point Unit, יש לנו עוד כל מיני דברים שאין ב-M3, יש לנו גם Caching ועוד הרבה דברים. אז אם אנחנו מדברים על פיצ'רים כאלה, אלה דברים פחות רלוונטיים לדרייברים. אם אנחנו מדברים על פיצ'רים כאלה, אז תדעו שזה כאילו מגיע מכל מיני מקומות. ויש גם את M7, שזו הארכיטקטורה היותר חזקה של ARM. אז M, זה לדעתי Microcontroller, או סתם זה מתאים. זו הארכיטקטורה עצמה. יש ארכיטקטורות יותר מתקדמות של ARM, שזה A ולמיקרו-מעבדים וכולי וכולי, אבל M היא הבסיסית.

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

לקראת סוף הקורס התחלנו לדבר על Multitasking Implementation: אם אין לנו מערכת הפעלה, אז אנחנו צריכים לעשות אימפלמנטציה של Multitasking. איך אנחנו עושים Task Scheduling, Context Switching ו-Stack Organization - איך אנחנו מחלקים את ה-Stack לכמה אזורים.

בסוף שני דברים אחרונים: דיברנו על Real-time Design, דיברנו על עבודה עם Schedulers, עבודה עם Timer Configuration ואיך אנחנו יוצרים לעצמנו Task Scheduler כדי לעבוד איתו לבד. וגם יצאנו לדבר לא מעט על Optimization Techniques של הקומפיילר, Bit Manipulation, Memory Access Pattern וכל מה שעוזר לתוכנית שלנו להיות קלה ומהירה. אז זה הקורס של ה-Bare Metal.

## תכנון ה-API של הדרייבר

מה השלבים שאנחנו עושים כאשר אנחנו ניגשים ליצירה של דרייבר חדש?

הדבר הראשון: אנחנו צריכים ללמוד את ה-Peripheral Datasheet ו-Reference Manual. מה זה אומר? זה לא רק אומר ללמוד את ה-Datasheet של הרכיב שאנחנו רוצים להתחבר אליו או של התקשורת עצמה (אם אנחנו לדוגמה עובדים ב-I2C, אז לא ללמוד מה זה אומר I2C), זה ללכת ל-MCU שלנו וממש ללמוד את ה-Datasheet ואת ה-Reference Manual שלו.

אז בואו נפתח כבר את STM32Cube. ניפתח מכאן: STM32CubeIDE. לוקח לו זמן לעלות, ואז אנחנו בוחרים את התיקייה שאיתה אנחנו עובדים. פה יש לנו את ה-Repository Base Path שלנו, לפה עשינו את ה-Clone, ואז יש לנו את כל השיעורים. אנחנו בשיעור 0, שזה שיעור של Introduction. אם תסתכלו יש פה כמה דוגמאות. אתם יכולים לבחור מכאן Select Folder, ואז אנחנו עושים Launch. יש לנו את ה-STM32CubeIDE עצמו.

ברגע שפתחנו אותו אין לנו פה כלום. מה שאנחנו צריכים לעשות זה Import. Import, ואז אנחנו יכולים לבחור Existing Projects into Workspace או File System, ואז מכאן אנחנו בוחרים שוב את התיקייה שאנחנו בה, הוא מזהה לנו שני פרויקטים - אלה הפרויקטים שנעבוד איתם היום.

אבל מה שאני רציתי להראות לכם זה בכלל את זה: נראה איך אנחנו יוצרים פרויקט חדש. New -> STM32 Project. מפה יש לנו את האפשרות לבחור: או MCU/MPU (MCU זה Microcontroller Unit, MPU זה Microprocessor Unit), או את ה-Board עצמו.

כדי שיהיה לנו גישה לשני המסמכים העיקריים שאנחנו נעבוד איתם בקורס, שהם ה-Datasheet וה-Reference Manual, אנחנו צריכים לעבוד ישירות מול... אתם יכולים לקחת את המסמכים ישירות מכאן. לי בשמורים יש את ה-Boards שאני עובד איתם, אז יש לנו את שני ה-Nucleo אלה ואת ה-STM32F411RE MCU. ברגע שאני בוחר, מה שיותר מעניין זה ה-Datasheet וה-Resources. אז ה-Datasheet מעניין אותנו, והדבר השני שמעניין אותנו זה ה-Reference Manual.

בתוך ה-Reference Manual ובתוך ה-Datasheet עצמו יש לנו את כל מה שאנחנו צריכים כדי לעשות את האנליזה ל-MCU שלנו. אז יש לנו את היכולות, יש לנו בהמשך את ה-Pin Configuration. טוב, זה ה-How-to, מה הפין שיוצא מאיפה, מאיפה יוצא מה הפין שיוצא, לפי כל חתימה. אבל יותר מעניין אותנו טבלת הפינים: איך אנחנו מקנפגים, כל אחד מהם, ואת זה אנחנו נדבר על זה יותר בשיעור הבא, מה יוצא מאיפה.

מהצד הזה יש לנו גם את ה-Reference Manual, שזה היכולות עצמן. אז לא רק היכולות, זה גם איך אנחנו פונים לאיזה כתובת בזיכרון. אז יש לנו את ה-Memory Map לכל שכבה, יש לה את הכתובת בסיס שלה. אחר כך יש לנו את הפריפריאל עצמו, זה ה-RCC, זה ה-Clock Configuration, יש לנו את ה-GPIO Ports, פריפריאלים של SPI, טיימרים, EXTI (שנדבר על זה היום, שזה ה-Interrupts), חלק מה-Interrupts, ה-Interrupts של ה-Manufacturer הספציפי, SDIO/SDIO Standard Data Input/Output, Analog Digital Converters, UARTים, PWR (שזה Power, יש גם PWM שזה גל קבוע), ובזה בעצם כל הפריפריאלים עצמם. כאשר אנחנו נצטרך לעבוד איתם, אנחנו גם נצטרך להכיר אותם. אם אנחנו רוצים דוגמה, אז יש לנו את ה-GPIOs עצמם, זה Section 8.

יש לנו כמה GPIOs שאנחנו יכולים לעבוד, מה ה-Operating State שלנו: Push-pull, אנחנו נדבר על הכל, Open Drain (שזו עוד צורה לעבוד), ו-Pull-up/Pull-down (שזו עוד שתי צורות לעבוד עם GPIOs), Speed Selection, States, Blocking Mode, Locking, Analog Function, Alternate Functions, שעל זה אנחנו נוכל לעבוד בהמשך. ובכללי, כל המידע עצמו וגם הארכיטקטורה. בעצם לזה אנחנו נגיע גם כאשר נעבוד על GPIOs. אז כל אחד מהם, ככל שנתחיל להכיר, נתחיל לצלול יותר לכל אחד מהחלקים אלה בתוך ה-Reference Manual. ה-Reference Manual זה המסמך הגדול ביותר שמסביר לנו את ה-MCU.

בנוסף, יש לנו את הסכמה החשמלית. ואני מניח שלא תמיד תעבדו עם Breakout Board או עם איזשהו Board כזה, אבל רק בשביל ההתחלה של ההבנה, אנחנו נעבוד עם... שוב אני פותח את ה-Repository. שוב אנחנו נעבוד עם Driver Development, אז יש לנו ב-Docs את הסכמה החשמלית. היום, כשאנחנו ניגע ב-PA0 שזה הכפתור, אנחנו נקנפג אותו, זה ה-PA0. זה הכפתור ונקנפג אותו, אז אנחנו גם קצת נסתכל על הסכמה.

אז אלה הדברים שצריך להתחיל להכיר. צריך לאפיין מה הצרכים שלנו מבחינת הריגסטרים שאנחנו רוצים לעבוד איתם בתוך ה-Reference Manual ומה הפונקציונליות. נרצה להבין, וזה עדיין בשלב של ה-Hardware Analysis: Timing Requirements ו-Constraints - אם יש לנו איזשהן התנגשויות וזה, נתחיל למפות את ה-Pin Assignment ואת ה-Alternate Functions של כל אחד.

היום אנחנו נסתכל על איזשהו EXTI0 של PA0 ונבין למה אנחנו נרצה לשים ולכוון אליו את הפונקציה עם ה-Priority הגבוה ביותר שלה. זה PA0 או PB0, כל אלה שהם על אינדקס 0 על הפורט שלהם. A, B, C, D עד H זה הפורטים שה-MCU מאפשר לנו, ככה שאפשר לשלוט על 16 GPIOs בבת אחת. אז כל אינדקס שלהם הוא ממופה ל-Interrupt, נגיע לזה.

ואז אנחנו בעצם רוצים לעבוד עם ה-Driver Architecture. אז איך אנחנו? נתחיל ביצירה של Header File, אתם תעשו את זה גם בשיעורי הבית, עם Function Prototypes. בעצם נתכנן את ה-API שהדרייבר עובד איתו. אם אנחנו כבר עובדים בחברה ויש איזשהו סגנון שעובדים איתו, אז אנחנו לא נצטרך להתחיל לחשב את הכל מאפס. אבל אם זה משהו שאנחנו עושים, אנחנו נחשוב איך אנחנו רוצים לעבוד עם ה-API בצורה הכי טובה. עושים את זה כותבים גם ספריות, ודרייבר הרבה פעמים זה ספרייה.

נתכנן את ה-Data Structures שאנחנו הולכים לעבוד, את הקונפיגורציה, אם אנחנו עובדים ב-C++ אז Class, אם אנחנו עובדים ב-C אז איזשהו Structure. אם אנחנו רוצים לעשות את זה בצורה דינמית, נצרף אליו Circular Buffers. אלה דרכים שאפשר לעבוד. נייצר Error Codes ו-Return Types שאנחנו מחזירים מכל אחד מהפונקציות.

לאחר מכן נעשה את האימפלמנטציה של הקוד Core Functions עצמם: איך אנחנו כותבים את ה-Init ואת ה-DeInit, את האימפלמנטציה של ה-Read וה-Write Operations או עוד Configuration ועוד Control Functions שאנחנו צריכים, ואיך אנחנו עושים Handle ל-Error Conditions ו-Edge Cases. לדוגמה: יכול להיות שאני עכשיו שולח ועוד אחד שולח בו-זמנית, אז יש לנו Collision, אז איך אנחנו מתמודדים עם זה. זה בסדר שזה לא היה ברור, זה רלוונטי ל-RS-485. יכול להיות שזה לא היה רלוונטי להכל, גם לא צריכים להכיר את הכל מהתחלה.

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

בסוף, איך אנחנו הולכים לבדוק את זה? יוצרים Test Cases של דרייברים, מוודאים שה-Timing Requirements וה-Performance באמת עובדים, ועושים Test Error כדי לסמלץ את ה-Error ולראות אם אנחנו, אם עשינו אימפלמנטציה של Recovery Mechanism, לראות שזה גם עובד. ואת כל זה אנחנו דוחפים בצורה יפה במסמך, שזה מאוד חשוב גם אם אנחנו עושים את זה כפרויקט - מסמך שמסביר לנו את הדוגמאות ואת ה-Limitations. שום חומרה היא לא אידיאלית, זה בסדר, יש מסמכים עצומים שנקראים Errata (או Errata), שמהם המסמכים של כל התקלות הידועות של דרייברים או של MCUs בפרט.

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

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

יש לנו איזשהו Interface קונסיסטנטי: אם אנחנו מימשנו System Calls, אז אנחנו עובדים עם System Calls בצורה הזאת. אבל במיקרו-קונטרולרים אין לנו את כל המקום ל-Overhead הזה, אז אנחנו עובדים עם איזשהו Standard API שאיננו משאירים אותו קבוע לכל ה-Hardware Implementations.

Error Handling: בעצם איך אנחנו מנהלים Error Codes ואיך אנחנו מנהלים Fault Condition, איך אנחנו יודעים מתי לא הצליחה לנו טרנזקציה וכולי.

Resource Management: איך אנחנו מתחילים ודי-מתחילים פריפריאלים בצורה טובה מספיק.

עוד דבר אחד שאנחנו עושים ברמת הדרייבר, זה Performance Optimization: ככה שאנחנו יכולים לעשות Buffering, Caching ועוד.

דוגמה ל-API של תקשורת (למשל RS-485):

קובץ ה-Header הזה הוא מה שיחשף לכל User שישתמש ב-Include הזה:

פונקציית `Init` (שתחזיר לו את ה-Struct), פונקציית `DeInit` (שזה ה-Destructor), פונקציית `Transmit` (שליחה על הקווים), `Receive`, ו-`SetMode`.

```c

// Example RS485 Driver API

typedef enum {

RS485_OK = 0,

RS485_ERROR,

RS485_BUSY,

RS485_TIMEOUT

} RS485_Status_t;

RS485_Status_t RS485_Init(RS485_Config_t *config);

RS485_Status_t RS485_DeInit(void);

RS485_Status_t RS485_Transmit(uint8_t *data, uint16_t length);

RS485_Status_t RS485_Receive(uint8_t *data, uint16_t length);

RS485_Status_t RS485_SetMode(RS485_Mode_t mode);

bool RS485_IsBusy(void);

```

זה בעצם מה שמגיע אל ה-User, ובמקרה הזה גם ה-Structure הזה. למה ה-Structure הזה גם כן? כי הרבה פעמים ה-User (המשתמש הבא, ה-User שלנו יכול להיות גם המתכנת של רמת האפליקציה, או שזה יכול להיות גם אנחנו) רואה מה צריך להגדיר: Baud Rate, צורה של הדאטה וכולי.

## שיקולים בבחירת רכיבים ואינטגרציה ל-MCU

איך אנחנו בוחרים רכיבים שיתאימו ל-MCU שלנו?

1. **Electrical Compatibility:**

* רמות מתחים (Voltage Levels): 3.3V vs 5V (או 1.8V). אם המיקרו-בקר עובד ב-3.3V והרכיב ב-5V, צריך לוודא compatibility או להשתמש ב-Level Shifter.

* צריכת זרם (Current Consumption): לוודא שהבקר מסוגל לספק את הזרם הנדרש על ידי הרכיב.

2. **Communication Interfaces:**

* זמינות פריפריאלים ב-MCU (I2C, SPI, UART). I2C מתאים לחיבור מספר רכיבים על אותו בוס, SPI מהיר יותר.

3. **Timing & Real-Time Requirements:**

* קצב העברת נתונים (Throughput), השהיות (Latency), צורך ב-DMA לעבודה ברקע ללא עומס על ה-CPU.

4. **Power Management:**

* זמן עלייה (Startup / Wake-up Time) ממצבי שינה (Sleep / Low Power Modes).

5. **Software Support:**

* זמינות דרייברים קיימים, דוקומנטציה, וקהילה.

## ארכיטקטורת האפיקים (AHB / APB) ורישום RCC

כאשר אנחנו מסתכלים על ה-Block Diagram של ה-MCU ב-Reference Manual, אנחנו רואים את ארכיטקטורת ה-Buses (האפיקים):

- **AHB (Advanced High-performance Bus):** אפיק מהיר המיועד לרכיבים שמחייבים רוחב פס גבוה - CPU, Flash, RAM, DMA, ו-GPIOs מהירים. על STM32F411 ה-AHB עובד בתדר גבוה (עד 100MHz).

- **APB (Advanced Peripheral Bus):** אפיק איטי יותר המיועד לפריפריאלים רגילים.

- **APB1:** Low-speed peripheral bus (עד 50MHz) - מכיל I2C, UART/USART, Timers.

- **APB2:** High-speed peripheral bus (עד 100MHz) - מכיל SPI מהיר, ADC, EXTI, USARTs מהירים.

**חשיבות ה-RCC (Reset and Clock Control):**

לפני שנפנה לרישומים (Registers) של פריפריאל כלשהו (למשל GPIOA או I2C1), **חובה להפעיל את ה-Clock שלו** דרך ה-RCC.

לדוגמה, להפעלת GPIOA, נגשת לרישום `RCC->AHB1ENR` ונרים את הביט המתאים (`RCC_AHB1ENR_GPIOAEN`). ללא הפעלת השעון ב-RCC, כל פנייה לרישומי הפריפריאל תגרום לסטייה/נפילה (Bus Fault) או שהשינויים לא יישמרו.

## סיכום והנחיות למטלות

היום עברנו על מבוא לדרייברים, הארכיטקטורה של ה-MCU, חלוקת ה-Buses, והתחלת העבודה מול ה-Reference Manual וה-Datasheet.

**הנחיות למטלות הבית:**

1. **Assignment 1 / 2:** בחרו רכיב תקשורת או פריפריאל (למשל I2C Sensor, SPI Display, UART Module), ותכננו עבורו את קובץ ה-Header (`.h`) עם הגדרת ה-API (פונקציות `Init`, `Read`, `Write`, `DeInit`, מבני נתונים `struct` וקודי שגיאה `enum`).

2. **Assignment 3:** בחרו רכיב חומרה ובדקו אינטגרציה מול STM32 - תאימות מתחים, בוס תקשורת נדרש, צריכת זרם ודרישות תזמון.

בשבוע הבא נמשיך לעומק לתוך GPIO Deep Dive, קינפוג הרישומים, וטיפול ב-Interrupts ו-EXTI.

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

...מי זה startup time, מה הזמן שאנחנו נותנים להם power עד שאפשר להתחיל לעבוד, עד שהם מתחילים להיות operation. אז זה דברים שצריך להתחשב בהם.

אם אנחנו במערכות low power – אנחנו נדבר הרבה על מערכות low power בקורס הזה – אם אנחנו במערכות low power, אני לא צריך להשאיר כל דבר לנצח דולק, אז אני מכבה רכיבים ומדליק אותם כשאני רוצה לעבוד. ואז יש לי את ה... את ה-power, את ה-wake-up time, את ה-startup time ואת ה-wake-up time.

אז זה בעצם שני מושגים שאני צריך להתחשב בהם. ובסוף, אם יש לי מספיק דוקומנטציה שאני יכול לעבוד איתה, לא אומרים לי רק "זה רכיב שיודע לעבוד עם I2C", גם אומרים לי מה ההודעות שהוא צריך לקבל ומה הוא מחזיר. סבבה. ואם יש community support של ה... support של איזושהי קהילה שנמצאת מאחורי הרכיב. אם זה רכיבים של Arduino, אז זה עוזר לנו, רכיבים של... של כל מיני חברות.

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

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

שוב, שאלות על איך אני בוחר components, איך אני בוחר רכיבים או דרייברים?

## תכנון אינטגרציה

אז איך אני בעצם מתכנן את האינטגרציה? קודם כול עובר על ה-MCU שלי, על ה-datasheet ועל הפריפריאלים, ומתחיל לעשות איזשהו תכנון של pin assignment. הפין הזה יהיה I2C event, הפין הזה יהיה whatever, SDA, clock – בהנחה שגם הקלוקים עובדים.

אחר כך אני בעצם עושה את ה... אחר כך אני גם עושה את הווידוא של ה... של הרכיבים, שהם תואמים מבחינה חשמלית, מבחינת כל מה שאמרנו. עושה אנליזה של ה-wake-up time, מחשב כמה זמן המערכת צריכה להיות למעלה וכמה זמן זה יקח לי מבחינת... כמה אנרגיה זה יקח לי. מתכנן תמיד ל-worst case, ואז מגלה שהוא יכול להיות גרוע יותר בשביל low-power applications. ובסוף אני מתחשב ב-initialization sequences ו-dependencies של מערכות אחרות. לדוגמה, מודם, אם אני צריך להתחל בשבילו איזשהו מגנט כדי שהוא יוכל להעביר לו קווים ו-whatever.

ואז אנחנו עושים את ה-pin assignment, ואנחנו מתכננים את כל ה-alternate functions ואם יש קונפליקטים.

ובסוף אנחנו עושים איזשהו תכנון של ה-usage, כולל איזה זיכרון אנחנו צריכים לכל פריפריאלים, CPU ו-power consumption. זה מה שאנחנו עושים בשביל אינטגרציה.

## הכנה לאינטגרציה

אז איך אנחנו מתכוננים לקראת אינטגרציה? כבר... בואו נדבר מבחינת סנריו. חשבנו על רכיבים, מצאנו אותם, חשבנו על ה-pin assignment. הפין PA0 הולך להיות זה, PD7 הולך להיות I2C, יש לנו PA8 הולך להיות לנו ה-Analog to Digital Converter, אוקיי?

אחרי כל זה, אנחנו צריכים להתחיל להתחשב באיך... אנחנו צריכים להתחיל להתכונן לאינטגרציה. מה אנחנו עושים?

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

אז hardware preparation, עבודה עם צב"דים לבדוק שהכול עובד. לוודא שבאמת הסיגנלים שאנחנו שולחים ומקבלים מובנים באוסצילוסקופ. סקופ, אמרנו, אוסצילוסקופ זה סקופ. סקופ זה ציוד בדיקה שמדפיס לנו מתח ביחס לזמן. אז אם אני עושה אותו על 5 שניות, אנחנו נראה אותו לאט-לאט ממלא את המסך, או 1 מילי-שנייה ואז הכול רץ מהר. אוקיי? ככה אנחנו בעצם בודקים את הציודים שלצידנו.

אחר כך בודקים שהסביבה שלנו עובדת, שה-debugger שלנו עובד, ה-version control של המערכת שלנו, הכול מוכן, ועושים דוקומנטציה. ל-integration plan, חשוב לעשות integration plan. אם אנחנו מתכננים את האינטגרציה, אנחנו ממש יכולים להתחיל לעשות checking לכל החלקים ולא להתחיל להסתבך עם דברים.

ו-driver development: ללמוד את ה-Peripheral Reference Manual, ראינו אותו כאן, נדבר עליו עוד רגע. לעשות אימפלמנטציה של דרייברים ספציפיים, בסיסיים, ובסוף גם לתכנן את ה-API כמו שאמרנו, ולעשות usage examples, דוגמה בשבילנו.

זה ככה אנחנו מתכוננים לאינטגרציה.

פה סיימנו את החלק של האינטגרציה ושל הדרייברים. שאלות על הנושאים האלה?

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

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

מקווה שהצליח לכם להוריד את ה-Reference Manual עצמו. אז יש לנו את המסמך הזה שנקרא ST Reference Manual. יש את המספר הזה כאן, אפשר לחפש אותו פה. הוא נמצא גם בתוך ה... יש פה לינק. אם תלחצו על הלינק הזה, אתם תמצאו את ה-Reference Manual הזה הספציפי. זה מדריך לתכנות על ה... על ה-CPU עצמו, על ה-MCU עצמו. אנחנו נעבוד איתו, אבל יותר מעניין ה-Reference Manual.

לפני ה-Reference Manual, אני רק אראה את מה שהראיתי לכם לפני שנייה. ה-table עצמו... איך אני אגיע לזה מהר?

אגב, בתוך ה-datasheet עצמו, אתם יכולים לראות את כל העבודה. כמה I2C, כמה SPI יש לנו, כמה I2C אנחנו יכולים לעבוד איתם, USART-ים או UART שזה... בצורה לעבוד סינכרונית עם UART, אנחנו גם כן נדבר על זה. כמה RAM וזיכרון יש לנו, מה המתחי עבודה שאנחנו יכולים לעבוד עם ה-MCU שלנו, אם אנחנו רוצים לעבוד עם 1.7V. צריך גם לדעת שאם אנחנו עובדים עם 1.7V, אז גם ה-GPIO-ים שלנו יכולים להיות 1.7V, עד 3.3V וכו' וכו' וכו'. כל זה אפשר להכיר מכאן.

כרגע מה שמעניין אותנו זה להסתכל על ה-peripheral architecture, איפה זה?

הנה, זה ה-block diagram של ה-MCU שלנו, או של כל MCU. לכל MCU יש כזה דבר.

## ממשקי באס ב-MCU

ול-MCU יש לנו כמה באסים. מה זה באס? באס, אתם יכולים לחשוב עליו כעל קו – זה לא בדיוק קו במקרה הזה – כעל קו שמבוסס בין כמה רכיבים, קווי תקשורת שמבוססים בין כמה רכיבים, וכולם יכולים לנגשת למיידע של כולם.

אז יש לנו כמה באסים ספציפיים שאנחנו עובדים איתם ספציפית ב-MCU הזה. יש לנו את ה-AHB, שזה Advanced High-performance Bus. זה נותן לנו גישה, זה נותן ל-CPU גישה לכל מיני פריפריאלים... שנייה, אני אישרר את זה.

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

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

אז יש לנו שני באסים שהם מהירים, ואנחנו יכולים לראות לאן הם מגיעים. אז יש לנו את AHB1 ו-AHB2. סבבה? הם בדרך כלל שולטים... הם מגיעים מה-CPU אל ה-DMA. דיברנו על DMA. DMA זה ה-coprocessor המהיר שלנו, שהוא עושה לנו העתקות וכתיבות בצורה מהירה בחומרה. אז ה-DMA צריך הרבה רוחב פס.

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

מה עוד יש לנו? יש לנו את ה-SRAM, זה הזיכרון עצמו. הזיכרון עצמו הוא מגיע ישירות לבאס מטריקס, לטבלה שמקשרת בין הבאסים. ויש לנו את ה-USB. ה-USB זה גם תקשורת עם הרבה רוחב פס, אז היא מחוברת ל-AHB2. אז AHB, Advanced High-performance Bus זה AHB.

המילה הסטנדרטית, בעצם ה-memory alignment הבסיסי של ה-MCU שלנו הוא 32 ביט. בגלל זה זה STM32. והצורה שאנחנו עובדים עם הבאסים, אז הם בעצם מחולקים למילים ברוחב 32, שכל... בעצם אמרנו, כל סייקל מתעדכנות.

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

אז ה-Flash מחובר, ה-SRAM, ה-DMA וה-High-speed GPIO, ה-GPIO המהירים, כולם מחוברים ב-AHB1.

יש לנו באס נוסף... רגע, שנייה. אם אני ארצה לעבוד עם כל אחד מהרכיבים האלה, אני צריך לאתחל... לאתחל אותו ברמת הבאס. אז יש לנו איזשהו רכיב שנקרא RCC, Clock Configuration משהו, שבו אני מאפשר את השעון לכל אחד מה-GPIO-ים, ל-DMA, לעוד רכיבים. ברגע שאני מאתחל אותו, אז הם עובדים עם הבאס, וכאשר אני ניגש אליהם מתתוך הבאס... אז אם אני רוצה לעבוד עם כל אחד מהרכיבים האלה, GPIO-ים, DMA, SRAM או Flash, אז אני צריך לאתחל בתוך AHB1 את השעון שלהם. סבבה.

אחר כך יש לנו עוד באס שהוא פחות מהיר, שהוא נקרא Advanced Peripheral Bus, APB. ואנחנו רואים שהוא מחובר על ה-AHB, הוא בלבן.

אז הבאס הזה, המהירות שלו נמוכה יותר, למרות שפה רשום לנו 100 MHz, אבל APB1 עובד על 50 MHz. המהירות יותר נמוכה, הוא בשביל פריפריאלים שהם יותר איטיים, לדוגמה I2C פחות מהיר, UART שהמהירות שלהם היא לא הכי גבוהה שיש, שעונים, טיימרים, דברים שצריכים פחות רוחב פס, פחות data.

אז אנחנו נעבוד איתם. APB1 הוא ה-low-speed, אנחנו גם רואים שהמקסימום שלו הוא פחות, 50 MHz. אפשר לעבוד איתו, יש לו UART, יש לו I2C, יש לו את כל הרכיבים שרואים שמחוברים כאן: Power Interface, ה-Real-Time Clock שאנחנו יכולים לעבוד איתו, זה הרכיב הזה וכולי. זה ה-APB.

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

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

יש לנו גם bus arbitration, שהבאס יכול לעבוד עם כמה רמות של priority לפי מה שאנחנו רוצים שיעבוד קודם. אז אלה ה-bus interfaces.

## עבודה עם רגיסטרים של RCC

זאת הסכמה, היא נמצאת בתוך ה-datasheet. אבל כאשר אנחנו עובדים עם הבאס עצמו, אנחנו נלך ל-Reference Manual. מתוך ה-Reference Manual יש לנו את ה-Reset and Clock Control, זה מה שאמרתי מקודם, RCC.

ה-RCC עצמו מסביר לנו על מה השליטה: הוא שולט על ה-reset, שולט על ה-watchdog, ויש לו גם שליטה על low power, נגיע ל-low power עצמו. מה שאותנו מעניין זה השליטה על השעונים והאתחול. זה ה-clock tree עצמו.

יש לנו Control Clock Register, הוא בעצם אחראי על כמה חלוקות של שעונים, איך אנחנו באמצעות קובעים את השעון, פחות קריטי לנו כרגע. מה שיותר מעניין אותנו כרגע זה ה-Clock Enable Registers. יש את ה-Reset Registers, ככה אני יכול לאתחל את השעון או לאתחל את הפריפריאלים שנמצאים. אלה ה-Enable Registers.

אם אני רוצה לעבוד עם GPIOA, אני צריך לשים ברגיסטר הזה, שנמצא באופסט 0x30 מה-RCC (שזאת הכתובת שראינו שם), אני צריך לשים פה 1. זה 32-bit. ה-32-bit register הזה הוא גם כן ממופה לבאס.

על ה-32-bit הזה אני שולט, ואני יכול להחליט איזה GPIO יעבוד: GPIOA enable, B, C, D, E. ברגע שאני אשים פה 1, אז port A הוא הפורט שפעיל.

בתוך ה-MCU שלנו יש לנו כמה פורטים ל-GPIO-ים. ה-GPIO-ים עצמם מחוברים כ-port כדי שיהיה אפשר לשלוט על כולם בבת אחת. ברגע שאני עושה port A enable, אז כל אלה יכולים לעבוד. אני יכול לעבוד עם כל A, E וכולי. אז אלה ה-RCC.

## מטלות הקורס ופרויקטים

בשיעור הבא נדבר על אינטראפטים, שזה נושא שאפשר לדבר עליו כבר אחרי GPIO, ונעשה את הדוגמה.

לגבי ה-Course Assignments: יש לכם את ה-assignments שכתבתי. את assignment 1 אתם לא יכולים לעשות עדיין, אבל את assignment 2 אתם כן יכולים לעשות. ב-assignment 2 תאחדו לכם איזשהו driver או תקשורת כלשהי ותתכננו לה API. אחר כך תתכננו איך אתם הולכים לתקשר איתה, תכתבו את ה-header file, ותכינו את ה-design principles. תעבדו ממש לפי המדריך הזה.

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

אתם יכולים לעשות גם את assignment 3. אני אשלח לכם קישור של כל ה-boards שאנחנו יכולים לתמוך בהם. אתם יכולים לבחור אחד. לדוגמה, אני בחרתי את STM32F411, Nucleo לדוגמה, הנה זה האתר של ST. פה אתם יכולים לבחור איזשהו board שמתאים לכם מתוך ה-product catalog.

תבחרו איזשהו רכיב, קחו את ה-datasheet שלו. הראיתי איך: New -> Project, ואז תבחרו את ה-board שאתם רוצים או את ה-MCU אם אתם רוצים ישירות, ותתכננו איך אתם עושים אינטגרציה ל-MCU שבחרתם.

אני אתן לכם רשימה של כאלה שאני ממליץ, אבל בסופו של דבר אתם צריכים לדעת לקחת איזשהו board, להגיד: יש לו את היכולות האלה, יש לו את ה-pinout הזה, זה עוזר לי, ותוכלו לבחור רכיב.

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

תחפשו רכיבים, תחפשו part numbers. אתם יכולים ממש לחפש אותם באתרים של DigiKey או Mouser, רק לדוגמה. אחרי זה אפשר לקנות ב-AliExpress, ב-Amazon, או בספקים בארץ.

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

בקיצור, תכתבו פסקאות ב-Google Drive. רשמתי לכם איך אתם הולכים לעשות את זה: power requirements, כל הדברים שרשומים כאן, תעברו על זה. אין דברים לא נכונים. אם לא תרשמו משהו כי תפחדו שמישהו יראה את זה, אתם סתם תפספסו. אני גם אעשה כאלה כדי שנוכל להציג בשיעור הבא, ובשיעור הבא נעשה review על כל הדברים האלה.

אתם יכולים לעשות את 2 ו-3, שיעור הבא תוכלו לעשות גם את 1. זה ה-Course Repository ויש לכם פה את הכל.

## שאלות ותשובות: תכנון API של Driver

**סטודנט:** שאלה לגבי הפונקציות של ה-driver API. אם עכשיו אני בוחר פרוטוקול תקשורת שונה לעשות לו את ה-API, המבנה הוא אותו מבנה?

**מרצה:** את ה-init אתה חייב לעשות, אתה יכול לקרוא לזה בשם אחר. deinit אתה גם חייב לעשות. ואז יש לך לפי הצרכים שלך. אם אתה רוצה לעשות driver ל-GPIO, אז מה זה transmit? זה לא רלוונטי, נכון?

אז זה פשוט לפי ה-API הזה. אבל אם אתה עושה תקשורת, עדיף לשמור על איזשהו מנגנון שאתה הולך לעבוד איתו, על משהו קבוע. אם אתה הולך לקבל data כ-buffer, אז תמיד שיהיה data כ-buffer. אם אתה הולך לקבל אותו כ-struct בגודל קבוע, אז תמיד שיהיה בגודל קבוע. תשחקו עם זה.

עבודה עם function pointers מוסיפה לנו קצת גמישות ונוחות. קצת פחות נוח ל-debugging, אבל יש גמישות מבחינת עבודה.

## פרויקטים בקורס וסיכום השיעור

לגבי הפרויקטים: או שאתם בוחרים רכיבים שלכם, מזמינים אותם ועושים אימפלמנטציה כמו בעולם האמיתי. אתם יכולים לחשוב על איזשהו real-world application, למשל מד גובה, מד דלת, ספירת אנשים, תחשבו על מה שבא לכם. LCD שאתם רוצים לעבוד איתו. יש הרבה רכיבים, תתפרעו. פחות הייתי ממליץ לעבוד עם BLE וכל מיני stacks שצריך לממש, שזה קצת יותר רציני, אלא דברים שנחמדים ושקל לעבוד איתם כדי שנוכל לסיים את הפרויקטים בזמן.

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

אני אור פוקס, זה המייל שלי. מדי פעם תראו אור סולימני או אור פוקס – שניהם זה אני.

אנחנו נפגשים בשיעור הבא בשבוע הבא. רק הערה: אשתי בחודש מתקדם, אז יכול להיות שאהיה איתה בבית חולים והשיעור שלנו יידחה בשבוע.

**סטודנט:** אור, יש אפשרות לדבר איתך ב-4 עיניים?

**מרצה:** כן בטח.

**סטודנט:** נראה לי שגם גבי ירצה להישאר איתנו, דיברתי איתו והוא גם באותו עניין.

**סטודנט 2:** כן, אני גם נראה לי אשאר.

**מרצה:** אוקיי, אז מי שלא רוצה להישאר יכול ללכת, ואנחנו נישאר.