חיישנים AIDL HAL

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

החיישנים בטכנולוגיית AIDL HAL זמינים ב-Android 13 גבוהים יותר עבור מכשירים חדשים ומשודרגים. טכנולוגיית AIDL HAL של החיישנים, שמבוססת על באמצעות Sensors HAL 2.1 ממשק AIDL HAL וגם חושף את סוגי חיישן ה-IMU עם הצירים והציר המוגבל.

ממשק AIDL HAL

מקור התיעוד העיקרי של החיישנים AIDL HAL נמצא בתקן HAL הגדרה ב- hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl.

הטמעת החיישנים AIDL HAL

כדי להטמיע את החיישנים AIDL HAL, על האובייקט להרחיב את ISensors וליישם את כל הפונקציות שמוגדרות hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl.

אתחול HAL

חובה לאתחל את ממשק ה-HAL של החיישנים על ידי מסגרת החיישן של Android לפני . ה-framework קורא לפונקציה initialize() כדי לספק לחיישן HAL: שני תיאורי FMQ וסמן אחד אובייקט ISensorsCallback.

טכנולוגיית HAL משתמשת במתאר הראשון כדי ליצור את ה-FMQ מסוג אירוע שמשמש לכתיבת החיישן אירועים למסגרת. פרוטוקול HAL משתמש במתאר השני כדי ליצור את ה-Wake נעילת FMQ המשמש לסנכרון כש-HAL משחרר את התכונה 'נעילת מצב שינה' שלו למשך WAKE_UP אירועי חיישנים. ה-HAL חייב לשמור מצביע לאובייקט ISensorsCallback, כדי שיכול להפעיל את כל פונקציות הקריאה החוזרת (callback) הנדרשות.

הפונקציה initialize() חייבת להיות הפונקציה הראשונה שנקראה במהלך אתחול תקן HAL של החיישנים.

חשיפת חיישנים זמינים

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

אם כמה חיישנים חולקים את אותו סוג חיישן ואותו מאפיין יציאה ממצב שינה, החיישן הראשון ברשימה נקרא חיישן ברירת המחדל והוא מוחזר אפליקציות שמשתמשות בgetDefaultSensor(int sensorType, bool wakeUp) מותאמת אישית.

רשימת היציבות של החיישנים

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

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

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

הגדרת חיישנים

לפני הפעלת החיישן, יש להגדיר את החיישן עם דגימה תקופה וזמן אחזור מקסימלי לדיווח באמצעות הפונקציה batch().

תמיד אפשר להגדיר מחדש את החיישן באמצעות batch() ללא של אובדן נתוני חיישנים.

תקופת דגימה

לתקופת הדגימה יש משמעות שונה בהתאם לסוג החיישן מוגדר:

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

לקבלת מידע על האינטראקציה בין תקופת דגימה לבין חיישן למצבי דיווח, ראו מצבי דיווח.

זמן אחזור מקסימלי לדיווח

זמן האחזור המקסימלי לדיווח קובע את הזמן המקסימלי בננו-שניות, אירועים יכולים להתעכב ולאחסן אותם ב-FIFO של החומרה לפני שהם כותבים אותם אירוע FMQ דרך HAL בזמן שה-SoC לא פעיל.

הערך אפס מציין שצריך לדווח על האירועים ברגע שהם או לרוקן את ה-FIFO ברגע אירוע אחד מהחיישן נמצא ב-FIFO.

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

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

לכל אירוע משויכת חותמת זמן. עיכוב המועד שבו אירוע מדווח אינו יכול להשפיע על חותמת הזמן של האירוע. חותמת הזמן חייבת להיות מדויק ותואמות לזמן שבו האירוע התרחש פיזית. המועד שבו דווח.

מידע נוסף ודרישות בנוגע לדיווח על אירועי חיישנים זמן אחזור מקסימלי שאינו אפס לדיווח, ראה אצווה.

הפעלת החיישנים

ה-framework מפעיל ומשבית חיישנים באמצעות הפונקציה activate(). לפני הפעלת החיישן, צריך להגדיר את החיישן במסגרת המסגרת באמצעות batch().

לאחר השבתת החיישן, אסור לאירועי חיישן נוספים מאותו חיישן להיכתב אל ה-Event FMQ.

חיישני ניקוי

אם החיישן מוגדר לאצוות נתונים של חיישנים, המסגרת יכולה לאלץ טעינה מיידית של אירועי חיישנים מרובים באמצעות הפעלה של flush(). הדבר גורם שכל אירועי החיישנים הארוכים של נקודת האחיזה של החיישן שצוין יחולו באופן מיידי שנכתבו ל-Event FMQ. חובה להוסיף אירוע ריקון של חיישנים בסיום אירועי החיישן שנכתבים כתוצאה מקריאה אל flush()

הניקוי מתבצע באופן אסינכרוני (כלומר, הפונקציה חייבת להחזיר ). אם בהטמעה נעשה שימוש ב-FIFO אחד לכמה חיישנים, ה-FIFO ואירוע 'הניקוי' יתווסף רק לחיישן שצוין.

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

אם קוראים לפונקציה flush() לחיישן חד-פעמי, flush() צריך להחזיר BAD_VALUE ולא ליצור אירוע ריק באופן מלא.

כתיבת אירועי חיישן ב-FMQ

רכיב FMQ לאירועים משמש את חיישני HAL כדי לדחוף אירועי חיישנים למכשיר Android מסגרת החיישן.

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

כשחיישן HAL של החיישנים כתב את המספר הרצוי של אירועי חיישן אירוע FMQ, תוסף ה-HAL של החיישנים חייב להודיע למסגרת שהאירועים יהיו מוכנים עד כותב את הביט EventQueueFlagBits::READ_AND_PROCESS ל-Event FMQ EventFlag::wake. ניתן ליצור את ה-Eventflag מ-FMQ לאירוע באמצעות EventFlag::createEventFlag וה-getEventFlagWord() של ה-FMQ לאירוע מותאמת אישית.

החיישן AIDL HAL תומך גם ב-write וגם ב-writeBlocking ב-FMQ של האירוע. הטמעת ברירת המחדל מספקת חומר עזר לשימוש ב-write. אם נעשה שימוש בפונקציה writeBlocking, יש להגדיר את הדגל readNotification לערך EventQueueFlagBits::EVENTS_READ, שנקבע על ידי ה-framework בזמן קריאת הנתונים מ-Event FMQ. יש להגדיר את סימון ההתראה לכתיבה לערך EventQueueFlagBits::READ_AND_PROCESS, כדי להודיע למסגרת שהאירועים נכתבו אל ה-Event FMQ.

אירועי WAKE_UP

אירועי WAKE_UP הם אירועי חיישנים שגורמים למעבד האפליקציות (AP) לקום ולטפל באירוע מיד. בכל פעם שנכתב אירוע WAKE_UP ל-Event FMQ, לחיישן HAL של החיישנים חייב להיות מנעול מצב שינה כדי לוודא המערכת לא יכולה להיכנס למצב שינה עד שה-framework יוכל לטפל באירוע. עם קבלת WAKE_UP, ה-framework מאבטח מצב שינה משלו, וכך מאפשר חיישן HAL לשחרור השחרור של נעילת מצב שינה. לסנכרון כאשר HAL של החיישנים משחררים את ה-wake Lock. יש להשתמש ב-FMQ מסוג Wake Lock.

חובה להשתמש ב-HAL של החיישנים כדי לקבוע את מספר ה-WAKE_UP ב-Wake Lock FMQ אירועים שטופלו על ידי ה-framework. פרוטוקול HAL צריך לשחרר רק את ה-War Lock שלו עבור WAKE_UP אירועים אם המספר הכולל של אירועי WAKE_UP שלא טופלו הוא אפס. לאחר טיפול באירועי חיישנים, ה-framework סופר את מספר האירועים מסומן כאירועים WAKE_UP וכותב את המספר הזה בחזרה ל-FMQ מסוג Wake Lock.

ה-framework מגדיר את פעולת הכתיבה WakeLockQueueFlagBits::DATA_WRITTEN התראה במכשיר ה-FMQ לנעילת ההשכמה בכל פעם שהיא כותבת נתונים ל-FMQ מסוג Wake Lock.

חיישנים דינמיים

חיישנים דינמיים הם חיישנים שלא נמצאים פיזית במכשיר אבל יכולים ישמשו כקלט למכשיר, כגון בקר משחקים עם מד תאוצה.

כשמחברים חיישן דינמי, הפונקציה onDynamicSensorConnected פועלת הקריאה ISensorsCallback צריכה להתבצע מתוך תקן ה-HAL של החיישנים. פעולה זו שולחת התראה של החיישן הדינמי החדש ומאפשרים שליטה בחיישן דרך ה-framework וכדי שהלקוחות יצטרכו לצרוך את האירועים של החיישן.

באופן דומה, כשחיישן דינמי מנותק, חובה לקרוא לפונקציה onDynamicSensorDisconnected ב-ISensorsCallback שהמסגרת יכולה להסיר כל חיישן שכבר לא זמין.

ערוץ ישיר

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

הפונקציות registerDirectChannel() ו-unregisterDirectChannel() יוצרות או להרוס ערוץ ישיר חדש.

מצבי פעולה

הפונקציה setOperationMode() מאפשרת ל-framework להגדיר חיישן כך שהמסגרת תוכל להחדיר נתוני חיישן לחיישן. האפשרות הזאת שימושית במקרים במיוחד עבור אלגוריתמים שקיימים מתחת ל-framework.

בדרך כלל משתמשים בפונקציה injectSensorData() כדי לדחוף תפעול לחיישן HAL של החיישנים. ניתן להשתמש בפונקציה גם כדי להחדיר חיישן אירועים בחיישן ספציפי.

אימות

כדי לבדוק את ההטמעה של מדידת HAL של החיישנים, יש להריץ את החיישן CTS ו-VTS בדיקות.

בדיקות CTS

בדיקות CTS של החיישנים קיימות גם בבדיקות CTS אוטומטיות וגם באימות CTS ידני אפליקציה.

הבדיקות האוטומטיות ממוקמות ב: cts/tests/sensor/src/android/hardware/cts. הבדיקות האלה מאמתות את הפונקציונליות הרגילה של החיישנים, כמו הפעלה מחיישנים, מאצווה ובקצבי אירועים של חיישנים.

בדיקות ה-CTS Verifier נמצאות ב: cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. בבדיקות האלה נדרש קלט ידני ממפעיל הבדיקה כדי לוודא שהחיישנים מדווחות ערכים מדויקים.

חשוב מאוד לעבור את בדיקות ה-CTS כדי לוודא שהמכשיר שנמצא בבדיקה עומד בדרישות כל הדרישות לגבי CDD.

בדיקות VTS

בדיקות VTS של החיישנים AIDL HAL ממוקמות ב: hardware/interfaces/sensors/aidl/vts/. הבדיקות האלה מבטיחות שרכיבי HAL של החיישנים הוטמעו בצורה תקינה ושכל בדרישות ב-ISensors.aidl וב-ISensorsCallback.aidl מתקיימות כראוי.

אתחול HAL

צריך לתמוך בפונקציה initialize() כדי ליצור ערוצי FMQ בין framework ו-HAL.

חשיפת חיישנים זמינים

בחיישן AIDL HAL של החיישנים, הפונקציה getSensorsList() חייבת להחזיר את אותו הערך במהלך הפעלה אחת של מכשיר, גם בכל החיישנים, HAL מופעל מחדש. דרישה חדשה של הפונקציה getSensorsList() היא חייבת להחזיר את אותו ערך במהלך אתחול של מכשיר אחד, גם בכל החיישנים מפעילים מחדש HAL. כך אפשר כדי לנסות ליצור מחדש חיבורי חיישן, אם שרת המערכת מופעלת מחדש. הערך שמוחזר על ידי getSensorsList() יכול להשתנות אחרי שהמכשיר מבצע הפעלה מחדש.

כתיבת אירועי חיישן ב-FMQ

במקום להמתין לקריאה אל poll(), בחיישנים AIDL HAL, פרוטוקול HAL חייב לכתוב באופן יזום אירועי חיישן ל-FMQ של האירוע בכל פעם שאירועי חיישן זמינים. קוד HAL אחראי גם לכתיבת הביטים הנכונים EventFlag כדי לגרום לקריאת FMQ בתוך המסגרת.

אירועי WAKE_UP

בגרסה HAL 1.0 של החיישנים, תכונת HAL הצליחה לשחרר את השחרור ממצב שינה בכל מכשיר WAKE_UP אירוע בכל שיחה עתידית אל poll() אחרי שפורסמה ב-WAKE_UP poll() כי כך המסגרת עיבדה את כל החיישנים אירועים והתכונה 'נעילת מצב שינה' בוצעה, אם יש צורך. כי, בחיישנים, AIDL עם AI, היא לא מקבלת יותר הודעה כשמערכת ה-framework מעבדת אירועים שכתוב במכשיר ה-FMQ, רכיב ה-FMQ לנעילת Wake מאפשר ל-framework לתקשר HAL כשטיפל ב-WAKE_UP אירועים.

בחיישן AIDL HAL של החיישנים, נעילת מצב השינה מאובטחת על ידי חיישן HAL של החיישנים למשך WAKE_UP האירועים חייבים להתחיל ב-SensorsHAL_WAKEUP.

חיישנים דינמיים

חיישנים דינמיים הוחזרו באמצעות הפונקציה poll() בחיישנים HAL 1.0. לחיישן AIDL HAL נדרשים onDynamicSensorsConnected תתבצע קריאה אל onDynamicSensorsDisconnected בISensorsCallback בכל פעם שהוא דינמי שינויים בחיבורי החיישנים. הקריאות החוזרות האלה זמינות כחלק מצביע ISensorsCallback שמסופק באמצעות הפונקציה initialize().

מצבי פעולה

צריכה להיות תמיכה במצב DATA_INJECTION לחיישנים של WAKE_UP.

תמיכה בריבוי HAL

החיישנים AIDL HAL תומכים בריבוי HAL באמצעות Sensors Multi-HAL framework. עבור פרטים על ההטמעה: ניוד מחיישנים עם HAL 2.1.