מבוא

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

הבנת דפוס ה- Singleton במערכות Embedded

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

  • (ב) ,0) בקרים/המרכזים (UART) 1 (ב) 1 (רק מקרה אחד צריך לנהל את השידור ולקבל מטאטאים).
  • (FLT:0)Digital Converter (Analog-to-Digital Converter) נהגים 1Figital Reve: 1LT - לקוחות רבים צריכים לקרוא את אותם תוצאות ההמרה ללא שכפול.
  • (ב) ,0) מודולים ניהול כוח: 1 (FLT:1) - נקודת החלטה אחת להיכנס לישון או למצבים פעילים.
  • שעון אמת-זמן (RTC) גישה ל- 1R, מקור שעון יחיד צריך להיות מסונכרן על ידי כל המשימות.
  • (ב) ⁇ :0) תזמון טימסק 1 במערכות חשוף-מטאליות - לולאה אחת או מפריעה למטפלים שולחים את כל המשימות השיתופיות.

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

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

הפרקטיקה הטובה ביותר ליישום

השתמש ב-Lazyization עם מודעות כוח

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

(ב) ⁇ (ב) ⁇ ⁇ ⁇ ⁇

// uart_driver.h
typedef struct {
 volatile uint32_t *base_addr;
 // ... other fields
} UART_HandleTypeDef;

UART_HandleTypeDef* UART_GetInstance(void);

// uart_driver.c
#include "uart_driver.h"
#include "chip_peripherals.h"

UART_HandleTypeDef* UART_GetInstance(void) {
 static UART_HandleTypeDef instance;
 static int initialized = 0;
 if (!initialized) {
 instance.base_addr = (uint32_t*)UART1_BASE;
 // Perform peripheral-specific configuration
 UART_Configure(instance.base_addr);
 initialized = 1;
 }
 return &instance;
}

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

ההתחלתיזציה Lazy מאפשרת גם את המערכת המוטבעת כדי להדוף כוח-hungry peripheral כוח-up עד הכרחי לחלוטין.אם ה- Singleton מנהל מכשיר קבוע גבוה (למשל, מהפך GSM או Wi-Fi מודול), יצירת המקרה מאוחר יותר מפחית את צריכת החשמל הממוצעת.עם זאת, להיות זהיר: אם הליטטון שנוצר באופן עצלן הוא גישה בתוך שירות שגרתי הדורש תזמון, במקרה ראשוני, עשוי להיות זהיר יותר (למשל, במקרה של מערכת הפעלה) מוקדם יותר).

(ב) [ה]] [ה]] [ה]] [ה]] [ה]] [ב]]] [ה]]]], [ה] [ה]]]ה'[ב]]'[ה]'[ה]'[ה]'[ה']'[ה']'[ה']']'[ה']']'''[ה'[ה']']''[ה']'''''[ה']']'[ה'[ה'[ה'[ה']'[ה']']']']'[ה'[ה'[ה'[ה']']']'[ה']']'[ה'[ה']'[ה']']'[ה']']'[ה'[ה']']'[ה']']'[ה']']'[ה'[ה']']'[ה'[ה'[ה']']']'[ה']']'[ב'[ה']'[ה'[ה

2.הבטח את בטיחות הקישור עבור Multi-Tasking ו Interrupts

מערכות Embedded לעתים קרובות לערבב לולאה מרכזית, שגרה של שירות מפריע (ISRs), ולפעמים RTOS (מערכת הפעלה בזמן אמת) כאשר Singleton הוא גישה מהקשרים מרובים, תנאי גזע יכולים להשחית את המדינה שלו - במיוחד במהלך הסימולציות העצלן.ה: שתי משימות קוראות FLT:1 בו זמנית, הן רואות FLT:2, והן לנסות להגדיר את החומרה, גורם כפול או נתונים ראשוניים או ראשונית.

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

  • (FLT:0 interrupts לא יכול להשתמש לחסום mutexesFLT) 1:1 - mutex אשר עשוי להניב CPU יגרום למלכוד אם נקרא מ ISR. במקום זאת, להשתמש בסעיפים קריטיים (הפרעות בלתי צפויות באזור הקריטי) או פעולות אטומיות ללא מנעול.
  • (FLT:0)RTOS משימות ⁇ FLT:1 - השתמש ב- mutex או Smaphore כדי לשמור על הגישה של Singleton.אם RTOS תומך בעדיפות עליונה ירושה, השתמש בו כדי למנוע עדיפות הסגירה.
  • (FLT:0)Bare-metal עם תזמון שיתופי פעולה תזמון FIRLT:1), אם הטון רק נגיש מהלאה העיקרית, אין צורך בהגנה נוספת, אך ודא כי ISRs לעולם לא קוראים ל- Singleton ישירות.

שם הסרטון:0.10.Example: Zu-Safe Singleton with CMSIS-RTOS mutexcioFLT 1

#include "cmsis_os2.h"
#include "singleton.h"

static GPIO_TypeDef* instance = NULL;
static osMutexId_t mutex_id;

void Singleton_Init(void) {
 mutex_id = osMutexNew(NULL);
}

GPIO_TypeDef* Singleton_GetInstance(void) {
 osMutexAcquire(mutex_id, osWaitForever);
 if (instance == NULL) {
 instance = (GPIO_TypeDef*)GPIOA_BASE;
 GPIO_ConfigureInstance(instance);
 }
 osMutexRelease(mutex_id);
 return instance;
}

ב-ISR, גישה בטוחה יותר היא להשתמש בפעולות אטומיות (למשל, FLT:4 ב- GCC) או מכונה ללא מנעול המדינה.

(ב) ,0) ↑ ,2CMSIS) , סמך ה-ARM CMSIS מספק הנחיות לפריפריה בטוחה חוטית:2CMSIS-Core (ARM) בטיחות חוטים 3LT 3.

שמור על משקל האור הבודדטון - לא Heap, No Complexors

מערכות Embedded לעתים קרובות יש זיכרון מוגבל, פרויקטים קריטיים רבים אוסרים הקצאה דינמי לחלוטין (MISRA-C: 2012 כלל 21.3) לכן, Singletons צריך להיות מוקצה סטטי או להציב באזורי זיכרון ייעודיים. להימנע משימוש ב-FLT:5 או FLT:6, כמו פיצול ושגיאות מחוץ לזיכרון יכול להוביל לכשלים קשים כדי למצוא.

הזינוק של הטון צריך להיות מינימלי:

  • לאחסן כתובת בסיס או לטפל של הפריפריה.
  • הגדר פרמטרים של ברירת מחדל (למשל, קצב הבנד, מפיץ השעון).
  • אל תתחילי לפריפריה שצריכה כוח עד שלקוח קורא במפורש פעולה (למשל, FLT 7).

ב C++, אתה יכול ליישם את הטון של מאייר באמצעות משתנה מקומי סטטי, אשר מובטח להיווצר בדיוק פעם אחת (C++11 ולאחר מכן להבטיח היערכות בטוחה חוט בטוח) עם זאת, להיות מודע לכך שההוראה עשוי לא להיקרא אם המערכת משתמשת aFLT:8), ואת סדר ההקצאה סטטית על פני יחידות התרגום יכול להיות מסובך.

(ב) ⁇ (ב) ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇

class UART {
public:
 static UART& getInstance() {
 static UART instance; // C++11 thread-safe by default
 return instance;
 }
private:
 UART() {
 // lightweight – only store address, no peripheral init
 base_ = (uint32_t*)UART1_BASE;
 }
 uint32_t* base_;
};

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

להימנע מתלויים מעגליים ומסגורים

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

לדוגמה, במקום:

void Sensor_Task(void) {
 UART_Transmit(UART_GetInstance(), "Hello");
}

המונחים:

void Sensor_Task(UART_HandleTypeDef* uart) {
 UART_Transmit(uart, "Hello");
}

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

מלכודות נפוצות להימנע

המדינה העולמית Overuse

יותר מדי על סינגלים לעתים קרובות מוביל לתלויים נסתרים המסבך את בדיקות יחידה ואת יכולת ההחלמה. במערכות משובצות, זה יכול להיות מזיק במיוחד כאשר הטון מנהל את מצבי הכוח או מפריעים המשפיעים על מודולים אחרים.FLT:0Mitigation: FLT:1 מגביל את מספר הרווקים למערכת משנה אחת או שתיים (למשל, שעון ומנהל שגיאות, איפה ניתן להחליף דפוס פעולה יחידי).

התעלמות מ-Power Constraints

יצירת סינגלטון כי ראשוני של כוח גבוה היקפי במהלך מערכת ההפעלה סטארט-אפ יכול לבזבז אנרגיה ביישומים של מחזור נמוך.לדוגמה, מקלט GPS Singleton צריך להיווצר רק כאשר משימת ניווט פעיל.FLT:0Solution:FLT:1 יישום "shallow" יחידטון כי רק יש לטפל, ולספק כוח מפורש / כוח / כוח עצלן / מסגרת כוח כי צריך את כוח עצלן (FLT:1 יישום 1) עם כוח עצלן (משלב) עם כוח עצלן 1 יישום "shlemental" 1" יחידטון כי רק מטפל רק מטפל רק מטפל רק מטפל כוח עצלן"

ניקוי נכון

במערכות משובצות רבות, הסינגלton Outlives היישום - אין שלב "הסתה" עם זאת, אם המערכת תומכת בטעינה דינמית (למשל, מברשות להגשת הבקשה) או הפעלה מחדש של זמן, ה- Singleton עשוי להיות צורך לשחרר משאבים.דפני זיכרון מ- Singletons הם נדירים בהקצאת חומרת יחיד, אך רישומים היקפיים שנותרו במצב פעיל יכולים לגרום לסכסוכים אופציונליים: 1Ficial או ליישבים.

אתגרים

(הופנה מהדף גישה לוטו (למשל, FLT:14) מאפשר להחליף את המקרה עם מבחן כפול.זה מפר את העיקרון הפתוח / סגור ומרתיע בדיקות קושחה בכתב:0Approach:00:FLT:1 חשיפה לאחור: Exse 1 משתנה עולמי או שימוש סטטר עבור בדיקות (מחזיק בבדיקה) על ידי aLT:15FLT: לחלופין, שימוש ב"מקודש יכול להיות לעג"ל עם תבנית" אך ניתן ללעג עם לעג עם לעג"ד"ד"ד"ל יכול להיות לעג"ד"ד"ד"ד"ד"ד"ד"ד"ד"ל יכול להיות לעג"ד"ד"ד"ד"ד"ד"ד"ד.

(ב) ⁇ :0)2: ⁇ : ⁇ 1 (הפיתוח מונע על ידי מבחן עבור C משובצ) מכוסה ב- (FLT:2Test-Driven Development for Embedded C על ידי ג'יימס ו' גרנינג'ר 3 (מספק דפוסים לדקופטונים).

הוראות C ו- C++

C - Static Local with Explicit Locking

תבנית C נפוצה משתמשת במשתנה סטטי בתוך פונקציה, נשמרת על ידי mutex או מפריעה.זה פשוט אבל דורש טיפול זהיר של המשמר:

// Recommended for single-core with interrupts disabled during init
MyPeripheral* MyPeripheral_GetInstance(void) {
 static MyPeripheral inst;
 static bool initialized = false;
 if (!initialized) {
 // Disable interrupts
 __disable_irq();
 if (!initialized) { // double-check after lock
 MyPeripheral_InitHardware(&inst);
 initialized = true;
 }
 __enable_irq();
 }
 return &inst;
}

דפוס מנעול כפול זה עובד רק אם המדור אינו מסדר מחדש חנויות ואם האדריכלות מבטיחה קריאה אטומית / טקסים לדגל (בדרך כלל מילה בת 32 סיביות המיושר על ARM Cortex-M).

C++ - Static Local with Contexpr and RAII

ה- C++11 מאייר הוא מאובטח על ידי התקן, אך להיות מודע לכך שלמשתנים מקומיים סטטיים יש מנגנון מנעול נסתר אשר צורב ערימה.עבור מערכות מחוסנות מאוד, יש לשקול חבר סטטי פשוט משתנה עם בונה הנקרא מוקדם ב-FLT 18 (ראשי תיבות של ייצור) בשני המקרים, כלל אצבע: לשמור על בניית אוטבטה 19 או טריוויאלי.

מסקנה

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

(ב) ⁇ ⁇ ⁇ ⁇ ⁇

  • השתמש ב ראשונית עצלנית כדי לשמר משאבים, אבל לפנים בשקיקה עבור נתיבים קריטיים בזמן.
  • לנעול את הטון עם המנגנון המתאים עבור RTOS או אדריכלות להפריע; לעולם אל לחסום בתוך ISR.
  • להימנע מ הקצאת הערימה - מעדיפים זיכרון סטטי.
  • עיצוב לבדיקות על ידי הזרקת ממשק של Singleton ולא לקרוא למבקרים גלובליים.
  • לספק שגרות דה-ניטריזציה מפורשות לניהול חשמל והגדרה מחדש.

שם מקור:0.10.10.10.10

  • (ב) ⁇ (ב"ה) ,0) ,"ד'ויקיפדיה" (צילום: יח"ד)
  • (ב) ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
  • (FLT:0C++ שאלות נפוצות - סדר הזיכיון סטטי (FiascoFLT:1) (למה טרמפונים להוטים יכולים להיות מסוכנים)