شارك في استبيان قابلية الاستخدام لدينا لتحسين هذا الموقع.
ترجمت واجهة Cloud Translation API‏ هذه الصفحة.
Switch to English

HIDL

لغة تعريف واجهة HAL أو HIDL (تُنطق "hide-l") هي لغة وصف واجهة (IDL) لتحديد الواجهة بين HAL ومستخدميها. يسمح بتحديد الأنواع واستدعاءات الطريقة ، المجمعة في واجهات وحزم. على نطاق أوسع ، HIDL هو نظام للتواصل بين قواعد الرموز التي يمكن تجميعها بشكل مستقل.

الغرض من HIDL هو استخدامه للاتصال بين العمليات (IPC). يشار إلى الاتصال بين العمليات باسم Binderized . بالنسبة للمكتبات التي يجب أن تكون مرتبطة بعملية ، يتوفر أيضًا وضع العبور (غير مدعوم في Java).

يحدد HIDL هياكل البيانات وتوقيعات الأسلوب ، المنظمة في واجهات (على غرار الفئة) التي يتم جمعها في حزم. سيبدو بناء جملة HIDL مألوفًا لمبرمجي C ++ و Java ، على الرغم من وجود مجموعة مختلفة من الكلمات الرئيسية. يستخدم HIDL أيضًا التعليقات التوضيحية بنمط Java.

تصميم HIDL

الهدف من HIDL هو أنه يمكن استبدال إطار العمل دون الحاجة إلى إعادة بناء HALs. سيتم إنشاء HALs بواسطة البائعين أو صانعي SOC ووضعها في قسم /vendor على الجهاز ، مما يتيح استبدال إطار العمل ، في القسم الخاص به ، بـ OTA دون إعادة تجميع HALs.

يوازن تصميم HIDL بين الاهتمامات التالية:

  • إمكانية التشغيل البيني . قم بإنشاء واجهات قابلة للتشغيل المتبادل بشكل موثوق بين العمليات التي يمكن تجميعها باستخدام العديد من البنى ، وسلاسل الأدوات ، وتكوينات البناء. تم إصدار واجهات HIDL ولا يمكن تغييرها بعد نشرها.
  • الكفاءة . يحاول HIDL تقليل عدد عمليات النسخ. يتم تسليم البيانات المعرفة بواسطة HIDL إلى كود C ++ في هياكل بيانات التخطيط القياسي C ++ التي يمكن استخدامها دون تفريغ. يوفر HIDL أيضًا واجهات ذاكرة مشتركة ، وبما أن RPCs بطيئة إلى حد ما ، فإن HIDL يدعم طريقتين لنقل البيانات دون استخدام مكالمة RPC: الذاكرة المشتركة وقائمة انتظار الرسائل السريعة (FMQ).
  • حدسي . يتجنب HIDL المشكلات الشائكة المتعلقة بملكية الذاكرة باستخدامه فقط in معلمات RPC (انظر لغة تعريف واجهة Android (AIDL) ) ؛ يتم إرجاع القيم التي لا يمكن إرجاعها بكفاءة من العمليات عبر وظائف رد الاتصال. لا يؤدي تمرير البيانات إلى HIDL لنقل أو تلقي البيانات من HIDL إلى تغيير ملكية البيانات - تظل الملكية دائمًا مع وظيفة الاستدعاء. تحتاج البيانات إلى الاستمرار فقط طوال مدة الوظيفة التي تم استدعاؤها ويمكن تدميرها على الفور بعد إرجاع الوظيفة المستدعى.

استخدام وضع العبور

لتحديث الأجهزة التي تعمل بإصدارات سابقة من Android إلى Android O ، يمكنك التفاف كل من HALs التقليدية (والقديمة) في واجهة HIDL جديدة تخدم HAL في وضعي Bindered ونفس العملية (العبور). هذا الغلاف شفاف لكل من HAL وإطار عمل Android.

وضع العبور متاح فقط لعملاء C ++ والتطبيقات. الأجهزة التي تعمل بإصدارات سابقة من Android لا تحتوي على HALs مكتوبة بلغة Java ، لذلك فإن Java HALs مرتبطة بطبيعتها.

عندما يتم تجميع ملف .hal ، ينتج hidl-gen ملف رأس BsFoo.h إضافي BsFoo.h بالإضافة إلى الرؤوس المستخدمة لاتصال الموثق ؛ يحدد هذا الرأس الوظائف المراد dlopen ed. نظرًا لأن HALs العبور تعمل في نفس العملية التي يتم استدعاؤها فيها ، يتم استدعاء طرق المرور في معظم الحالات بواسطة استدعاء دالة مباشر (نفس مؤشر الترابط). تعمل طرق oneway في مؤشر ترابط خاص بها حيث لا يُقصد منها انتظار HAL لمعالجتها (وهذا يعني أن أي HAL يستخدم طرق oneway في وضع العبور يجب أن يكون آمنًا للخيط).

إعطاء IFoo.hal ، BsFoo.h يلتف الأساليب ولدت HIDL لتوفير ميزات إضافية (مثل اتخاذ oneway المعاملات تشغيل في موضوع آخر). يشبه هذا الملف BpFoo.h ، ولكن بدلاً من تمرير المكالمات IPC باستخدام Binder ، يتم استدعاء الوظائف المطلوبة مباشرة. قد توفر عمليات التنفيذ المستقبلية لـ 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 ed هذه الحزمة ويتم إنشاء مثيل HIDL_FETCH_IFoo باستخدام HIDL_FETCH_IFoo . يمكنك إنشاء الكود الأساسي باستخدام hidl-gen و -Lc++-impl -Landroidbp-impl و -Landroidbp-impl .
  • abcd@MN::IFoo-service . يفتح HAL العبور ويسجل نفسه كخدمة مقيدة ، مما يتيح استخدام نفس تطبيق HAL كمرور وربط.

بالنظر إلى النوع IFoo ، يمكنك استدعاء sp<IFoo> IFoo::getService(string name, bool getStub) للوصول إلى مثيل IFoo . إذا كان getStub صحيحًا ، تحاول getService فتح HAL فقط في وضع العبور. إذا كانت getStub خاطئة ، تحاول getService البحث عن خدمة مرتبطة ؛ إذا فشل ذلك ، فسيحاول العثور على خدمة العبور. يجب عدم استخدام المعلمة getStub إلا في defaultPassthroughServiceImplementation . (الأجهزة التي يتم تشغيلها باستخدام Android O هي أجهزة مقيدة بالكامل ، لذا فإن فتح خدمة في وضع العبور غير مسموح به.)

قواعد HIDL

حسب التصميم ، فإن لغة HIDL تشبه لغة C (ولكنها لا تستخدم المعالج الأولي C). جميع علامات الترقيم غير الموضحة أدناه (بصرف النظر عن الاستخدام الواضح لـ = و | ) هي جزء من القواعد.

ملاحظة: للحصول على تفاصيل حول نمط رمز HIDL ، راجع دليل نمط التعليمات البرمجية .

  • /** */ يشير إلى تعليق توثيق. يمكن تطبيق هذه فقط على إعلانات النوع والطريقة والحقل وقيمة التعداد.
  • /* */ يشير إلى تعليق متعدد الأسطر.
  • // يشير إلى تعليق في نهاية السطر. بصرف النظر عن // ، فإن الأسطر الجديدة هي نفسها مثل أي مسافة بيضاء أخرى.
  • في المثال النحوي أدناه ، النص من // إلى نهاية السطر ليس جزءًا من القواعد ولكنه بدلاً من ذلك تعليق على القواعد.
  • [empty] يعني أن المصطلح قد يكون فارغًا.
  • ? يعني اتباع حرفي أو مصطلح أنه اختياري.
  • ... يشير إلى تسلسل يحتوي على صفر أو أكثر من العناصر مع فصل علامات الترقيم كما هو موضح. لا توجد حجج متغيرة في HIDL.
  • تفصل الفواصل عن عناصر التسلسل.
  • تنهي الفاصلة المنقوطة كل عنصر ، بما في ذلك العنصر الأخير.
  • الأحرف الكبيرة هي علامة غير نهائية.
  • italics هو عائلة رمزية مثل integer أو identifier (قواعد تحليل C القياسية).
  • constexpr هو تعبير ثابت من النمط C (مثل 1 + 1 و 1 + 1 1L << 3 ).
  • import_name هو اسم حزمة أو واجهة ، مؤهل كما هو موصوف في HIDL Versioning .
  • 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 لاستدعاءات الإجراءات عن بُعد بين العمليات ، والتي يتم تنفيذها عبر آلية تشبه Binder. انظر أيضا العبور .
رد الاتصال غير متزامن واجهة يخدمها مستخدم HAL ، تم تمريرها إلى HAL (عبر طريقة HIDL) ، ويتم استدعاؤها بواسطة HAL لإرجاع البيانات في أي وقت.
رد اتصال متزامن إرجاع البيانات من تطبيق أسلوب HIDL الخاص بالخادم إلى العميل. غير مستخدَم للطرق التي تُرجع باطلة أو قيمة أولية واحدة.
عميل العملية التي تستدعي أساليب واجهة معينة. قد تكون عملية HAL أو إطار العمل عميلاً لواجهة واحدة وخادم آخر. انظر أيضا العبور .
يمتد يشير إلى واجهة تضيف أساليب و / أو أنواعًا إلى واجهة أخرى. يمكن للواجهة توسيع واجهة واحدة أخرى فقط. يمكن استخدامه لزيادة إصدار ثانوي في نفس اسم الحزمة أو لحزمة جديدة (مثل امتداد البائع) للبناء على حزمة قديمة.
يولد يشير إلى طريقة واجهة تقوم بإرجاع القيم إلى العميل. لإرجاع قيمة واحدة غير أولية ، أو أكثر من قيمة واحدة ، يتم إنشاء وظيفة رد اتصال متزامن.
واجهه المستخدم مجموعة من الأساليب والأنواع. تُترجم إلى فصل دراسي بلغة C ++ أو Java. يتم استدعاء جميع الطرق في الواجهة في نفس الاتجاه: تستدعي عملية العميل الطرق التي تنفذها عملية الخادم.
اتجاه واحد عند تطبيقه على طريقة HIDL ، يشير إلى أن الطريقة لا تُرجع أي قيم ولا تمنع.
صفقة مجموعة من الواجهات وأنواع البيانات التي تشترك في إصدار.
يمر من خلال وضع HIDL حيث يكون الخادم عبارة عن مكتبة مشتركة ، يتم dlopen بواسطة العميل. في وضع العبور ، يكون العميل والخادم نفس العملية لكنهما مصدران منفصلان. تستخدم فقط لجلب قواعد الرموز القديمة في نموذج HIDL. انظر أيضا Binderized .
الخادم العملية التي تنفذ أساليب الواجهة. انظر أيضا العبور .
المواصلات البنية التحتية HIDL التي تنقل البيانات بين الخادم والعميل.
الإصدار نسخة الحزمة. يتكون من عددين صحيحين ، كبير وثانوي. قد تضيف الزيادات الطفيفة في الإصدارات (ولكن لا تغير) الأنواع والطرق.