ממשק VHAL

ממשק AIDL VHAL מוגדר ב-android.hardware.automotive.vehicle namespace. ממשק VHAL מוגדר בכתובת IVehicle.aidl. אלא אם צוין אחרת, צריך להטמיע את כל השיטות עבור גרסה ספציפית של VHAL.

גרסאות

גרסת Android הגרסה העדכנית של VHAL הגרסה האחרונה של מאפיין VHAL גרסת VHAL מינימלית תואמת
Android 16 V4 V4 V1
Android 15 V3 V3 V1
Android 14 V2 V2 V1
Android 13 V1 (ממשק המאפיינים של VHAL לא מפוצל) V1

מומלץ להטמיע את הגרסה האחרונה של VHAL לגרסה ספציפית של Android.

פונקציות וקריאות חוזרות

הפונקציות של VHAL מוגדרות בכתובת IVehicle.aidl.

שיטה
VehiclePropConfigs getAllPropConfigs()
מחזירה רשימה של כל תצורות הנכסים שנתמכות על ידי שכבת הפשטת חומרה לרכב זו.
VehiclePropConfigs getPropConfigs(in int[] props)
מחזירה רשימה של Property Configurations עבור מזהי נכסים נתונים.
void getValues(IVehicleCallback callback, in GetValueRequests requests)
קבלת ערכים של מאפייני רכב באופן אסינכרוני. מטפלת באצווה של GetValueRequest באופן אסינכרוני. התוצאה מועברת באמצעות שיטת הקריאה החוזרת onGetValues.
void setValues(IVehicleCallback callback, in SetValueRequests requests)
הגדרה של ערכי מאפייני הרכב באופן אסינכרוני. מטפלת בקבוצה של SetValueRequest באופן אסינכרוני. התוצאה מועברת באמצעות שיטת הקריאה החוזרת onSetValues.
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
הרשמה לאירועים בנכס עם אפשרויות שצוינו. אפשרויות המינוי כוללות מזהה נכס, מזהה אזור נכס וקצב דגימה בהרץ (לנכס רציף). לא נעשה שימוש ב-maxSharedMemoryFileCount.
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
מבטל את ההרשמה לאירועים של נכסים שנרשמו אליהם בעבר, עבור נכסים שצוינו.
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
לא נעשה שימוש בערך הזה, ואפשר להטמיע אותו כפעולה שלא עושה כלום.
(חדש ב-Android 16)
SupportedValuesListResults getSupportedValuesLists(in List propIdAreaIds)
מקבל את רשימות הערכים הנתמכים עבור זוגות של מזהה מאפיין ומזהה אזור שצוינו.
הוצג ב-VHAL V4.
‫(New in Android 16)
MinMaxSupportedValueResults getMinMaxSupportedValue(in List propIdAreaIds)
Gets the minimum and maximum supported values for the specified property ID and area ID pairs.
הוצג ב-VHAL V4.
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List propIdAreaIds)
רושמת קריאה חוזרת שתופעל כשהערכים הנתמכים ישתנו.
הוצג ב-VHAL V4.
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List propIdAreaIds)
ביטול הרישום של הקריאה החוזרת לשינוי ערך נתמך.
הוצג ב-VHAL V4.

הפונקציות ל-callback מוגדרות ב-IVehicleCallback.aidl והן כוללות את ה-methods האלה.

שיטה
oneway void onGetValues(in GetValueResults responses)
פונקציית קריאה חוזרת עבור הפונקציה getValues להעברת תוצאות של קבלת ערך. הפונקציה נקראת כשחלק מהערכים לאחזור מוכנים.
oneway void onSetValues(in SetValueResults responses)
Callback for setValues function to deliver set value results. הפונקציה נקראת כש-VHAL מסיים לטפל בחלק מהבקשות להגדרת נכסים.
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
Callback for reporting property update events.
CONTINUOUS property, a property event happens based on subscribe sample rate in Hz or vehicle bus message frequency. אירוע בנכס יכול לקרות גם אם הסטטוס של הנכס משתנה. לדוגמה, מ'לא זמין' ל'זמין'.
במאפיין ON_CHANGE, אירוע של מאפיין מתרחש כשערך של מאפיין או הסטטוס של מאפיין משתנים.
המאפיין הזה צריך לשמש גם להעברת אירועים של שינוי סטטוס הנכס. לדוגמה, אם הנכס לא זמין או שיש שגיאה בקריאה שלו, צריך להעביר VehiclePropValue עם סטטוס לא זמין או שגיאה וערך ריק.
SharedMemoryFileCount תמיד 0.
oneway void onPropertySetError(in VehiclePropErrors errors)
פונקציית Callback לדיווח על שגיאות בהגדרת מאפיינים אסינכרוניים שאין להן בקשת הגדרה תואמת. request. אם אנחנו יודעים לאיזו בקשת הגדרה השגיאה מתייחסת, צריך להשתמש ב-onSetValues עם תוצאת שגיאה במקום בשיטה הזו.
oneway void onSupportedValueChange(in List propIdAreaIds)
קריאה חוזרת לדיווח על שינויים בערך המינימלי והמקסימלי הנתמכים או ברשימת הערכים הנתמכים. המתקשר אמור להתקשר אל getMinMaxSupportedValue או אל getSupportedValuesLists כדי לקבל את הערכים המעודכנים.

ההטמעה של VHAL מאומתת על ידי VHAL VTS בכתובת VtsHalAutomotiveVehicle_TargetTest.cpp.

הבדיקה מוודאת שהשיטות הבסיסיות הוטמעו בצורה נכונה ושההגדרות של הנכס הנתמך נכונות. הבדיקה מופעלת מול כל המופעים של VHAL במכשיר, אבל AAOS משתמש רק במופע ברירת המחדל (android.hardware.automotive.vehicle.IVehicle/default)

ערך מאפיין הרכב

משתמשים במבנה VehiclePropValue כדי לתאר את הערך של כל מאפיין, שכולל את השדות הבאים:

שדה תיאור
timestamp חותמת הזמן שמייצגת את השעה שבה האירוע קרה, והיא מסונכרנת עם השעון SystemClock.elapsedRealtimeNano().
prop מזהה הנכס של הערך הזה.
areaid מזהה האזור של הערך הזה. האזור צריך להיות אחד מהאזורים הנתמכים שמופיעים בהגדרת מזהה האזור, או 0 עבור נכסים גלובליים.
value מבנה נתונים שמכיל את הערך בפועל של הנכס. בהתאם לסוג הנכס, שדה אחד או יותר בשדה הזה משמשים לאחסון הערך בפועל. לדוגמה, הרכיב הראשון ב-value.int32Values משמש למאפיינים מסוג Int32. פרטים נוספים מופיעים במאמר בנושא הגדרות של נכסים.
status הסטטוס של הנכס לקריאה. במאפיין קריאה/כתיבה, יכול להיות שההגדרה הזו תחול גם על כתיבה, אבל זה לא מובטח. לדוגמה, יכול להיות שהמאפיין יהיה זמין לקריאה אבל לא לכתיבה. במקרה כזה, הסטטוס הוא AVAILABLE ושדה הערך מכיל מידע תקין. לרשימת הסטטוסים האפשריים, ראו VehiclePropertyStatus.

הפונקציות האסינכרוניות getValues ו-setValues

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

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

איור 1. תהליך אסינכרוני.

‫parcelable גדולים

כל המבנים שנקראים XXXs, כמו VehiclePropConfigs,‏ SetValueRequests ו-VehiclePropValues, נקראים LargeParcelable (או StableLargeParcelable). כל אחד מהם מייצג רשימה של ערכים שמשמשים להעברת נתונים גדולים שעשויים לחרוג מהמגבלות של Binder (4KB בהטמעה של ספריית LargeParcelable) מעבר לגבולות של Binder. לכל אחד מהם יש הגדרת מבנה דומה שכוללת את השדות הבאים.

הדרכה תיאור
payloads רשימת ערכים אם גודל הערך מתאים למגבלת הזיכרון של הקובץ, או רשימה ריקה.
sharedMemoryFd מתאר קובץ שאפשר להגדיר כ-Null, שמצביע על קובץ זיכרון משותף שמאחסן את המטען הייעודי (payload) שעבר סריאליזציה, אם רשימת הערכים גדולה מדי.

לדוגמה, VehiclePropConfigs מוגדר כך:

parcelable VehiclePropConfigs {
    // The list of vehicle property configs if they fit the binder memory
    // limitation.
    VehiclePropConfig[] payloads;
    // Shared memory file to store configs if they exceed binder memory
    // limitation. Created by VHAL, readable only at client. Client could keep
    // the fd opened or keep the FD mapped to access configs.
    @nullable ParcelFileDescriptor sharedMemoryFd;
}

VehiclePropConfigs מכיל מטען ייעודי לא ריק או sharedMemoryFd שאינו null.

  • אם payloads לא ריק, הוא מכיל רשימה של הנתונים בפועל, שהם הגדרות הנכס.
  • אם sharedMemoryFd לא ריק, הוא מכיל קובץ של זיכרון משותף, שבו מאוחסנת התבנית הסדרתית של VehiclePropConfigs. המבנה משתמש בפונקציה writeToParcel כדי לבצע סריאליזציה של Parcel.

בתור לקוח Java של VHAL, ‏ Car Service מטפל בסריאליזציה ובדה-סריאליזציה של LargeParcelable. ביישומים של VHAL ובספריות לקוח מקוריות, צריך לבצע סריאליזציה ודה-סריאליזציה של LargeParcelable באמצעות הספרייה LargeParcelable או מחלקת wrapper שימושית לספרייה ב-ParcelableUtils.h.

לדוגמה, לקוח מקורי שמנתח בקשות ל-getValues שמתקבלות מ-binder נראה כך:

// 'requests' are from the binder.
GetValueRequests requests;
expected<LargeParcelableBase::BorrowedOwnedObject, ScopedAStatus> deserializedResults = fromStableLargeParcelable(requests);
if (deserializedResults.ok()) {
    const std::vector& getValueRequests = deserializedResults.value().getObject()->payloads;
    // Use the getValueRequests.
  } else {
    // handle error.
}

בדוגמה הבאה מוצגת הטמעה של VHAL ששולחת תוצאות עבור getValues דרך ה-binder:

std::vector results = getResults();
GetValueResults parcelableResults;
ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults);
if (status.isOk()) {
    // Send parcelableResults through callback.
} else {
    // Handle error.
}