HAL arayüz tanımlama dili veya HIDL, aşağıdakileri belirtmek için kullanılan bir arayüz açıklama dilidir (IDL) HAL ile HAL arasındaki arayüz teslim etmeye odaklandığı teslimatı öğrendiniz. HIDL, aşağıdaki gibi toplanan türlerin ve yöntem çağrılarının belirtilmesini sağlar: göz atabilirsiniz. HIDL daha genel olarak ifade etmek gerekirse arasında bağımsız olarak derlenebilir.
HIDL, süreçler arası iletişim (IPC) için kullanılmak üzere tasarlanmıştır. HDL ile oluşturulan HAL'ler: bağlayıcı kullanarak diğer mimari katmanlarıyla iletişim kurabilmeleri için "binderized HAL" olarak adlandırılır. işlemleri arası iletişim (IPC) çağrıları Binder HAL'ler, istemciden ayrı bir işlemde çalışır. çalışır. Örneğin, bir işleme, posta geçiş reklamı veya modu da kullanılabilir (Java'da desteklenmez).
HIDL, arayüzler halinde düzenlenmiş veri yapılarını ve yöntem imzalarını belirtir (bir sınıfa benzer şekilde) paket halinde toplanır. HIDL'nin söz dizimi C++ ve Java programcıları ama anahtar kelimeler. HIDL Java tarzı ek açıklamalar da kullanır.
Terminoloji
Bu bölümde HIDL ile ilgili aşağıdaki terimler kullanılmaktadır:
bağlı | HIDL'nin işlemler arasında uzak prosedür çağrıları için kullanıldığını gösterir. ve Bağlayıcı benzeri bir mekanizma üzerinden uygulanır. Ayrıca posta geçiş konusuna da bakın. |
---|---|
geri çağırma, eşzamansız | Bir HAL kullanıcısı tarafından sunulan, HAL'ye geçirilen (HIDL yöntemi kullanılarak) arayüz ve istediğiniz zaman veri döndürmesi için HAL tarafından çağrılacaktır. |
geri çağırma, eşzamanlı | Bir sunucunun HIDL yöntemi uygulamasındaki verileri istemciye döndürür. Boşluk veya tek bir temel değer döndüren yöntemler için kullanılmaz. |
istemci | Belirli bir arayüze ait yöntemleri çağıran işlem. HAL veya Android çerçevesi işlemi, bir arayüzün istemcisi ve diğerinin sunucusu olabilir. Şu kaynakları da inceleyin parantez. |
uzatır | Başka bir arayüze yöntem ve/veya tür ekleyen bir arayüzü belirtir. Bir arayüz yalnızca diğer bir arayüzü genişletebilir. Küçükler için kullanılabilir aynı paket adında veya yeni bir paket için (ör. tedarikçi firmanın uzantı) eski bir paketin üzerinde derlemek için kullanır. |
oluşturur | İstemciye değer döndüren bir arayüz yöntemini belirtir. Geri dönmek için primitif olmayan bir değer veya birden fazla değer, eşzamanlı bir geri çağırma işlevi oluşturulur. |
arayüz | Yöntem ve tür koleksiyonu. C++ veya Java sınıfa çevrilmişse. Tümü bir arayüzdeki yöntemler de aynı yönde çağrılır: istemci işlemi Bir sunucu işlemi tarafından uygulanan yöntemleri çağırır. |
tek yön | Bir HIDL yöntemine uygulandığında yöntemin hiçbir değer döndürmediğini belirtir ve engellemez. |
paket | Bir sürümü paylaşan arayüzler ve veri türleri koleksiyonu. |
geçiş | Sunucunun paylaşılan bir kitaplık olduğu HIDL modu, dlopen ed
teslim ederler. Geçiş modunda, istemci ve sunucu aynı süreçtir ancak
ayrı kod tabanları kullanır. Yalnızca eski kod tabanlarını HIDL modeline taşımak için kullanılır.
Bağlanmış bölümüne de bakın. |
sunucu | Bir arayüzdeki yöntemleri uygulayan işlem. Şu kaynakları da inceleyin parantez. |
ulaşım | Verileri sunucu ile istemci arasında taşıyan HIDL altyapısı. |
sürüm | Bir paketin sürümü. Büyük ve küçük olmak üzere iki tam sayıdan oluşur. Küçük yaştaki bir şahıs Sürüm artışları tür ve yöntemler ekleyebilir (ancak bunları değiştirmez). |
HIDL tasarımı
HIDL'nin amacı Android çerçevesinin zahmetsizce değiştirilebilmesidir.
yeniden oluşturmamız gerekir. HAL'ler tedarikçiler veya SOC üreticileri tarafından oluşturulur ve
Cihazdaki /vendor
bölümü, Android çerçevesini kendi başına etkinleştiriyor
bölümü, HAL'ler yeniden derlemeden bir OTA ile değiştirilir.
HIDL tasarımı aşağıdaki endişeleri dengeler:
- Birlikte çalışabilirlik. Güvenilir bir şekilde birlikte çalışabilen arayüzler oluşturun farklı mimariler, araç zincirleriyle derlenebilecek süreçler arasında ve yapılandırmaları oluşturun. HIDL arayüzlerinin sürümü vardır ve değiştirilemez .
- Verimlilik. HIDL, metinlerin kopya sayısını en aza anlamına gelir. HIDL tarafından tanımlanan veriler C++ koduna C++ standart düzeninde iletilir veri yapıları oluşturun. HIDL ayrıca paylaşılan doğal olarak biraz yavaş olduğu için HIDL iki sunucuyu destekler. bir RPC çağrısı kullanmadan veri aktarmanın yolları: paylaşılan bellek ve Mesaj Sırası (FMQ).
- Sezgiseldir. HIDL, bellek sahipliğiyle ilgili zorlu sorunları önlemek için
RPC için yalnızca
in
parametrelerini kullanma (bkz. Android Arayüz Tanımlama Dili (AIDL)); değerleri etkili bir şekilde geri çağırma işlevleri aracılığıyla döndürülür. Veriler de iletilemiyor aktarım için HIDL'ye geçme veya HIDL'den veri alma ya da verileri: Sahiplik her zaman çağrı işlevinde kalır. Veri kullanımı yalnızca çağrılan işlev süresince devam eder ve yok edilebilir işlevi geri döndüğünden emin olun.
Geçiş modunu kullan
Android'in önceki sürümlerini çalıştıran cihazları Android O'ya güncellemek için şunları yapabilirsiniz: hem geleneksel (ve eski) HAL'leri hem de Birleştirilmiş ve aynı işlem (geçiş) modlarında HAL. Bu sarmalama hem HAL hem de Android çerçevesine göre şeffaf olması gerekir.
Geçiş modu, yalnızca C++ istemcileri ve uygulamaları için kullanılabilir. Android'in önceki sürümlerini çalıştıran cihazlarda Java'da yazılmış HAL'ler yoktur, bu nedenle Java HAL'leri doğası gereği bağlayıcıdır.
Geçiş üstbilgisi dosyaları
Bir .hal
dosyası derlendiğinde, hidl-gen
şunları üretir:
başlıklara ek olarak BsFoo.h
ek geçiş başlık dosyası
bağlayıcı iletişim için kullanılır. bu başlık,
dlopen
ed. Geçiş HAL'leri her zaman
olarak adlandırılırlar. Çoğu durumda, geçiş yöntemleri doğrudan
işlev çağrısı (aynı iş parçacığı). oneway
yöntem kendi iş parçacığında çalışıyor
HAL'nin bunları işlemesini beklemek gibi olmadığından (bu, HAL
(geçiş modunda oneway
yöntemlerini kullanan) iş parçacığı açısından güvenli olmalıdır.
IFoo.hal
ile BsFoo.h
, HIDL tarafından oluşturulan HIDL'yi kapsar
ek özellikler sağlamak için başka yöntemler de (oneway
işlemler başka bir iş parçacığında çalıştırılır). Bu dosya şuna benzer:
BpFoo.h
, bununla birlikte bağlayıcı kullanarak IPC'yi iletmek yerine
ve istenen işlevlerin doğrudan çağrılmasıdır. Gelecekteki HAL uygulamaları
birden fazla uygulama sağlayabilir, örneğin FooFast HAL ve
FooVerify HAL. Bu gibi durumlarda, her ek uygulama için
(ör. PTFooFast.cpp
ve
PTFooAccurate.cpp
) tıklayın.
Geçiş HAL'lerini bağlama
Geçiş modunu destekleyen HAL uygulamalarını bağlayabilirsiniz. Örneğin,
HAL arayüzü a.b.c.d@M.N::IFoo
, iki paket oluşturulur:
a.b.c.d@M.N::IFoo-impl
HAL uygulamasını içerir veIFoo* HIDL_FETCH_IFoo(const char* name)
işlevini gösterir. Şu tarihte: eski cihazlarda, bu paketdlopen
HIDL_FETCH_IFoo
kullanılarak örneklendirilir. Temel kodu oluşturabilirsiniz.hidl-gen
,-Lc++-impl
ve-Landroidbp-impl
.a.b.c.d@M.N::IFoo-service
Geçiş HAL'sini açar ve kendisini bağlayıcı bir hizmet olarak kaydederek, aynı HAL uygulamasını etkinleştirir. hem geçiş hem de bağlayıcı olarak kullanılmasını sağlar.
IFoo
türünde, bir örneğe erişmek için sp<IFoo>
IFoo::getService(string name, bool getStub)
yöntemini çağırabilirsiniz
/ IFoo
. getStub
doğruysa getService
HAL'yi yalnızca geçiş modunda açmaya çalışır. getStub
ise
false, getService
bağlayıcı bir hizmet bulmaya çalışır; eğer
başarısız olursa geçiş hizmetini bulmaya çalışır. getStub
parametresi,
defaultPassthroughServiceImplementation
. (
Android O tamamen bağlı cihazlardır. Bu nedenle, bir hizmeti geçiş modunda açma
izin verilmez.)
HIDL dil bilgisi
HIDL dili tasarımı gereği C'ye benzer (ancak C'yi kullanmaz)
. Aşağıda açıklanmayan tüm noktalama işaretleri (bariz şekilde kullanılan kullanım
(=
ve |
) dil bilgisinin bir parçası.
Not: HIDL kodu stiliyle ilgili ayrıntılar için şuraya bakın: Kod Stil Kılavuzu.
/** */
, doküman yorumunu gösterir. Bu düzenlemeler, yalnızca tür, yöntem, alan ve enum değer bildirimlerine izin verir./* */
, çok satırlı bir yorumu gösterir.//
, satırın sonundaki yorumu gösterir. Şuralardan://
, yeni satırlar diğer tüm boşluklarla aynıdır.- Aşağıdaki örnek dilbilgisinde,
//
dilinden satırı, dilbilgisinin bir parçası değildir, bunun yerine dilbilgisi hakkında bir yorumdur. [empty]
, terimin boş olabileceği anlamına gelir.?
harfinin veya terimin ardından gelen kelime isteğe bağlı olduğu anlamına gelir....
, şununla sıfır veya daha fazla öğe içeren diziyi gösterir: noktalama işaretleri belirtilir. HIDL'de değişken argümanlar yoktur.- Sıra öğelerini virgülle ayırın.
- Noktalı virgüller, son öğe de dahil olmak üzere her öğeyi sonlandırır.
- BÜYÜK HARF, terminal olmayan bir ifadedir.
italics
, şunun gibi bir jeton ailesidir:integer
veyaidentifier
(standart C) ayrıştırma kuralları) görürsünüz.constexpr
, C stili bir sabit ifadedir (örneğin,1 + 1
ve1L << 3
).import_name
, nitelikli bir paket veya arayüz adıdır HIDL'de açıklandığı gibi Sürüm oluşturma.- Küçük
words
harfi, düz simgedir.
Örnek:
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