כדי לתמוך בניהול צריכת החשמל ברכב, מערכת Android מספקת שירות CarPowerManagementService
וממשק CarPowerManager
.
מעברי המצב מופעלים על ידי יחידת הבקרה הראשית של הרכב (VMCU). כדי לתקשר עם ה-VMCU, המפתחים צריכים להטמיע כמה רכיבים. המפתחים המוטמעים אחראים על השילוב עם שכבת הפשטת החומרה של הרכב (VHAL) ועל הטמעת הליבה. בנוסף, המפתחים אחראים להשבית את מקורות ההפעלה ולדאוג שההשבתה לא תידחה ללא הגבלת זמן.
טרמינולוגיה
המונחים הבאים מופיעים במסמך הזה:
suspend()
ול-shutdown()
.תכנון המערכת
בקטע הזה מוסבר איך AAOS מייצג את מצב האנרגיה של מעבד האפליקציות, ואילו מודולים מטמיעים את מערכת ניהול האנרגיה. בנוסף, במאמר הזה מוסבר איך המודולים האלה פועלים יחד ואיך מתרחשים בדרך כלל מעברים בין מצבים.
מכונת מצב של טעינה ברכב
מערכת AAOS משתמשת במכונת מצב כדי לייצג את מצב ההפעלה של הנקודה לשיתוף אינטרנט. מכונת המצבים מספקת את המצבים שמפורטים בהמשך:
איור 1. מכונת מצב של מתח הרכב.
המעברים הנפוצים ביותר מודגשים בכחול. אלה המצבים והמעברים הנפוצים:
- השהיה ב-RAM הרכב וה-SoC מושבתים. לא מתבצע ביצוע קוד. החשמל נשמר בזיכרון ה-RAM של SoC.
- מתנה ל-VHAL כשהנהג מבצע פעולה ברכב, למשל פותח דלת, ה-VMCU מעביר חשמל ל-SoC. מערכת AAOS ממשיכה לפעול מ-Suspend-to-RAM ומגיעה למצב Wait for VHAL, שבו היא ממתינה לתיאום עם ה-VHAL.
- מופעל. ה-VHAL מצווה על AAOS לעבור למצב מופעל. במצב הזה, מערכת AAOS פועלת במלואה ומתקיימת אינטראקציה בינה לבין הנהג.
- Shutdown Prepare כשהנהג מסיים לנהוג, ה-VHAL מורה ל-AAOS להיכנס למצב Shutdown Prepare. במצב הזה, המסך והאודיו מושבתים ומערכת AAOS לא מקיימת אינטראקציה עם הנהג. מערכת Android עדיין פועלת וניתן לעדכן את האפליקציות ואת מערכת Android. כשהעדכונים, אם יש כאלה, מסתיימים, מערכת Android עוברת למצב Wait for VHAL Finish.
- מתנה לסיום ה-VHAL. בשלב הזה, AAOS מודיע ל-VHAL שהוא מוכן לכבות. ה-VMCU צפוי להעביר את ה-SoC למצב שינה עמוקה ולהפסיק את אספקת החשמל למעבד האפליקציה. לאחר מכן, מערכת AAOS נמצאת במצב השהיה ב-RAM, אבל לא מתבצע בה ביצוע קוד.
מודולים לניהול צריכת החשמל
מערכת ניהול צריכת החשמל מורכבת מהמודולים הבאים:
שם המודול | תיאור |
---|---|
CarPowerManager | Java או C++ API. |
CarPowerManagementService | תיאום המעברים בין מצבי החשמל. |
CarPowerPolicyDaemon | מתקשר עם לקוחות המדיניות המקורית בנושא צריכת חשמל. |
Vehicle HAL | ממשק ל-VMCU. |
בועה | השהיה להטמעה ב-RAM או בדיסק. |
התכונה 'שינה עמוקה'/'תרדמת חורף' (השהיית Android ב-RAM או בדיסק) מוטמעת בליבה.
התכונה הזו מוצגת במרחב המשתמש כקובץ מיוחד שנמצא ב-/sys/power/state
. כדי להשעות את AAOS, כותבים mem
או disk
בקובץ הזה.
ה-CPMS מתאם את מצב האנרגיה עם שירותים אחרים ו-HALs אחרים. ה-CPMS מטמיע את מכונת המצבים שמתוארת למעלה, ושולח התראות לכל משתמש שמבצע מעקב כשמתרחש מעבר בין מצבי ההפעלה. השירות הזה משתמש גם ב-VHAL כדי לשלוח הודעות לחומרה.
ה-CPPD מנהל את מדיניות צריכת החשמל עד שה-CPMS מקבל את השליטה. הוא גם שולח התראות על שינויים במדיניות צריכת החשמל למאזינים המקוריים.
חלק מהמאפיינים מוגדרים ב-VHAL. כדי לתקשר עם ה-VMCU, ה-CPMS קורא את המאפיינים האלה וכותב אותם. אפליקציות יכולות להשתמש בממשק שמוגדר ב-CPM כדי לעקוב אחרי שינויים במצבי ההפעלה. הממשק הזה מאפשר גם לאפליקציות לרשום מאזינים למדיניות צריכת החשמל. אפשר להפעיל את ה-API הזה מ-Java, והוא מסומן בתווית הערה @hide / @System API, כלומר הוא זמין רק לאפליקציות עם הרשאות. באיור הבא מוסבר הקשר בין המודולים, האפליקציות והשירותים האלה:
איור 2. תרשים עזר של רכיבי החשמל.
רצף הודעות
בקטע הקודם מתוארים המודולים שמרכיבים את מערכת ניהול צריכת החשמל. בקטע הזה נעזרים בדוגמאות לכניסה למצב שינה עמוקה וליציאה ממצב שינה עמוקה כדי להסביר איך מתבצעת התקשורת בין המודולים לאפליקציות:
מעבר לשינה עמוקה
רק ה-VMCU יכול להתחיל מצב שינה עמוקה. לאחר הפעלת מצב השינה העמוק, ה-VMCU שולח התראה ל-CPMS דרך ה-VHAL. ה-CPMS משנה את המצב ל-SHUTDOWN PREPARE ומפיץ את מעבר המצב הזה לכל המשקיפים (האפליקציות והשירותים שמנטרים את ה-CPMS) באמצעות קריאה ל-method onStateChanged()
עם מזהה מצב חדש שסופק על ידי ה-CPM.
ה-CPM מתווך בין האפליקציות או השירותים לבין מערכת ניהול ה-CPM. ה-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 קורא גם ל-method ההשהיה שלו, שמשהה את הליבה.
התהליך שמתואר למעלה מוצג בהמחשה הבאה:
איור 3. נכנסים לשינה עמוקה.
ממשקי תכנות שסופקו על ידי CPM
בקטע הזה מתוארת ממשק ה-API ל-Java ש-CPM מספק לאפליקציות ולשירותים של המערכת. ממשק ה-API הזה מאפשר לתוכנת המערכת:
- מעקב אחרי שינויים במצבי החשמל בנקודת הגישה.
- החלת מדיניות צריכת חשמל.
כדי לקרוא ל-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 לפני שהיא עוברת למצב מופעל. |
ביטול הרישום של 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 כדי להודיע לו שהמכשיר מושבת לחלוטין. המכשיר המאחד גם אחראי להסרת תנאי מרוץ בין שליחת ההודעה הסופית של 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 באמצעות המאפיין הזה, באמצעות ערכי המניין VehicleApPowerStateReport. |
AP_POWER_STATE_REQ | ה-VMCU משתמש במאפיין הזה כדי להורות ל-Android לעבור למצבי צריכת אנרגיה שונים, באמצעות ערכי המניין VehicleApPowerStateReq. |
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 אמור להפעיל מחדש את הנתב אחרי הזמן שצוין בערך השני. | חובה להגדיר |
DEEP_SLEEP_EXIT | הנתב יוצא ממצב השינה העמוקה. | |
HIBERNATION_ENTRY | הנתב עובר למצב שינה. ה-VMCU אמור להפעיל מחדש את הנתב אחרי הזמן שצוין בערך השני. | חובה להגדיר |
HIBERNATION_EXIT | ה-AP יוצא ממצב ההרדמה. | |
SHUTDOWN_POSTPONE | Android לא מוכן לכבות. ה-VMCU צריך להמתין את הזמן שצוין בערך השני לפני שהוא יכבה את הנקודה לשיתוף אינטרנט. Android עשויה לבקש דחייה נוספת על ידי שליחת דוחות SHUTDOWN_POSTPONE נוספים. | חובה להגדיר |
SHUTDOWN_PREPARE | מערכת Android מתכוננת לכיבוי. | חובה להגדיר |
SHUTDOWN_START | הנתב מוכן לכיבוי. ה-VMCU אמור להפעיל מחדש את הנקודה לשיתוף אינטרנט אחרי הזמן שצוין בערך השני. (לא חובה ש-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
ומפורטת בהמשך:
שם הערך | תיאור |
---|---|
מופעלת | הנתב האלחוטי אמור להתחיל לפעול במלואו. |
SHUTDOWN_PREPARE | הנתב האלחוט אמור להתכונן לכיבוי. הערך השני מציין אם מותר לנתב להשהות את ההשבתה, ואם הנתב צפוי לכבות או להיכנס למצב שינה עמוקה. |
CANCEL_SHUTDOWN | הנתב האלחוט אמור להפסיק את ההכנה לכיבוי ולהתחיל בהכנה להפעלה. |
סיום | נכון לעכשיו, נתב ה-AP יושבת או יושעה. |
הערך VehicleApPowerStateShutdownParam
מוגדר ב-VehicleApPowerStateShutdownParam.aidl
. המאפיין הזה כולל את הרכיבים הבאים:
שם הערך | תיאור |
---|---|
CAN_SLEEP | הנתב האלחוט יכול להיכנס למצב שינה עמוקה במקום לכבות לגמרי. מותר לדחות את הבחינה. |
CAN_HIBERNATE | הנתב יכול לעבור למצב תרדמה במקום לכבות לגמרי. מותר לדחות את הבחינה. |
SHUTDOWN_ONLY | הנתב האלחוט אמור להיכבות. מותר לדחות את הבחינה. אי אפשר להשתמש במצב שינה עמוקה. |
SLEEP_IMMEDIATELY | ה-AP יכול להיכנס למצב שינה עמוקה, אבל הוא חייב לעבור למצב שינה או לכבות באופן מיידי. אי אפשר לדחות את המועד. |
HIBERNATE_IMMEDIATELY | הנתב האלחוט יכול לעבור למצב השהיה בדיסק, אבל הוא חייב לעבור למצב תרדמה או לכבות באופן מיידי. אי אפשר לדחות את המועד. |
SHUTDOWN_IMMEDIATELY | יש לכבות את הנתב באופן מיידי. אי אפשר לדחות את המועד. אי אפשר להשתמש במצב שינה עמוקה. |
מקורות להפעלה
המשתמש המאחד צריך להשבית את מקורות ההפעלה המתאימים כשהמכשיר נמצא במצב השהיה. מקורות נפוצים להפעלה מחדש כוללים פעימות לב, מודם, Wi-Fi ו-Bluetooth. המקור היחיד התקף להפעלה חייב להיות הפסקה (interrupt) מ-VMCU כדי להעיר את ה-SoC. ההנחה היא ש-VMCU יכול להאזין למודם כדי לזהות אירועי הפעלה מרחוק (למשל, הפעלת מנוע מרחוק). אם הפונקציונליות הזו מועברת לנקודת הגישה, צריך להוסיף מקור אחר להפעלה מחדש כדי לתת שירות למודם.
אפליקציות
יצרני ציוד מקורי צריכים להקפיד לכתוב אפליקציות כך שאפשר יהיה להשבית אותן במהירות ולא לדחות את התהליך ללא הגבלת זמן.
נספח
ספריות בעץ קוד המקור
Content | ספרייה |
---|---|
קוד שקשור ל-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. תרשים של אובייקט העזר.