כדי לתמוך בניהול צריכת חשמל ספציפי לרכב, מערכת Android מספקת CarPowerManagementServiceשירות וCarPowerManagerממשק.
מעברים בין מצבים מופעלים על ידי יחידת הבקרה הראשית של הרכב (VMCU). כדי לתקשר עם ה-VMCU, משלבי מערכות צריכים להטמיע כמה רכיבים. משלבי המערכות אחראים לשילוב עם שכבת ההפשטה של חומרת הרכב (VHAL) והטמעת הליבה. הם גם אחראים להשבתת מקורות ההפעלה ולוודא שהכיבויים לא נדחים ללא הגבלת זמן.
הסברים על המונחים
במסמך הזה אנחנו משתמשים במונחים הבאים:
עיצוב המערכת
בקטע הזה מוסבר איך AAOS מייצג את מצב ההפעלה של מעבד האפליקציה, ואילו מודולים מטמיעים את מערכת ניהול ההפעלה. בנוסף, מוסבר כאן איך המודולים האלה פועלים יחד ואיך מתרחשים בדרך כלל מעברים בין מצבים.
מכונת מצב הטעינה של הרכב
מערכת AAOS משתמשת במכונת מצבים כדי לייצג את מצב ההפעלה של ה-AP. מכונת המצבים מספקת את המצבים שמפורטים בהמשך:

איור 1. מכונת מצבים של מצב הטעינה של הרכב.
המעברים הנפוצים ביותר מודגשים בכחול. אלה המצבים והמעברים הנפוצים:
- השהיה ל-RAM. הרכב ומערכת ה-SoC מושבתים. לא מופעל קוד. המתח נשמר בזיכרון ה-RAM של ה-SoC.
- מחכים ל-VHAL. כשהנהג מבצע אינטראקציה עם הרכב, למשל פותח דלת, ה-VMCU מעביר חשמל ל-SoC. מערכת AAOS ממשיכה מ-Suspend-to-RAM ונכנסת למצב Wait for VHAL, שבו היא ממתינה לתיאום עם VHAL.
- מופעלת ממשק VHAL אומר ל-AAOS לעבור למצב 'מופעל'. במצב הזה, מערכת AAOS פועלת באופן מלא ומקיימת אינטראקציה עם הנהג.
- הכנה לכיבוי. כשהנהג מסיים לנהוג, ה-VHAL אומר ל-AAOS לעבור למצב הכנה לכיבוי. במצב הזה, המסך והשמע מושבתים ו-AAOS לא מקיים אינטראקציה עם הנהג. מערכת Android עדיין פועלת ויכולה לעדכן אפליקציות ומערכת Android. כשהעדכונים, אם יש כאלה, מסתיימים, מערכת Android עוברת למצב המתנה לסיום VHAL.
- מחכים לסיום של VHAL. בשלב הזה, מערכת AAOS מודיעה ל-VHAL שהיא מוכנה לכיבוי. ה-VMCU אמור להעביר את ה-SoC למצב שינה עמוקה ולהפסיק את אספקת החשמל למעבד האפליקציות. מערכת AAOS נמצאת במצב Suspend-to-RAM, למרות שלא מתבצע קידוד.
מודולים לניהול צריכת החשמל
מערכת ניהול צריכת החשמל מורכבת מהמודולים הבאים:
| שם המודול | תיאור |
|---|---|
| CarPowerManager | Java או C++ API. |
| CarPowerManagementService | מתאם בין מעברים של מצבי טעינה ומקצה את ניהול מדיניות הטעינה ל-CarPowerPolicyDaemon. |
| CarPowerPolicyDaemon | מנהל את מדיניות צריכת החשמל ומתקשר עם לקוחות של מדיניות צריכת חשמל מקומית. |
| שכבת הפשטת חומרה לרכב | ממשק ל-VMCU. |
| ליבה | השעיה ל-RAM או הטמעה של דיסק. |
התכונה של שינה עמוקה או תרדמה (השעיית Android ל-RAM או לדיסק) מיושמת בקרנל.
התכונה הזו מוצגת למרחב המשתמש כקובץ מיוחד שנמצא ב-/sys/power/state. מערכת AAOS מושעית על ידי כתיבת mem או disk לקובץ הזה.
ה-CPMS מתאם את מצב ההפעלה עם שירותים אחרים ועם HALs. ה-CPMS מטמיע את מכונת המצבים שמתוארת למעלה ושולח התראות לכל משתמש שצופה כשמתרחש מעבר בין מצבי הפעלה. השירות הזה משתמש גם ב-VHAL כדי לשלוח הודעות לחומרה.
ה-CPPD הוא מקור המידע האמין לגבי מדיניות צריכת חשמל. הוא מנהל את מדיניות צריכת החשמל לאורך מחזור החיים של המכשיר, ומודיע ל-CPMS, ל-VHAL ולמאזינים מקומיים אחרים על שינויים במדיניות צריכת החשמל. ה-CPMS מעביר בקשות לשינוי מדיניות בנושא צריכת חשמל ל-CPPD.
מערכת CPMS מתקשרת עם VMCU באמצעות קריאה וכתיבה של מאפייני VHAL שקשורים למצב ההפעלה, כמו AP_POWER_STATE_REQ ו-AP_POWER_STATE_REPORT. אפליקציות יכולות להשתמש בממשק שמוגדר ב-CPM כדי לעקוב אחרי שינויים במצב ההפעלה. הממשק הזה מאפשר לאפליקציות לרשום מאזינים למדיניות צריכת החשמל. ה-API הזה של Java מסומן בהערות @SystemApi ו-@hide, ולכן הוא זמין רק לאפליקציות עם הרשאות. האיור הבא מציג את הקשר בין המודולים, האפליקציות והשירותים האלה:

איור 2. תרשים הפניה לרכיבי חשמל.
רצף הודעות
בקטע הקודם תיארנו את המודולים שמרכיבים את מערכת ניהול צריכת החשמל. בדוגמאות enter deep sleep ו-exit deep sleep שבקטע הזה מוסבר איך המודולים והאפליקציות מתקשרים:
כניסה לשינה עמוקה
רק יחידת הבקרה של המכונה הווירטואלית יכולה להפעיל שינה עמוקה. אחרי שמפעילים את מצב השינה העמוקה, ה-VMCU שולח הודעה ל-CPMS דרך ה-VHAL. ה-CPMS משנה את המצב ל-SHUTDOWN PREPARE ומשדר את מעבר המצב הזה לכל האובייקטים שצופים בו (האפליקציות והשירותים שמנטרים את ה-CPMS) על ידי קריאה לשיטה onStateChanged() עם מזהה מצב חדש שסופק על ידי ה-CPM.
ה-CPM מתווך בין האפליקציות/השירותים לבין ה-CPMS. קוד ה-method onStateChanged() של האפליקציות/השירותים מופעל באופן סינכרוני בקוד ה-method onStateChanged() של ה-CPM. רוב האפליקציות והשירותים נדרשים להשלים את ההכנה שלהם לפני שהם חוזרים מהקריאה הזו. לשירותים עם הרשאות מיוחדות מותר להמשיך את ההכנות שלהם באופן אסינכרוני אחרי שהם חוזרים מ-PRE_SHUTDOWN_PREPARE, SUSPEND_ENTER, POST_SUSPEND_ENTER. במקרה כזה, השירות עם ההרשאות המיוחדות אמור להפעיל את complete() באובייקט CompletablePowerStateChangeFuture שסופק כשהוא מסיים את ההכנה שלו. חשוב לשים לב שהכנה אסינכרונית לא מותרת ל-SHUTDOWN_PREPARE. לפני ששולחים את DEEP_SLEEP_ENTRY ל-VHAL, ה-CPMS שולח מעת לעת בקשות לדחיית כיבוי ל-VHAL.
כשכל אובייקטי ה-CPM מסיימים את ההכנות לכיבוי, ה-CPMS שולח AP_POWER_STATE_REPORT ל-VHAL, שמודיע ל-VMCU שה-AP מוכן להשהיה. ה-CPMS גם קורא לשיטת ההשהיה שלו, שמשעה את הליבה.
האיור הבא מציג את הרצף שמתואר למעלה:

איור 3. כניסה לשינה עמוקה.
ממשקי תכנות שסופקו על ידי CPM
בקטע הזה מתואר Java API שסופק על ידי CPM לאפליקציות ולשירותי מערכת. ה-API הזה מאפשר לתוכנת המערכת:
- מעקב אחרי שינויים במצב ההפעלה בנקודת הגישה.
- החלת מדיניות צריכת חשמל.
כדי להפעיל את ממשקי ה-API שסופקו על ידי CPM, מבצעים את השלבים הבאים:
- כדי לקבל את מופע ה-CPM, צריך להפעיל את Car API.
- מבצעים קריאה למתודה המתאימה באובייקט שנוצר בשלב 1.
יצירת אובייקט CarPowerManager
כדי ליצור אובייקט CPM, קוראים לשיטה getCarManager() של אובייקט Car. השיטה הזו היא דוגמה לפיתוח שמשמשת ליצירת אובייקטים של CPM. מציינים את android.car.Car.POWER_SERVICE כארגומנט כדי ליצור אובייקט CPM.
Car car = Car.createCar(this); CarPowerManager powerManager = (CarPowerManager) car.getCarManager(android.car.Car.POWER_SERVICE);
CarPowerStateListener וההרשמה
אפליקציות ושירותים של המערכת יכולים לקבל התראות על שינויים במצב ההפעלה באמצעות הטמעה של CarPowerManager.CarPowerStateListener. הממשק הזה מגדיר שיטה אחת, onStateChanged(), שהיא פונקציית קריאה חוזרת שמופעלת כשמצב ההפעלה של CPMS משתנה. בדוגמה הבאה מוגדרת מחלקה אנונימית חדשה שמטמיעה את הממשק:
private final CarPowerManager.CarPowerStateListener powerListener = new CarPowerManager.CarPowerStateListener () { @Override public void onStateChanged(int state) { Log.i(TAG, "onStateChanged() state = " + state); } };
כדי להנחות את אובייקט המאזין הזה לעקוב אחרי מעבר בין מצבי הפעלה, יוצרים שרשור ביצוע חדש ורושמים את המאזין ואת השרשור הזה באובייקט CPM:
executor = new ThreadPerTaskExecutor(); powerManager.setListener(powerListener, executor);
כשמצב ההפעלה משתנה, מופעלת השיטה onStateChanged() של אובייקט המאזין עם ערך שמייצג את מצב ההפעלה החדש. הקשר בין הערך בפועל לבין מצב ההפעלה מוגדר ב-CarPowerManager ומוצג בטבלה הבאה:
| שם | תיאור |
|---|---|
| STATE_ON | מזינים את מצב ההפעלה. המערכת פועלת באופן מלא. |
| STATE_SHUTDOWN_CANCELLED | הכיבוי מבוטל ומצב ההפעלה חוזר למצב הרגיל. |
| STATE_SHUTDOWN_ENTER | האפליקציות אמורות להתנקות ולהיות מוכנות לכיבוי. |
| STATE_POST_SHUTDOWN_ENTER | ההכנות לכיבוי הסתיימו וה-VMCU מוכן לכיבוי. המערכת תעבור למצב כיבוי. |
| STATE_PRE_SHUTDOWN_PREPARE | תהליך ההשבתה נדרש, אבל מערכת CPMS עדיין לא מתחילה את התהליך. התצוגה והאודיו עדיין פועלים |
| STATE_SHUTDOWN_PREPARE | יכול להיות שמצב חנייה יפעל במהלך התקופה. |
| STATE_SUSPEND_ENTER | האפליקציות צפויות לנקות את עצמן ולהיות מוכנות להשהיה ל-RAM. |
| STATE_POST_SUSPEND_ENTER | ההכנות להשהיה ל-RAM הושלמו ו-VMCU מוכן להשהיה ל-RAM. נכנס למצב השהיה. |
| STATE_SUSPEND_EXIT | להוציא ממצב שינה או להפעיל מחדש השעיה שבוטלה. |
| STATE_HIBERNATION_ENTER | האפליקציות צריכות להתנקות ולהיות מוכנות למצב שינה. |
| STATE_POST_HIBERNATION_ENTER | ההכנות למצב שינה הסתיימו ו-VMCU מוכן למצב שינה. |
| STATE_HIBERNATION_EXIT | יציאה ממצב שינה או המשך פעולה ממצב שינה שבוטל. |
| STATE_WAIT_FOR_VHAL | המערכת מתחילה לפעול, אבל מחכה ליצור תקשורת עם VHAL לפני שהיא עוברת למצב ON. |
ביטול הרישום של CarPowerStateListener
כדי לבטל את הרישום של כל אובייקטי ה-listener שנרשמו ל-CPM, צריך לבצע קריאה ל-method clearListener:
powerManager.clearListener();
שילוב מערכות בהטמעה שלכם ב-Android
האינטגרטורים אחראים לדברים הבאים:
- הטמעה של ממשק הליבה להשעיית Android.
- הטמעת הפונקציות של VHAL כדי:
- העברת ההפעלה של השהיה או כיבוי מהרכב אל Android.
- שליחת ההודעה 'מוכן לכיבוי' מ-Android לרכב.
- התחלת כיבוי או השעיה של Android דרך ממשק ליבת Linux.
- חשוב לוודא שכל מקורות ההתעוררות מושבתים כשהמכשיר במצב השהיה.
- חשוב לוודא שהאפליקציות נסגרות מספיק מהר כדי לא לדחות את תהליך ההשבתה ללא הגבלת זמן.
- מוודאים שחבילת ה-BSP מפעילה (או משביתה) את רכיבי המכשיר בהתאם למדיניות ניהול צריכת החשמל, כדי לא לחסום את ההשעיה או את מצב השינה.
ממשק ליבה: /sys/power/state
מערכת AAOS מעבירה מכשיר למצב השהיה כששירות או אפליקציה כותבים mem להשהיה ב-RAM או disk להשהיה בדיסק בקובץ שנמצא ב-/sys/power/state. האינטגרטור צריך לספק פונקציה שעוקבת אחרי הקובץ הזה ומעבירה את Linux למצב צריכת חשמל בהשהיה. הפונקציה הזו יכולה לשלוח GPIO ל-VMCU כדי להודיע ל-VMCU שהמכשיר נסגר לגמרי. האינטגרטור אחראי גם להסרת תנאי מירוץ בין VHAL לשליחת ההודעה הסופית ל-VMCU לבין המערכת שעוברת למצב השהיה או כיבוי.
האחריות של VHAL
VHAL מספק ממשק בין רשת הרכב לבין Android. VHAL:
- העברת ההפעלה של השהיה או כיבוי מהמכונית אל Android.
- ההודעה 'מוכן לכיבוי' נשלחת מ-Android לרכב.
- הפקודה מתחילה את הכיבוי או ההשעיה של Android דרך ממשק ליבת ה-Linux.
כשמערכת ה-CPMS מודיעה ל-VHAL שהיא מוכנה לכיבוי, מערכת ה-VHAL שולחת את ההודעה shutdown ready (הכיבוי מוכן) ל-VMCU. בדרך כלל, ציוד היקפי על שבב כמו UART, SPI ו-USB מעביר את ההודעה. אחרי שההודעה נשלחת, מערכת CPMS קוראת לפקודת הליבה כדי להשהות או לכבות את המכשיר. לפני כן, יכול להיות ש-VHAL או BSP יעבירו אות GPIO כדי להודיע ל-VMCU שאפשר להפסיק את אספקת החשמל למכשיר.
ממשק VHAL צריך לתמוך במאפיינים הבאים, ששולטים בניהול צריכת החשמל דרך VHAL:
| שם | תיאור |
|---|---|
| AP_POWER_STATE_REPORT | מערכת Android מדווחת על מעברים בין מצבים ל-VMCU באמצעות המאפיין הזה, תוך שימוש בערכי enum של VehicleApPowerStateReport. |
| AP_POWER_STATE_REQ | ה-VMCU משתמש במאפיין הזה כדי להנחות את Android לעבור למצבי הפעלה שונים, באמצעות ערכי enum של VehicleApPowerStateReq. |
AP_POWER_STATE_REPORT
המאפיין הזה משמש לדיווח על מצב ניהול החשמל הנוכחי של Android. המאפיין הזה מכיל שני מספרים שלמים:
-
int32Values[0]: ספירת VehicleApPowerStateReport של המצב הנוכחי. -
int32Values[1]: משך הזמן באלפיות השנייה לדחייה, להשהיה או לכיבוי. המשמעות של הערך הזה תלויה בערך הראשון.
הערך הראשון יכול להיות אחד מהערכים הבאים. VehicleApPowerStateReport.aidl
כולל תיאורים ספציפיים יותר, שמאוחסנים בhardware/interfaces/automotive/vehicle/aidl/android/hardware/automotive/vehicle.
| שם הערך | תיאור | הערך השני |
|---|---|---|
| WAIT_FOR_VHAL | ה-AP מתחיל וצריך ליצור תקשורת עם ה-VHAL. | |
| DEEP_SLEEP_ENTRY | נקודת הגישה עוברת למצב שינה עמוקה. ה-VMCU צריך להפעיל מחדש את ה-AP אחרי הזמן שצוין בערך השני. | חובה להגדיר |
| DEEP_SLEEP_EXIT | נקודת הגישה יוצאת ממצב שינה עמוקה. | |
| HIBERNATION_ENTRY | נקודת הגישה עוברת למצב שינה. ה-VMCU צריך להפעיל מחדש את ה-AP אחרי הזמן שצוין בערך השני. | חובה להגדיר |
| HIBERNATION_EXIT | נקודת הגישה יוצאת ממצב שינה. | |
| SHUTDOWN_POSTPONE | מערכת Android לא מוכנה לכיבוי. ה-VMCU צריך להמתין את הזמן שצוין בערך השני לפני כיבוי ה-AP. יכול להיות שמערכת Android תבקש דחייה נוספת על ידי שליחת דוחות נוספים של SHUTDOWN_POSTPONE. | חובה להגדיר |
| SHUTDOWN_PREPARE | מערכת Android מתכוננת לכיבוי. | חובה להגדיר |
| SHUTDOWN_START | נקודת הגישה מוכנה לכיבוי. ה-VMCU צריך להפעיל מחדש את ה-AP אחרי הזמן שצוין בערך השני. (לא נדרשת תמיכה ב-VMCU כדי להשתמש בתכונה של הפעלה מתוזמנת). | חובה להגדיר |
| SHUTDOWN_CANCELLED | מערכת Android מפסיקה להתכונן לכיבוי ותמשיך למצב WAIT_FOR_VHAL. | |
| מופעל | מערכת Android פועלת כרגיל. |
המצב יכול להיות מוגדר באופן אוטונומי או בתגובה לבקשה דרך VMCU.
AP_POWER_STATE_REQ
הנכס הזה נשלח על ידי VMCU כדי להעביר את Android למצב צריכת חשמל שונה, והוא מכיל שני מספרים שלמים:
-
int32Values[0]:VehicleApPowerStateReqערך enum שמייצג את המצב החדש שאליו רוצים לעבור. -
int32Values[1]:VehicleApPowerStateShutdownParamערך enum. הערך הזה נשלח רק בהודעתSHUTDOWN_PREPAREומועבר ל-Android עם האפשרויות שהוא מכיל.
ערך המספר השלם הראשון מייצג את המצב החדש שאליו מערכת Android אמורה לעבור. הסמנטיקה מוגדרת ב-VehicleApPowerStateReq.aidl ומפורטת בהמשך:
| שם הערך | תיאור |
|---|---|
| מופעל | נקודת הגישה צריכה להתחיל לפעול באופן מלא. |
| SHUTDOWN_PREPARE | נקודת הגישה צריכה להתכונן לכיבוי. הערך השני מציין אם לנקודת הגישה מותר לדחות את הכיבוי, ואם נקודת הגישה צריכה לצפות לכיבוי או להיכנס למצב שינה עמוקה. |
| CANCEL_SHUTDOWN | נקודת הגישה אמורה להפסיק את ההכנה לכיבוי ולהתכונן להפעלה. |
| סיום | נקודת הגישה תושבת או תושעה. |
הערך VehicleApPowerStateShutdownParam מוגדר ב-VehicleApPowerStateShutdownParam.aidl. ה-enum הזה כולל את הרכיבים הבאים:
| שם הערך | תיאור |
|---|---|
| CAN_SLEEP | ה-AP יכול להיכנס למצב שינה עמוקה במקום להיסגר לגמרי. מותר לדחות את הפעולה. |
| CAN_HIBERNATE | יכול להיות שנקודת הגישה תעבור למצב שינה במקום להיסגר לגמרי. מותר לדחות את התשלום. |
| SHUTDOWN_ONLY | נקודת הגישה אמורה להיכבות. מותר לדחות את התשלום. אסור להשתמש בשינה עמוקה. |
| SLEEP_IMMEDIATELY | יכול להיות שנקודת הגישה תעבור למצב שינה עמוקה, אבל היא חייבת לעבור למצב שינה או להיסגר באופן מיידי. אסור לדחות את הפעולה. |
| HIBERNATE_IMMEDIATELY | יכול להיות שנקודת הגישה תעבור למצב השהיה לדיסק, אבל היא חייבת לעבור למצב שינה או להיסגר באופן מיידי. אסור לדחות את הפעולה. |
| SHUTDOWN_IMMEDIATELY | ה-AP חייב להיסגר באופן מיידי. אי אפשר לדחות את התשלום. אסור להשתמש בשינה עמוקה. |
מקורות להוצאה ממצב שינה
המשלב צריך להשבית את מקורות ההפעלה המתאימים כשהמכשיר במצב השהיה. מקורות הפעלה נפוצים כוללים פעימות לב, מודם, Wi-Fi ו-Bluetooth. מקור ההפעלה התקין היחיד צריך להיות הפרעה מ-VMCU כדי להפעיל את ה-SoC. ההנחה היא ש-VMCU יכול להאזין למודם לאירועי הפעלה מרחוק (כמו הפעלה מרחוק של המנוע). אם הפונקציונליות הזו מועברת ל-AP, צריך להוסיף מקור הפעלה נוסף כדי לטפל במודם.
אפליקציות
יצרני ציוד מקורי צריכים לכתוב אפליקציות כך שניתן יהיה לסגור אותן במהירות, ולא לדחות את התהליך ללא הגבלת זמן.
נספח
ספריות בעץ של קוד המקור
| תוכן | הארגון שלי |
|---|---|
| קוד שקשור ל-CarPowerManager. | packages/services/Car/car-lib/src/android/car/hardware/power |
| CarPowerManagementService וכן הלאה. | packages/services/Car/service/src/com/android/car/power |
שירותים שפועלים עם VHAL, כמו VehicleHal ו-HAlClient. |
packages/services/Car/service/src/com/android/car/hal |
| ממשק VHAL והגדרות מאפיינים. | hardware/interfaces/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ |
אפליקציה לדוגמה שתיתן לכם מושג לגבי CarPowerManager |
packages/services/Car/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink |
תרשים כיתות
בתרשים המחלקות הזה מוצגים הממשקים והמחלקות של Java במערכת לניהול צריכת החשמל:

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

איור 5. דיאגרמת הפניה לאובייקט.