שכבת ההפשטה של חומרת החיישנים (HAL) היא הממשק בין מסגרת החיישנים של אנדרואיד לבין חיישני המכשיר, כגון מד תאוצה או גירוסקופ. החיישנים HAL מגדירים את הפונקציות שיש ליישם כדי לאפשר למסגרת לשלוט בחיישנים.
חיישנים HAL 2.0 זמין באנדרואיד 10 ומעלה עבור מכשירים חדשים ומשודרגים. חיישנים HAL 2.0 מבוסס על חיישנים HAL 1.0 אבל יש כמה הבדלים מרכזיים, שמונעים ממנו להיות תואם לאחור. חיישנים HAL 2.0 משתמש בתורי הודעות מהירים (FMQs) כדי לשלוח אירועי חיישן מה-HAL לתוך מסגרת החיישנים של אנדרואיד.
חיישנים HAL 2.1 זמין באנדרואיד 11 ואילך עבור מכשירים חדשים ומשודרגים. חיישנים HAL 2.1 הוא איטרציה של חיישני HAL 2.0 שחושפת את סוג החיישן HINGE_ANGLE ומעדכנת שיטות שונות כדי לקבל את סוג HINGE_ANGLE
.
ממשק HAL 2.1
המקור העיקרי לתיעוד עבור חיישנים HAL 2.1 נמצא בהגדרת HAL ב- hardware/interfaces/sensors/2.1/ISensors.hal . אם יש סתירה בין דרישות בין דף זה לבין ISensors.hal
, השתמש בדרישה ב- ISensors.hal
.
ממשק HAL 2.0
המקור העיקרי לתיעוד עבור חיישנים HAL 2.0 נמצא בהגדרת HAL ב- hardware/interfaces/sensors/2.0/ISensors.hal . אם יש סתירה בין דרישות בין דף זה לבין ISensors.hal
, השתמש בדרישה ב- ISensors.hal
.
יישום חיישנים HAL 2.0 ו-HAL 2.1
כדי ליישם חיישנים HAL 2.0 או 2.1, אובייקט חייב להרחיב את ממשק ISensors
וליישם את כל הפונקציות המוגדרות ב 2.0/ISensors.hal
או 2.1/ISensors.hal
.
אתחול ה-HAL
יש לאתחל את ה-SENSYS HAL על ידי מסגרת החיישנים של Android לפני שניתן יהיה להשתמש בו. המסגרת קוראת לפונקציה initialize()
עבור HAL 2.0 ולפונקציה initialize_2_1()
עבור HAL 2.1 כדי לספק שלושה פרמטרים ל-SENSORS HAL: שני מתארי FMQ ומצביע אחד לאובייקט ISensorsCallback
.
ה-HAL משתמש במתאר הראשון כדי ליצור את ה- Event FMQ המשמש לכתיבת אירועי חיישנים למסגרת. ה-HAL משתמש במתאר השני כדי ליצור את Wake Lock FMQ המשמש לסנכרון כאשר ה-HAL משחרר את נעילת ההתעוררות שלו עבור אירועי חיישן WAKE_UP
. ה-HAL חייב לשמור מצביע לאובייקט ISensorsCallback
כך שניתן יהיה להפעיל את כל פונקציות ההתקשרות הנחוצות.
הפונקציה initialize()
או initialize_2_1()
חייבת להיות הפונקציה הראשונה שנקראת בעת אתחול ה-SENSORS HAL.
חשוף חיישנים זמינים
כדי לקבל רשימה של כל החיישנים הסטטיים הזמינים במכשיר, השתמש בפונקציה getSensorsList()
ב-HAL 2.0 ובפונקציה getSensorsList_2_1()
ב-HAL 2.1. פונקציה זו מחזירה רשימה של חיישנים, כל אחד מזוהה באופן ייחודי באמצעות הידית שלו. הידית של חיישן נתון אינה חייבת להשתנות כאשר התהליך המארח את חיישני HAL מתחיל מחדש. נקודות האחיזה עשויות להשתנות במהלך אתחולים מחדש של המכשיר, וכן אתחול מחדש של שרת המערכת.
אם מספר חיישנים חולקים את אותו סוג חיישן ומאפיין התעוררות, החיישן הראשון ברשימה נקרא חיישן ברירת המחדל ומוחזר לאפליקציות המשתמשות בפונקציית getDefaultSensor(int sensorType, bool wakeUp)
.
רשימת יציבות חיישנים
לאחר הפעלה מחדש של Sensors HAL, אם הנתונים המוחזרים על ידי getSensorsList()
או getSensorsList_2_1()
מצביעים על שינוי משמעותי בהשוואה לרשימת החיישנים שאוחזרו לפני ההפעלה מחדש, המסגרת מפעילה הפעלה מחדש של זמן הריצה של אנדרואיד. שינויים משמעותיים ברשימת החיישנים כוללים מקרים שבהם חיישן עם ידית נתונה חסר או ששינה תכונות, או שבהם הוכנסו חיישנים חדשים. למרות שהפעלה מחדש של זמן הריצה של אנדרואיד מפריעה למשתמש, היא נדרשת מכיוון שמסגרת אנדרואיד אינה יכולה עוד לעמוד בחוזה ה-API של אנדרואיד שחיישנים סטטיים (לא דינמיים) אינם משתנים במהלך חייה של אפליקציה. זה עשוי גם למנוע מהמסגרת לשחזר בקשות חיישנים פעילות שנעשו על ידי אפליקציות. לכן, מומלץ לספקי HAL למנוע שינויים ברשימת החיישנים שניתן להימנע מהם.
כדי להבטיח ידיות חיישן יציבות, ה-HAL חייב למפות באופן דטרמיניסטי חיישן פיזי נתון במכשיר לידית שלו. למרות שממשק ה-SENSORS HAL לא מחייב יישום ספציפי, למפתחים יש מספר אפשרויות זמינות כדי לעמוד בדרישה זו.
לדוגמה, ניתן למיין את רשימת החיישנים באמצעות שילוב של התכונות הקבועות של כל חיישן, כגון ספק, דגם וסוג חיישן. אפשרות נוספת מסתמכת על העובדה שמערכת החיישנים הסטטיים של המכשיר קבועה בחומרה, כך שה-HAL צריך לדעת מתי כל החיישנים הצפויים סיימו את האתחול לפני החזרה מ- getSensorsList()
או getSensorsList_2_1()
. רשימה זו של חיישנים צפויים ניתנת לקומפילציה לתוך הבינארי HAL או לאחסן בקובץ תצורה במערכת הקבצים, וניתן להשתמש בסדר ההופעה כדי לגזור ידיות יציבות. למרות שהפתרון הטוב ביותר תלוי בפרטי ההטמעה הספציפיים של ה-HAL שלך, הדרישה העיקרית היא שידיות החיישנים לא ישתנו במהלך התחלות מחדש של HAL.
הגדר חיישנים
לפני הפעלת חיישן, יש להגדיר את החיישן עם תקופת דגימה והשהיית דיווח מקסימלית באמצעות הפונקציה batch()
.
חיישן חייב להיות מסוגל להגדיר מחדש בכל עת באמצעות batch()
ללא אובדן נתוני החיישן.
תקופת הדגימה
לתקופת הדגימה יש משמעות שונה בהתבסס על סוג החיישן המוגדר:
- רציף: אירועי חיישן נוצרים בקצב רציף.
- On-change: אירועים לא נוצרים מהר יותר מתקופת הדגימה ועשויים להיווצר בקצב איטי יותר מתקופת הדגימה אם הערך הנמדד לא משתנה.
- הזדמנות אחת: מתעלמים מתקופת הדגימה.
- מיוחד: לפרטים נוספים, ראה סוגי חיישנים .
כדי ללמוד על האינטראקציה בין תקופת דגימה לבין מצבי הדיווח של חיישן, ראה מצבי דיווח .
זמן אחזור מרבי לדיווח
השהיה המקסימלית לדיווח קובעת את הזמן המקסימלי בננו-שניות שניתן לעכב אירועים ולאחסן אותם ב-FIFO החומרה לפני כתיבה ל-Event FMQ דרך HAL בזמן שה-SoC ער.
ערך של אפס מסמל שיש לדווח על האירועים ברגע שהם נמדדים, או לדלג על ה-FIFO לחלוטין, או לרוקן את ה-FIFO ברגע שאירוע אחד מהחיישן קיים ב-FIFO.
לדוגמה, מד תאוצה המופעל ב-50 הרץ עם חביון דיווח מקסימלי של אפס טריגרים מפריע 50 פעמים בשנייה כאשר ה-SoC ער.
כאשר זמן האחזור המרבי לדיווח גדול מאפס, אין צורך לדווח על אירועי חיישן ברגע שהם מזוהים. ניתן לאחסן אירועים באופן זמני ב-FIFO החומרה ולדווח באצווה, כל עוד אין אירוע מתעכב יותר מהשהייה המקסימלית לדיווח. כל האירועים מאז האצווה הקודמת מוקלטים ומוחזרים בבת אחת. זה מקטין את מספר ההפסקות הנשלחות ל-SoC ומאפשר ל-SoC לעבור למצב צריכת חשמל נמוכה יותר בזמן שהחיישן לוכד ומקבץ נתונים.
לכל אירוע יש חותמת זמן המשויכת אליו. דחיית השעה שבה מדווח אירוע אינה יכולה להשפיע על חותמת הזמן של האירוע. חותמת הזמן חייבת להיות מדויקת ולהתאים לזמן שבו האירוע התרחש פיזית, לא לזמן שבו דווח.
למידע נוסף ודרישות לגבי דיווח על אירועי חיישנים עם זמן אחזור דיווח מקסימלי שאינו אפס, ראה אצווה .
הפעל חיישנים
המסגרת מאפשרת ומשביתה חיישנים באמצעות הפונקציה activate()
. לפני הפעלת חיישן, על המסגרת תחילה להגדיר את החיישן באמצעות batch()
.
לאחר ביטול הפעלה של חיישן, אסור לכתוב אירועי חיישן נוספים מאותו חיישן ל- Event FMQ.
חיישני שטיפה
אם חיישן מוגדר לנתוני חיישן אצווה, המסגרת יכולה לכפות ניקוי מיידי של אירועי חיישן אצווה על ידי קריאת flush()
. זה גורם לאירועי החיישן המצטברים עבור ידית החיישן שצוינה להיכתב באופן מיידי ל- Event FMQ. ה-SENSORS HAL חייבת לצרף אירוע של flush complete לסוף אירועי החיישן שנכתבים כתוצאה מקריאה ל- flush()
.
ההדחה מתרחשת באופן אסינכרוני (כלומר, פונקציה זו חייבת לחזור מיד). אם היישום משתמש ב-FIFO בודד עבור מספר חיישנים, ה-FIFO הזה נשטף ואירוע השלמה של השטיפה מתווסף רק עבור החיישן שצוין.
אם לחיישן שצוין אין FIFO (אין אפשרות חציצה), או אם ה-FIFO היה ריק בזמן הקריאה, flush()
עדיין חייב להצליח ולשלוח אירוע השלמה של שטיפה עבור אותו חיישן. זה חל על כל החיישנים מלבד חיישני צילום אחד.
אם flush()
נקרא עבור חיישן חד-פעמי, אז flush()
חייב להחזיר BAD_VALUE
ולא ליצור אירוע השלמה של flush.
כתוב אירועי חיישן ל-FMQ
ה-Event FMQ משמש את ה-SENSORS HAL כדי לדחוף אירועי חיישן למסגרת החיישנים של אנדרואיד.
ה-Event FMQ הוא FMQ מסונכרן, מה שאומר שכל ניסיון לכתוב יותר אירועים ל-FMQ מהשטח הפנוי מאפשר תוצאה של כתיבה נכשלת. במקרה כזה, ה-HAL צריך לקבוע אם לכתוב את קבוצת האירועים הנוכחית כשתי קבוצות קטנות יותר של אירועים או לכתוב את כל האירועים יחד כאשר מספיק מקום פנוי.
כאשר ה-Sensors HAL כתב את המספר הרצוי של אירועי החיישנים ל-Event FMQ, על ה-SENSYS HAL להודיע למסגרת שהאירועים מוכנים על ידי כתיבת ה- EventQueueFlagBits::READ_AND_PROCESS
לפונקציית EventFlag::wake
של ה-Event FMQ. ניתן ליצור את ה-EventFlag מה-Event FMQ באמצעות EventFlag::createEventFlag
והפונקציה getEventFlagWord()
של Event FMQ.
חיישנים HAL 2.0/2.1 תומכים הן write
והן writeBlocking
ב- Event FMQ. יישום ברירת המחדל מספק הפניה לשימוש write
. אם נעשה שימוש בפונקציית writeBlocking
, יש להגדיר את דגל readNotification
ל- EventQueueFlagBits::EVENTS_READ
, אשר מוגדר על ידי המסגרת כאשר היא קוראת אירועים מה-Event FMQ. יש להגדיר את דגל הודעת הכתיבה ל- EventQueueFlagBits::READ_AND_PROCESS
, אשר מודיע למסגרת שאירועים נכתבו ל-Event FMQ.
אירועי WAKE_UP
אירועי WAKE_UP
הם אירועי חיישן שגורמים למעבד היישומים (AP) להתעורר ולטפל באירוע באופן מיידי. בכל פעם שנכתב אירוע WAKE_UP
ל-Event FMQ, ה-SENSYS HAL חייב לאבטח נעילת ערות כדי להבטיח שהמערכת תישאר ערה עד שהמסגרת תוכל להתמודד עם האירוע. עם קבלת אירוע WAKE_UP
, המסגרת מאבטחת את נעילת ההתעוררות שלה, ומאפשרת ל-Sensors HAL לשחרר את נעילת ההתעוררות שלו. כדי לסנכרן כאשר ה-Sensors HAL משחרר את נעילת ההתעוררות שלו, השתמש ב-Wke Lock FMQ.
ה-SENSYS HAL חייב לקרוא את Wake Lock FMQ כדי לקבוע את מספר אירועי WAKE_UP
שהמסגרת טיפלה בהם. ה-HAL צריך לשחרר את נעילת ההתעוררות שלו עבור אירועי WAKE_UP
רק אם המספר הכולל של אירועי WAKE_UP
שלא טופלו הוא אפס. לאחר טיפול באירועי חיישנים, המסגרת סופרת את מספר האירועים המסומנים כאירועי WAKE_UP
וכותבת את המספר הזה בחזרה ל-Wake Lock FMQ.
המסגרת מגדירה את הודעת הכתיבה של WakeLockQueueFlagBits::DATA_WRITTEN
ב-Wake Lock FMQ בכל פעם שהיא כותבת נתונים ל-Wake Lock FMQ.
חיישנים דינמיים
חיישנים דינמיים הם חיישנים שאינם חלק פיזית מהמכשיר אך יכולים לשמש כקלט למכשיר, כגון משחק משטח עם מד תאוצה.
כאשר חיישן דינמי מחובר, יש לקרוא לפונקציה onDynamicSensorConnected
ב- ISensorsCallback
מה-Sensors HAL. זה מודיע למסגרת של החיישן הדינמי החדש ומאפשר לשלוט בחיישן דרך המסגרת ולצרוך את אירועי החיישן על ידי לקוחות.
באופן דומה, כאשר חיישן דינמי מנותק, יש לקרוא לפונקציה onDynamicSensorDisconnected
ב- ISensorsCallback
כדי שהמסגרת תוכל להסיר כל חיישן שאינו זמין עוד.
ערוץ ישיר
ערוץ ישיר הוא שיטת פעולה שבה אירועי חיישנים נכתבים לזיכרון ספציפי במקום ל- Event FMQ עוקף את מסגרת החיישנים של Android. לקוח שרושם ערוץ ישיר חייב לקרוא את אירועי החיישן ישירות מהזיכרון ששימש ליצירת הערוץ הישיר ולא יקבל את אירועי החיישן דרך המסגרת. הפונקציה configDirectReport()
דומה ל- batch()
עבור פעולה רגילה ומגדירה את ערוץ הדיווח הישיר.
הפונקציות registerDirectChannel()
ו- unregisterDirectChannel()
יוצרות או משמידות ערוץ ישיר חדש.
מצבי פעולה
הפונקציה setOperationMode()
מאפשרת למסגרת להגדיר חיישן כך שהמסגרת תוכל להחדיר נתוני חיישן לחיישן. זה שימושי לבדיקה, במיוחד עבור אלגוריתמים שקיימים מתחת למסגרת.
הפונקציה injectSensorData()
ב-HAL 2.0 ופונקציה injectSensorsData_2_1()
ב-HAL 2.0 משמשת בדרך כלל כדי לדחוף פרמטרים תפעוליים לתוך ה-SENSORS HAL. ניתן להשתמש בפונקציה גם להזרקת אירועי חיישן לחיישן ספציפי.
מַתַן תוֹקֵף
כדי לאמת את היישום שלך של חיישנים HAL, הפעל את בדיקות החיישן CTS ו-VTS.
בדיקות CTS
בדיקות CTS של חיישנים קיימות הן בבדיקות CTS אוטומטיות והן באפליקציית CTS Verifier הידנית.
הבדיקות האוטומטיות ממוקמות ב- cts/tests/sensor/src/android/hardware/cts . בדיקות אלו מאמתות את הפונקציונליות הסטנדרטית של חיישנים, כגון הפעלת חיישנים, אצווה ושיעורי אירועי חיישנים.
בדיקות CTS Verifier ממוקמות ב- cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors . בדיקות אלו דורשות קלט ידני ממפעיל הבדיקה ומבטיחות שחיישנים מדווחים על ערכים מדויקים.
עמידה במבחני CTS היא קריטית כדי להבטיח שהמכשיר הנבדק עומד בכל דרישות ה-CDD.
בדיקות VTS
בדיקות VTS עבור חיישנים HAL 2.0 ממוקמות בחומרה/ממשקים/חיישנים/2.0/vts . בדיקות VTS עבור חיישנים HAL 2.1 ממוקמות בחומרה/ממשקים/חיישנים/2.1/vts . בדיקות אלו מבטיחות שה-Sensors HAL מיושם כהלכה ושכל הדרישות בתוך ISensors.hal
ו- ISensorsCallback.hal
מתקיימות כראוי.
שדרוג לחיישנים HAL 2.1 מ-2.0
בעת שדרוג ל-Sensors HAL 2.1 מ-2.0, יישום ה-HAL שלך חייב לכלול את השיטות initialize_2_1()
, getSensorsList_2_1()
ו- injectSensorsData_2_1()
יחד עם סוגי HAL 2.1. שיטות אלה חייבות לעמוד באותן דרישות המפורטות עבור HAL 2.0 לעיל.
מכיוון ש-HAL של גרסאות מינוריות חייבות לתמוך בכל הפונקציות מ-HAL קודמים, HALs 2.1 חייבים לתמוך באתחול כ-2.0 HAL. כדי למנוע את המורכבות של תמיכה בשתי גרסאות HAL, מומלץ מאוד להשתמש ב-Multi-HAL 2.1.
לדוגמא כיצד ליישם חיישנים 2.1 HAL משלך, ראה Sensors.h .
שדרוג לחיישנים HAL 2.0 מ-1.0
בעת שדרוג לחיישנים HAL 2.0 מ-1.0, ודא שהטמעת ה-HAL שלך עומדת בדרישות הבאות.
אתחול ה-HAL
יש לתמוך בפונקציה initialize()
כדי להקים FMQs בין המסגרת ל-HAL.
חשוף חיישנים זמינים
ב-Sensors HAL 2.0, הפונקציה getSensorsList()
חייבת להחזיר את אותו ערך במהלך אתחול של מכשיר בודד, אפילו על פני חיישנים. דרישה חדשה של הפונקציה getSensorsList()
היא שהיא חייבת להחזיר את אותו הערך במהלך אתחול של מכשיר בודד, אפילו על פני חיישני הפעלה מחדש של HAL. זה מאפשר למסגרת לנסות ליצור מחדש חיבורי חיישנים אם שרת המערכת יופעל מחדש. הערך המוחזר על ידי getSensorsList()
יכול להשתנות לאחר שהמכשיר מבצע אתחול מחדש.
כתוב אירועי חיישן ל-FMQ
במקום לחכות לקריאה של poll()
ב-Sensors HAL 2.0, ה-SENSORS HAL חייב לכתוב באופן יזום אירועי חיישן ל-Event FMQ בכל פעם שאירועי חיישן זמינים. ה-HAL אחראי גם לכתיבת הביטים הנכונים ל- EventFlag
כדי לגרום לקריאת FMQ בתוך המסגרת.
אירועי WAKE_UP
ב-Sencers HAL 1.0, ה-HAL הצליח לשחרר את נעילת ההתעוררות שלו עבור כל אירוע WAKE_UP
בכל קריאה נוספת ל- poll()
לאחר ש- WAKE_UP
פורסם ל- poll()
מכיוון שזה הצביע על כך שהמסגרת עיבדה את כל אירועי החיישן והשיגה נעילת התעוררות, במידת הצורך. מכיוון שבסנסורים HAL 2.0, ה-HAL כבר לא יודע מתי המסגרת עיבדה אירועים שנכתבו ל-FMQ, ה-Wake Lock FMQ מאפשר למסגרת לתקשר ל-HAL כאשר היא טיפלה באירועי WAKE_UP
.
ב-Sensors HAL 2.0, נעילת ההתעוררות המאובטחת על-ידי ה-SENSORS HAL לאירועי WAKE_UP
חייבת להתחיל עם SensorsHAL_WAKEUP
.
חיישנים דינמיים
חיישנים דינמיים הוחזרו באמצעות הפונקציה poll()
ב-Sensors HAL 1.0. חיישנים HAL 2.0 דורשים ש- onDynamicSensorsConnected
ו- onDynamicSensorsDisconnected
ב- ISensorsCallback
ייקראו בכל פעם שחיבורי חיישנים דינמיים משתנים. התקשרויות אלו זמינות כחלק ממצביע ISensorsCallback
המסופק באמצעות הפונקציה initialize()
.
מצבי פעולה
יש לתמוך במצב DATA_INJECTION
עבור חיישני WAKE_UP
בסנסורים HAL 2.0.
תמיכה ב-Multi-HAL
חיישני HAL 2.0 ו-2.1 תומכים ב-Multi-HAL באמצעות מסגרת Multi-HAL של חיישנים . לפרטי יישום, ראה העברה מחיישנים HAL 1.0 .