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

איור 1. רכיבי HAL
עליכם להטמיע את ה-HAL (והדרייבר) התואם לחומרה הספציפית שהמוצר מספק. בדרך כלל, הטמעות HAL מוטמעות במודולים של ספריות משותפות (קבצי .so
), אבל מכיוון ש-Android לא מחייבת אינטראקציה רגילה בין הטמעת HAL לבין מנהלי ההתקנים, אתם יכולים לעשות מה שמתאים ביותר למצב שלכם. עם זאת, כדי לאפשר למערכת Android לבצע אינטראקציה נכונה עם החומרה, חובה לפעול בהתאם לחוזה שמוגדר בכל ממשק HAL ספציפי לחומרה.
כדי להבטיח של-HALs יהיה מבנה צפוי, לכל ממשק HAL ספציפי לחומרה יש מאפיינים שמוגדרים ב-hardware/libhardware/include/hardware/hardware.h
. הממשק הזה מאפשר למערכת Android לטעון גרסאות נכונות של מודולי ה-HAL באופן עקבי. ממשק HAL מורכב משני רכיבים: מודולים ומכשירים.
מודולים של HAL
מודול מייצג את הטמעת ה-HAL באריזות, שמאוחסנת כספרייה משותפת (.so file
). קובץ הכותרת hardware/libhardware/include/hardware/hardware.h
מגדיר מבנה (hw_module_t
) שמייצג מודול ומכיל מטא-נתונים כמו הגרסה, השם והמחבר של המודול. מערכת Android משתמשת במטא-נתונים האלה כדי למצוא את מודול ה-HAL ולטעון אותו בצורה נכונה.
בנוסף, המבנה hw_module_t
מכיל הפניה למבנה אחר, hw_module_methods_t
, שמכיל הפניה לפונקציית open של המודול. הפונקציה הפתוחה הזו משמשת ליצירת תקשורת עם החומרה ש-HAL משמש כאבסוקציה שלה.
בדרך כלל, כל HAL ספציפי לחומרה מרחיב את המבנה הגנרי hw_module_t
עם מידע נוסף על פריט החומרה הספציפי. לדוגמה, ב-HAL של המצלמה, המבנה camera_module_t
מכיל את המבנה hw_module_t
יחד עם מצביעים אחרים לפונקציות ספציפיות למצלמה:
typedef struct camera_module { hw_module_t common; int (*get_number_of_cameras)(void); int (*get_camera_info)(int camera_id, struct camera_info *info); } camera_module_t;
כשמטמיעים HAL ויוצרים את המבנה של המודול, צריך לתת לו את השם HAL_MODULE_INFO_SYM
. דוגמה מ-HAL האודיו של Nexus 9:
struct audio_module HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = AUDIO_MODULE_API_VERSION_0_1, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = AUDIO_HARDWARE_MODULE_ID, .name = "NVIDIA Tegra Audio HAL", .author = "The Android Open Source Project", .methods = &hal_module_methods, }, };
מכשירי HAL
מכשיר הוא אבסוקציה של החומרה של המוצר. לדוגמה, מודול אודיו יכול להכיל מכשיר אודיו ראשי, מכשיר אודיו USB או מכשיר אודיו A2DP ב-Bluetooth.
המכשיר מיוצג על ידי המבנה hw_device_t
. בדומה למודול, לכל סוג מכשיר מוגדרת גרסה מפורטת של hw_device_t
הגנרי שמכילה מצביע פונקציות לתכונות ספציפיות של החומרה. לדוגמה, סוג המבנה audio_hw_device_t
מכיל מצביעים לפונקציות של פעולות של מכשירי אודיו:
struct audio_hw_device { struct hw_device_t common; /** * used by audio flinger to enumerate what devices are supported by * each audio_hw_device implementation. * * Return value is a bitmask of 1 or more values of audio_devices_t */ uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); ... }; typedef struct audio_hw_device audio_hw_device_t;
בנוסף למאפיינים הרגילים האלה, כל ממשק HAL ספציפי לחומרה יכול להגדיר עוד תכונות ודרישות משלו. פרטים נוספים זמינים במסמכי העזרה של HAL ובהוראות הנפרדות לכל HAL.
פיתוח מודולים של HAL
הטמעות HAL מובנות בקובצי המודולים (.so
) ומקושרות באופן דינמי על ידי Android במקרים הרלוונטיים. כדי ליצור את המודולים, יוצרים קובצי Android.mk
לכל הטמעת HAL ומפנים אותם לקובצי המקור. באופן כללי, יש לתת לספריות המשותפות שמות בפורמט מסוים כדי שאפשר יהיה למצוא אותן ולטעון אותן בצורה תקינה. סכמת השמות משתנה מעט ממודול למודול, אבל היא פועלת לפי התבנית הכללית: <module_type>.<device_name>
.