כדי לתמוך בניהול צריכת החשמל הספציפי לרכב, 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 לעבור למצב On (מופעל). במצב הזה, מערכת AAOS פועלת באופן מלא ומקיימת אינטראקציה עם הנהג.
- הכנה לפני כיבוי. כשהנהג מסיים לנהוג, ה-VHAL שולח את הפקודה
SHUTDOWN_PREPAREכדי להורות ל-AAOS להיכנס לשלב ההכנה לפני הכיבוי. במצב הזה, מאזינים לשינויים במצב ההפעלה מקבלים את הערךSTATE_PRE_SHUTDOWN_PREPARE. זו אזהרה מוקדמת על כך שההשבתה מתחילה. - הכנה לכיבוי. כשהמאזינים מסיימים או כשמגיעים לזמן הקצוב של Pre Shutdown Prepare, מערכת Android נכנסת לשלב הליבה של Shutdown Prepare, ומודיעה למאזינים באמצעות
STATE_SHUTDOWN_PREPARE. המסך והאודיו כבויים ואין אינטראקציה בין AAOS לבין הנהג. מערכת Android ממשיכה לפעול ויכולה לבצע פעולות ניקוי ועדכון, כמו הפעלת מצב מוסך. - ממתינים לסיום של VHAL. בשלב הזה, מערכת AAOS מודיעה ל-VHAL שהיא מוכנה לכיבוי. ה-VMCU אמור להעביר את ה-SoC למצב שינה עמוקה ולנתק את החשמל ממעבד האפליקציה. בשלב הזה, מערכת AAOS נמצאת במצב Suspend-to-RAM, אבל לא מופעל קוד.
מודולים לניהול צריכת חשמל
מערכת ניהול החשמל מורכבת מהמודולים הבאים:
| שם המודול | תיאור |
|---|---|
| CarPowerManager | Java או C++ API. |
| CarPowerManagementService | מתאם את המעברים בין מצבי צריכת החשמל ומעביר את ניהול מדיניות צריכת החשמל ל-CarPowerPolicyDaemon. |
| CarPowerPolicyDaemon | מנהל את מדיניות צריכת החשמל ומתקשר עם לקוחות מקוריים של מדיניות צריכת החשמל. |
| שכבת הפשטת חומרה לרכב | ממשק ל-VMCU. |
| ליבה | הטמעה של השעיה ל-RAM או לדיסק. |
התכונה "שינה עמוקה" (השעיית Android ל-RAM או לדיסק) מוטמעת בליבה (kernel).
התכונה הזו חשופה למרחב המשתמש כקובץ מיוחד שנמצא ב-/sys/power/state. כדי להשעות את AAOS, כותבים mem או disk בקובץ הזה.
ה-CPMS מתאם את מצב ההפעלה עם שירותים אחרים ועם שכבות HAL. ה-CPMS מיישם את מכונת המצבים שמתוארת למעלה ושולח התראות לכל משקיף כשמתרחש מעבר בין מצבי צריכת חשמל. השירות הזה משתמש גם ב-VHAL כדי לשלוח הודעות לחומרה.
ה-CPPD הוא מקור המידע האמין לגבי מדיניות צריכת החשמל. הוא מנהל את מדיניות צריכת החשמל לאורך מחזור החיים של המכשיר, ומודיע ל-CPMS, ל-VHAL ולמאזינים מקומיים אחרים על שינויים במדיניות צריכת החשמל. ה-CPMS מעביר בקשות לשינוי מדיניות צריכת החשמל ל-CPPD.
ה-CPMS מתקשר עם ה-VMCU על ידי קריאה וכתיבה של מאפייני VHAL שקשורים למצב ההפעלה, כמו AP_POWER_STATE_REQ ו-AP_POWER_STATE_REPORT. אפליקציות יכולות להשתמש בממשק שמוגדר ב-CPM כדי לעקוב אחרי שינויים במצב ההפעלה. הממשק הזה גם מאפשר לאפליקציות לרשום מאזינים למדיניות צריכת החשמל. ה-API הזה של Java מסומן ב-@SystemApi וב-@hide, ולכן הוא זמין רק לאפליקציות עם הרשאות. הקשר בין המודולים, האפליקציות והשירותים האלה מוצג בתרשים הבא:

איור 2. תרשים עזר של רכיבי החשמל.
רצף הודעות
בקטע הקודם תיארנו את המודולים שמרכיבים את מערכת ניהול צריכת החשמל. בקטע הזה נשתמש בדוגמאות כניסה למצב שינה עמוקה ויציאה ממצב שינה עמוקה כדי להסביר איך המודולים והאפליקציות מתקשרים:
כניסה למצב שינה עמוקה
רק ה-VMCU יכול להפעיל שינה עמוקה. אחרי שהמצב "שינה עמוקה" מופעל, ה-VMCU שולח התראה ל-CPMS דרך ה-VHAL. ה-CPMS משנה את המצב ל-SHUTDOWN PREPARE ומשדר את המעבר הזה לכל הצופים (האפליקציות והשירותים שעוקבים אחרי ה-CPMS) על ידי קריאה ל-method 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 שמעבד האפליקציות מוכן להשעיה. בנוסף, ה-CPMS קורא ל-method ההשעיה שלו, שמשעה את הליבה.
הרצף שמתואר למעלה מוצג בתרשים הבא:

איור 3. נכנסים לשינה עמוקה.
ממשקי תכנות שסופקו על ידי CPM
בקטע הזה מתואר ה-Java API שסופק על ידי ה-CPM לאפליקציות ולשירותים של המערכת. ה-API הזה מאפשר לתוכנת המערכת:
- מעקב אחרי שינויים במצב צריכת החשמל ב-AP.
- להחיל כללי מדיניות בנושא צריכת חשמל.
כדי להפעיל את ממשקי ה-API שסופקו על ידי ה-CPM, פועלים לפי השלבים הבאים:
- כדי לקבל את המכונה של ה-CPM, צריך לשלוח קריאה ל-Car API.
- מפעילים את ה-method המתאים באובייקט שנוצר בשלב 1.
יצירת אובייקט CarPowerManager
כדי ליצור אובייקט CPM, צריך להפעיל את ה-method 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(), שהיא פונקציית קריאה חוזרת (callback) שמופעלת כשמצב ההפעלה של 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
כדי לבטל את הרישום של כל אובייקטי המאזינים שרשומים ל-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 שולח את ההודעה "מוכן לכיבוי" ל-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 לעבור למצבי צריכת חשמל שונים, באמצעות ערכי VehicleApPowerStateReq enum. |
AP_POWER_STATE_REPORT
המאפיין הזה משמש לדיווח על מצב ניהול צריכת החשמל הנוכחי של Android. המאפיין הזה מכיל שני מספרים שלמים:
-
int32Values[0]: VehicleApPowerStateReport enum של המצב הנוכחי. -
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 | AP נכנס למצב תנומה. ה-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]: ערך enum מסוגVehicleApPowerStateReq, שמייצג את המצב החדש שאליו צריך לעבור. -
int32Values[1]: ערך הטיפוס בן המנייה (enum) שלVehicleApPowerStateShutdownParam. הערך הזה נשלח רק בהודעתSHUTDOWN_PREPARE, והוא מעביר ל-Android את האפשרויות שהיא מכילה.
הערך הראשון של המספר השלם מייצג את המצב החדש שאליו Android אמורה לעבור. הסמנטיקה מוגדרת ב-VehicleApPowerStateReq.aidl ומפורטת בהמשך:
| שם הערך | תיאור |
|---|---|
| מופעל | AP צריכה להתחיל לפעול באופן מלא. |
| SHUTDOWN_PREPARE | נקודת הגישה צריכה להתכונן לכיבוי. הערך השני מציין אם מותר למעבד היישומים לדחות את הכיבוי, ואם מעבד היישומים צפוי להיכבות או להיכנס למצב שינה עמוקה. |
| CANCEL_SHUTDOWN | נקודת הגישה צריכה להפסיק את ההכנות לכיבוי ולהתכונן להפעלה. |
| סיום | עכשיו נקודת הגישה תושבת או תושעה. |
הערך VehicleApPowerStateShutdownParam מוגדר ב-VehicleApPowerStateShutdownParam.aidl. ה-enum הזה כולל את הרכיבים הבאים:
| שם הערך | תיאור |
|---|---|
| CAN_SLEEP | נקודת הגישה יכולה להיכנס למצב שינה עמוקה במקום להפסיק לפעול לגמרי. אפשר לדחות את העדכון. |
| CAN_HIBERNATE | נקודת הגישה יכולה להיכנס למצב שינה במקום להפסיק לפעול לגמרי. מותר לדחות את המועד. |
| SHUTDOWN_ONLY | נקודת הגישה אמורה להיכבות. אפשר לדחות את העדכון. אי אפשר להשתמש במצב שינה עמוקה. |
| SLEEP_IMMEDIATELY | AP יכולה להיכנס למצב שינה עמוקה, אבל היא חייבת לעבור למצב שינה או לכבות באופן מיידי. אי אפשר לדחות את העדכון. |
| HIBERNATE_IMMEDIATELY | מעבד האפליקציות יכול להיכנס למצב השעיה לדיסק, אבל הוא חייב לעבור למצב שינה או להיכבות מיד. אי אפשר לדחות את העדכון. |
| SHUTDOWN_IMMEDIATELY | נקודת הגישה חייבת להיסגר באופן מיידי. אי אפשר לדחות את העדכון. אי אפשר להשתמש במצב שינה עמוקה. |
מקורות ליציאה ממצב שינה
האינטגרטור צריך להשבית את מקורות ההפעלה המתאימים כשהמכשיר במצב השעיה. מקורות נפוצים להפעלה כוללים אותות חיים, מודם, 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. תרשים של הפניות לאובייקטים.