Google is committed to advancing racial equity for Black communities. See how.
דף זה תורגם על ידי Cloud Translation API.
Switch to English

HIDL

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

HIDL מיועד לשמש לתקשורת בין תהליכים (IPC). תקשורת בין תהליכים מכונה Binderized . עבור ספריות שיש לקשר אותן לתהליך, זמין גם מצב מעבר (לא נתמך ב- Java).

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

עיצוב HIDL

מטרת HIDL היא שניתן להחליף את המסגרת מבלי לבנות מחדש את ה- HAL. מכשירי HAL ייבנו על ידי ספקים או יצרני SOC ויוכנסו במחיצת /vendor במכשיר, מה שמאפשר להחליף את המסגרת, במחיצה שלה, ל- OTA מבלי להרכיב מחדש את ה- HALs.

עיצוב HIDL מאזן בין החששות הבאים:

  • יכולת פעולה הדדית . צור ממשקים אינטראפטיביים מהימנים בין תהליכים אשר עשויים להיות מורכבים עם ארכיטקטורות שונות, שרשראות כלים ותצורות בנייה. ממשקי HIDL מותקנים בגרסה ולא ניתן לשנות אותם לאחר פרסום.
  • יעילות . HIDL מנסה למזער את מספר פעולות ההעתקה. נתונים המוגדרים על ידי HIDL מועברים לקוד C ++ במבני נתוני פריסה סטנדרטיים C ++ בהם ניתן להשתמש ללא פריקה. HIDL מספק גם ממשקי זיכרון משותפים, מכיוון שה- RPC מטבעו איטי במקצת, HIDL תומך בשתי דרכים להעברת נתונים ללא שימוש בשיחת RPC: זיכרון משותף ותור הודעות מהיר (FMQ).
  • אינטואיטיבי . HIDL נמנע קוצני סוגיות בעלות זיכרון באמצעות רק in פרמטרים עבור RPC (ראה הגדרה של ממשק אנדרואיד שפה (AIDL) ); ערכים שלא ניתן להחזיר ביעילות משיטות מוחזרים באמצעות פונקציות התקשרות. גם העברת נתונים ל- HIDL להעברה או קבלת נתונים מ- HIDL לא משנה את הבעלות על הנתונים - הבעלות נשארת תמיד עם פונקציית הקריאה. הנתונים צריכים להימשך רק למשך הפונקציה הנקראת ועלולים להיהרס מיד לאחר חזרת הפונקציה הנקראת.

שימוש במצב מעבר

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

מצב Passthrough זמין רק עבור לקוחות C ++ ויישומים. למכשירים המריצים גרסאות קודמות של Android אין HALs כתובים בג'אווה, ולכן HALs של Java קשורים מטבעם.

.hal קובץ .hal , hidl-gen מייצר קובץ כותרת מעבר נוסף BsFoo.h בנוסף לכותרות המשמשות לתקשורת קלסר; כותרת זו מגדירה פונקציות שיש dlopen . מכיוון ש- HAL של מעבר מעבר פועל באותו תהליך בו הם נקראים, ברוב המקרים שיטות מעבר מופעלות על ידי קריאת פונקציה ישירה (אותו שרשור). oneway שיטות לרוץ חוט שלהם כפי שהם אינם מיועדים לחכות HAL לעבד אותם (אמצעי זה כל HAL כי השימושים oneway שיטות במצב התמסורת חייב להיות חוט בטוח).

בהינתן IFoo.hal , BsFoo.h עוטפת את השיטות שנוצר HIDL לספק תכונות נוספות (כגון עשיית oneway עסקות לרוץ חוט אחר). קובץ זה דומה ל- BpFoo.h , אולם במקום להעביר שיחות IPC באמצעות קלסר, הפונקציות הרצויות מופעלות ישירות. יישומים עתידיים של HALs עשויים לספק יישומים מרובים, כגון FooFast HAL ו- FooAccurate HAL. במקרים כאלה, ייווצר קובץ לכל יישום נוסף (למשל, PTFooFast.cpp ו- PTFooAccurate.cpp ).

HALs מעבר מעבר

אתה יכול לקשור יישומי HAL התומכים במצב מעבר. בהינתן ממשק HAL abcd@MN::IFoo , abcd@MN::IFoo שתי חבילות:

  • abcd@MN::IFoo-impl . מכיל את יישום ה- HAL וחושף את הפונקציה IFoo* HIDL_FETCH_IFoo(const char* name) . במכשירים מדור קודם, חבילה זו dlopen ויישום HIDL_FETCH_IFoo באמצעות HIDL_FETCH_IFoo . ניתן ליצור את קוד הבסיס באמצעות hidl-gen ו- -Lc++-impl ו- -Landroidbp-impl .
  • abcd@MN::IFoo-service . פותח את ה- HST של מעבר המעבר ורושם את עצמו כשירות מקושר, מה שמאפשר להשתמש באותה הטמעת HAL כמעבר וגם לקישור.

בהתחשב בסוג IFoo , אתה יכול להתקשר ל- sp<IFoo> IFoo::getService(string name, bool getStub) כדי לקבל גישה למופע של IFoo . אם getStub נכון, getService מנסה לפתוח את ה- HAL רק במצב מעבר. אם getStub שגוי, getService מנסה למצוא שירות מקושר; אם זה נכשל, הוא מנסה למצוא את שירות מעבר. אין getStub בפרמטר getStub אלא ב defaultPassthroughServiceImplementation . (התקנים המופעלים עם Android O הם מכשירים מקושרים לחלוטין, כך שאסור לפתוח שירות במצב מעבר.)

דקדוק HIDL

לפי תכנון, שפת HIDL דומה ל- C (אך אינה משתמשת במעבד C מראש). כל הפיסוקים שלא מתוארים להלן (מלבד השימוש הברור ב- = ו- | ) הם חלק מהדקדוק.

הערה: לפרטים אודות סגנון קוד HIDL, עיין במדריך לסגנון הקוד .

  • /** */ מציין הערת תיעוד. ניתן להחיל את אלה רק על הצהרות ערך מסוג סוג, שיטה, שדה ואומנות.
  • /* */ מציין תגובה רב-שורתית.
  • // מציין תגובה לסוף השורה. מלבד // , שורות חדשות זהות לכל מרחב לבן אחר.
  • בדקדוק לדוגמא שלמטה, טקסט מ // עד סוף השורה אינו חלק מהדקדוק אלא הוא הערה על הדקדוק.
  • [empty] פירושו שהמונח עשוי להיות ריק.
  • ? המשמעות של מילול או מונח היא אופציונלית.
  • ... מציין רצף המכיל אפס או יותר פריטים עם פיסוק המפריד כמצוין. אין טיעונים משתנים ב- HIDL.
  • פסיקים מרכיבים רצף נפרדים.
  • נקודה-פסיק מסיימת כל אלמנט, כולל האלמנט האחרון.
  • UPPERCASE הוא מסוף שאינו מסוף.
  • italics היא משפחה סמלית כגון integer או identifier (כללי ניתוח C סטנדרטיים).
  • constexpr הוא ביטוי קבוע בסגנון C (כגון 1 + 1 ו- 1L << 3 ).
  • import_name הוא שם חבילה או ממשק, המוסמך כמתואר בגירסת HIDL .
  • words באותיות קטנות הן אסימונים מילוליים.

דוגמא:

ROOT =
    PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... }  // not for types.hal
  | PACKAGE IMPORTS ITEM ITEM...  // only for types.hal; no method definitions

ITEM =
    ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?;
  |  safe_union identifier { UFIELD; UFIELD; ...};
  |  struct identifier { SFIELD; SFIELD; ...};  // Note - no forward declarations
  |  union identifier { UFIELD; UFIELD; ...};
  |  enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar
  |  typedef TYPE identifier;

VERSION = integer.integer;

PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION;

PREAMBLE = interface identifier EXTENDS

EXTENDS = <empty> | extends import_name  // must be interface, not package

GENERATES = generates (FIELD, FIELD ...)

// allows the Binder interface to be used as a type
// (similar to typedef'ing the final identifier)
IMPORTS =
   [empty]
  |  IMPORTS import import_name;

TYPE =
  uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t |
 float | double | bool | string
|  identifier  // must be defined as a typedef, struct, union, enum or import
               // including those defined later in the file
|  memory
|  pointer
|  vec<TYPE>
|  bitfield<TYPE>  // TYPE is user-defined enum
|  fmq_sync<TYPE>
|  fmq_unsync<TYPE>
|  TYPE[SIZE]

FIELD =
   TYPE identifier

UFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...};
  |  struct identifier { FIELD; FIELD; ...};
  |  union identifier { FIELD; FIELD; ...};
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SIZE =  // Must be greater than zero
     constexpr

ANNOTATIONS =
     [empty]
  |  ANNOTATIONS ANNOTATION

ANNOTATION =
  |  @identifier
  |  @identifier(VALUE)
  |  @identifier(ANNO_ENTRY, ANNO_ENTRY  ...)

ANNO_ENTRY =
     identifier=VALUE

VALUE =
     "any text including \" and other escapes"
  |  constexpr
  |  {VALUE, VALUE ...}  // only in annotations

ENUM_ENTRY =
     identifier
  |  identifier = constexpr

טרמינולוגיה

סעיף זה משתמש במונחים הבאים הקשורים ל- HIDL:

מקושר מציין ש- HIDL משמש לשיחות פרוצדורות מרחוק בין תהליכים, המיושמות באמצעות מנגנון דמוי קלסר. ראה גם מעבר .
התקשרות חוזרת, אסינכרונית ממשק המוגש על ידי משתמש HAL, הועבר ל- HAL (בשיטת HIDL), וקרא על ידי HAL להחזיר נתונים בכל עת.
התקשרות חוזרת, סינכרוני מחזיר נתונים מהטמעת שיטת HIDL של השרת ללקוח. לא בשימוש לשיטות שמחזירות ריק או ערך פרימיטיבי יחיד.
לָקוּחַ תהליך הקורא לשיטות של ממשק מסוים. תהליך HAL או מסגרת עשוי להיות לקוח של ממשק אחד ושרת של אחר. ראה גם מעבר .
מרחיב מציין ממשק שמוסיף שיטות ו / או סוגים לממשק אחר. ממשק יכול להרחיב ממשק אחד נוסף בלבד. ניתן להשתמש בהגדלת גרסת מינור באותו שם חבילה או לחבילה חדשה (למשל סיומת ספק) לבניית חבילה ישנה יותר.
מייצר מציין שיטת ממשק המחזירה ערכים ללקוח. כדי להחזיר ערך אחד לא פרימיטיבי, או יותר מערך אחד, נוצרת פונקציית קריאה סינכרונית.
מִמְשָׁק אוסף שיטות וסוגים. תורגם לשיעור ב- C ++ או ב- Java. כל השיטות בממשק נקראות באותו כיוון: תהליך לקוח קורא לשיטות המיושמות על ידי תהליך שרת.
דרך אחת כאשר מוחל על שיטת HIDL, מציין שהשיטה אינה מחזירה ערכים ואינה חוסמת.
חֲבִילָה אוסף ממשקים וסוגי נתונים המשתפים גרסה.
עובר דרך מצב HIDL בו השרת הוא ספרייה משותפת, dlopen ידי הלקוח. במצב מעבר, הלקוח והשרת הם אותו תהליך אך בסיסי קוד נפרדים. משמש רק בכדי להכניס בסיסי קודמים למודל HIDL. ראה גם Binderized .
שרת תהליך המיישם שיטות של ממשק. ראה גם מעבר .
תַחְבּוּרָה תשתית HIDL המעבירה נתונים בין השרת ללקוח.
גִרְסָה גרסת חבילה. מורכב משני מספרים שלמים, מייג'ור ומינור. תוספות גרסאות קלות עשויות להוסיף (אך לא לשנות) סוגים ושיטות.