סביבת זמן ריצה של מרכז המידע (CHRE)

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

סביבת זמן הריצה של Context Hub‏ (CHRE) מספקת פלטפורמה משותפת להרצת אפליקציות במעבד עם צריכת חשמל נמוכה, עם API פשוט, סטנדרטי וידידותי להטמעה. ה-CHRE מאפשר ליצרני מכשירים ולשותפים מהימנים שלהם להעביר את העיבוד מה-AP כדי לחסוך בסוללה ולשפר תחומים שונים בחוויית המשתמש, וגם להפעיל תכונות מסוימות שפועלות תמיד ומודעות להקשר, במיוחד תכונות שכוללות יישום של למידת מכונה לחישה סביבתית.

מושגים מרכזיים

‫CHRE היא סביבת התוכנה שבה אפליקציות קטנות מקומיות, שנקראות אפליקציות ננו, פועלות במעבד עם צריכת חשמל נמוכה ומקיימות אינטראקציה עם המערכת הבסיסית באמצעות CHRE API משותף. כדי להאיץ את ההטמעה התקינה של ממשקי ה-API של CHRE, הטמעה לדוגמה של CHRE בפלטפורמות שונות כלולה ב-AOSP. ההטמעה לדוגמה כוללת קוד משותף והפשטות לחומרה ולתוכנה הבסיסיות באמצעות סדרה של שכבות הפשטה של פלטפורמה (PAL). אפליקציות ננו כמעט תמיד קשורות לאחת או יותר אפליקציות לקוח שפועלות ב-Android, ומבצעות אינטראקציה עם CHRE ואפליקציות ננו באמצעות ממשקי API של מערכת ContextHubManager עם גישה מוגבלת.

באופן כללי, אפשר להשוות בין הארכיטקטורה של CHRE לבין הארכיטקטורה של Android בכללותה. עם זאת, יש כמה הבדלים חשובים:

  • ‫CHRE תומכת בהרצה רק של אפליקציות ננו שפותחו בקוד Native (C או C++‎). אין תמיכה ב-Java.
  • בגלל מגבלות משאבים ומגבלות אבטחה, אי אפשר להשתמש ב-CHRE באפליקציות שרירותיות של צד שלישי ל-Android. רק אפליקציות מהימנות של המערכת יכולות לגשת אליו.

חשוב גם להבחין בין המושג CHRE לבין רכזת חיישנים. למרות שבדרך כלל משתמשים באותו חומרה כדי להטמיע את ה-sensor hub ואת CHRE, ‏ CHRE עצמו לא מספק את יכולות החיישן שנדרשות על ידי Android Sensors HAL. ‫CHRE קשור ל-Context Hub HAL, והוא פועל כלקוח של מסגרת חיישנים ספציפית למכשיר כדי לקבל נתוני חיישנים בלי לערב את ה-AP.

ארכיטקטורת ה-framework של CHRE

איור 1. ארכיטקטורת ה-framework של CHRE

Context Hub HAL

שכבת הפשטת החומרה (HAL) של Context Hub היא הממשק בין מסגרת Android לבין הטמעת CHRE במכשיר, שמוגדרת בכתובת hardware/interfaces/contexthub. ה-HAL של Context Hub מגדיר את ממשקי ה-API שדרכם מסגרת Android מגלה את רכזי ההקשר הזמינים ואת האפליקציות הזעירות שלהם, מנהלת אינטראקציה עם האפליקציות הזעירות האלה באמצעות העברת הודעות, ומאפשרת טעינה וביטול טעינה של אפליקציות זעירות. הטמעה לדוגמה של Context Hub HAL שפועלת עם הטמעה לדוגמה של CHRE זמינה בכתובת system/chre/host.

במקרה של סתירה בין התיעוד הזה לבין הגדרת ה-HAL, הגדרת ה-HAL היא הקובעת.

אתחול

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

טעינה ופריקה של אפליקציות ננו

Context Hub יכול לכלול קבוצה של אפליקציות ננו שכלולות בתמונת המכשיר ונטענות כש-CHRE מתחיל. האפליקציות האלה נקראות אפליקציות ננו שנטענות מראש, והן צריכות להיכלל בתשובה הראשונה האפשרית ל-queryApps().

ה-HAL של Context Hub תומך גם בטעינה ובפריקה של nanoapps באופן דינמי בזמן הריצה, באמצעות הפונקציות loadNanoApp() ו-unloadNanoApp(). אפליקציות Nano מסופקות ל-HAL בפורמט בינארי שספציפי לחומרה של CHRE ולהטמעה של התוכנה במכשיר.

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

הפעלה מחדש של Context Hub

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

סקירה כללית על מערכת CHRE

ה-CHRE מבוסס על ארכיטקטורה מונחית-אירועים, שבה יחידת החישוב העיקרית היא אירוע שמועבר לנקודת הכניסה לטיפול באירועים של אפליקציית ננו. למרות שמסגרת CHRE יכולה להיות מרובת-הליכים, אפליקציית ננו נתונה אף פעם לא מופעלת מכמה הליכים במקביל. מסגרת CHRE פועלת באינטראקציה עם אפליקציית ננו נתונה דרך אחת משלוש נקודות הכניסה של אפליקציית הננו (nanoappStart(),‏ nanoappHandleEvent() ו-nanoappEnd()) או דרך קריאה חוזרת שסופקה בקריאה קודמת ל-CHRE API. אפליקציות ננו פועלות באינטראקציה עם מסגרת CHRE והמערכת הבסיסית דרך CHRE API. ממשק CHRE API מספק קבוצה של יכולות בסיסיות וגם כלים לגישה לאותות הקשריים, כולל חיישנים, GNSS,‏ Wi-Fi,‏ WWAN ואודיו. אפשר להרחיב אותו עם יכולות נוספות שספציפיות לספק לשימוש בננו-אפליקציות שספציפיות לספק.

מערכת build

בעוד ש-Context Hub HAL ורכיבים נחוצים אחרים בצד ה-AP נוצרים לצד Android, יכול להיות שלקוד שפועל ב-CHRE יש דרישות שגורמות לו להיות לא תואם למערכת ה-build של Android, כמו הצורך בשרשרת כלים מיוחדת. לכן, פרויקט CHRE ב-AOSP מספק מערכת build פשוטה שמבוססת על GNU Make כדי לקמפל אפליקציות nano, ובאופן אופציונלי, את מסגרת CHRE לספריות שאפשר לשלב במערכת. יצרני מכשירים שמוסיפים תמיכה ב-CHRE צריכים לשלב תמיכה במערכת build במכשירי היעד שלהם ב-AOSP.

ממשק CHRE API נכתב בהתאם לתקן השפה C99, וההטמעה לדוגמה משתמשת בקבוצת משנה מוגבלת של C++11 שמתאימה לאפליקציות עם משאבים מוגבלים.

CHRE API

ממשק ה-API של CHRE הוא אוסף של קובצי כותרות ב-C שמגדירים את ממשק התוכנה בין אפליקציית nano לבין המערכת. היא נועדה להפוך את קוד אפליקציות הננו לתואם לכל המכשירים שתומכים ב-CHRE, כלומר לא צריך לשנות את קוד המקור של אפליקציית ננו כדי לתמוך בסוג חדש של מכשיר, אבל יכול להיות שיהיה צורך לבצע קומפילציה מחדש במיוחד עבור סט הפקודות של המעבד של מכשיר היעד או ממשק הבינארי של האפליקציה (ABI). הארכיטקטורה של CHRE ועיצוב ה-API גם מבטיחים תאימות בינארית של אפליקציות ננו בין גרסאות שונות של CHRE API. כלומר, אין צורך לבצע קומפילציה מחדש של אפליקציית ננו כדי להפעיל אותה במערכת שמטמיעה גרסה שונה של CHRE API בהשוואה ל-API היעד שאליו מתבצעת הקומפילציה של אפליקציית הננו. במילים אחרות, אם קובץ בינארי של אפליקציית ננו פועל במכשיר שתומך ב-CHRE API v1.3, והמכשיר הזה משודרג כך שיתמוך ב-CHRE API v1.4, אותו קובץ בינארי של אפליקציית הננו ימשיך לפעול. באופן דומה, אפשר להפעיל את האפליקציה הקטנה ב-CHRE API גרסה 1.2, והיא יכולה לקבוע בזמן הריצה אם היא דורשת יכולות מ-API גרסה 1.3 כדי להשיג את השימוש שלה, או אם היא יכולה לפעול, אולי עם ירידה הדרגתית בביצועים.

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

סיכום הגרסה

בדומה לסכימת ניהול הגרסאות של Android HIDL,‏ CHRE API פועל לפי ניהול גרסאות סמנטי. הגרסה הראשית מציינת תאימות בינארית, והגרסה המשנית גדלה כשמוצגות תכונות שתואמות לדורות קודמים. ממשק ה-API של CHRE כולל הערות בקוד המקור שמזהות באיזו גרסה הוצגה פונקציה או פרמטר, למשל @since v1.1.

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

סיכומים של כל גרסה זמינים במאמר version.h.

תכונות מערכת חובה

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

בנוסף לתכונות הליבה של המערכת שמוגדרות ב-CHRE API, יש גם תכונות חובה ברמת המערכת של CHRE שמוגדרות ברמת Context Hub HAL. המשמעותית ביותר מביניהן היא היכולת לטעון ולבטל טעינה של אפליקציות ננו באופן דינמי.

ספרייה רגילה של C/C++‎

כדי לצמצם את השימוש בזיכרון ואת מורכבות המערכת, יישומי CHRE צריכים לתמוך רק בקבוצת משנה של ספריות C ו-C++‎ סטנדרטיות ובתכונות שפה שדורשות תמיכה בזמן ריצה. בהתאם לעקרונות האלה, חלק מהתכונות מוחרגות באופן מפורש בגלל התלות שלהן בזיכרון ובמערכת ההפעלה, ואחרות מוחרגות כי הן מוחלפות בממשקי API מתאימים יותר שספציפיים ל-CHRE. הרשימה הבאה היא חלקית, אבל אלה היכולות שלא אמורות להיות זמינות בננו-אפליקציות:

  • חריגים ב-C++ ומידע על סוג בזמן ריצה (RTTI)
  • תמיכה בריבוי תהליכים בספרייה רגילה, כולל כותרות C++11‎ <thread>, <mutex>, <atomic>, <future>
  • ספריות קלט/פלט רגילות של C ו-C++‎
  • ספריית התבניות הסטנדרטית (STL) של C++‎
  • ספריית ביטויים רגולריים סטנדרטיים של C++‎
  • הקצאת זיכרון דינמית באמצעות פונקציות רגילות (לדוגמה, malloc,‏ calloc,‏ realloc,‏ free,‏ operator new) ופונקציות אחרות של ספריות רגילות שמשתמשות בהקצאה דינמית, כמו std::unique_ptr
  • תמיכה בלוקליזציה ובתווי Unicode
  • ספריות של תאריכים ושעות
  • פונקציות שמשנות את זרימת התוכנית הרגילה, כולל <setjmp.h>, <signal.h>, abort, std::terminate
  • גישה לסביבת המארח, כולל system, getenv
  • ספריות POSIX וספריות אחרות שלא נכללות בתקני השפה C99 או C++11

במקרים רבים, יש פונקציות וספריות שירות של CHRE API שמספקות יכולות שוות ערך. לדוגמה, אפשר להשתמש ב-chreLog לרישום ביומן של ניפוי באגים שמיועד למערכת logcat של Android, כשבתוכנה מסורתית יותר אפשר להשתמש ב-printf או ב-std::cout.

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

  • כלי עזר למחרוזות ולמערכים: memcmp, memcpy, memmove, memset, strlen
  • ספרייה מתמטית: פונקציות נפוצות של נקודה צפה (floating-point) עם דיוק יחיד:

    • פעולות בסיסיות: ceilf, fabsf, floorf, fmaxf, fminf, fmodf, roundf, lroundf, remainderf
    • פונקציות מעריכיות ופונקציות חזקה: expf, ‏ log2f, ‏ powf, ‏ sqrtf
    • פונקציות טריגונומטריות והיפרבוליות: sinf, cosf, tanf, asinf, acosf, atan2f, tanhf

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

תכונות אופציונליות

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

חיישנים

‫CHRE API מאפשר לבקש נתונים מחיישנים, כולל מד תאוצה, ג'ירוסקופ, מגנטומטר, חיישן אור רגיש לסביבה וחיישן קרבה. ממשקי ה-API האלה נועדו לספק קבוצת תכונות דומה לזו של ממשקי ה-API של חיישני Android, כולל תמיכה באריזת דגימות של חיישנים כדי לצמצם את צריכת החשמל. עיבוד נתוני החיישנים בתוך CHRE מאפשר עיבוד של אותות תנועה עם צריכת חשמל נמוכה בהרבה וזמן אחזור נמוך יותר בהשוואה להפעלה ב-AP.

GNSS

‫CHRE מספקת ממשקי API לבקשת נתוני מיקום ממערכת גלובלית לניווט באמצעות לוויינים (GNSS), כולל GPS וקבוצות לוויינים אחרות. הנתונים האלה כוללים בקשות לתיקונים תקופתיים של המיקום וגם נתוני מדידה גולמיים, אבל אלה שתי יכולות נפרדות. ל-CHRE יש קישור ישיר למערכת המשנה GNSS, ולכן צריכת החשמל נמוכה יותר בהשוואה לבקשות GNSS שמבוססות על AP, כי ה-AP יכול להישאר במצב שינה במהלך כל מחזור החיים של סשן מיקום.

Wi-Fi

‫CHRE מאפשרת אינטראקציה עם שבב ה-Wi-Fi, בעיקר למטרות מיקום. מערכת GNSS פועלת היטב במיקומים חיצוניים, אבל תוצאות של סריקות Wi-Fi יכולות לספק מידע מדויק על מיקום בתוך מבנים ובאזורים מיושבים. בנוסף לחיסכון בעלויות של הפעלת ה-AP לצורך סריקה, CHRE יכול להאזין לתוצאות של סריקות Wi-Fi שמבוצעות על ידי קושחת ה-Wi-Fi למטרות קישוריות, שבדרך כלל לא מועברות ל-AP מסיבות שקשורות לצריכת חשמל. שימוש בסריקות קישוריות למטרות הקשריות עוזר להפחית את המספר הכולל של סריקות ה-Wi-Fi שמבוצעות, וכך לחסוך בחשמל.

הוספנו תמיכה ב-Wi-Fi ב-CHRE API v1.1, כולל היכולת לעקוב אחרי תוצאות הסריקה ולהפעיל סריקות לפי דרישה. היכולות האלה הורחבו בגרסה 1.2 עם האפשרות לבצע מדידות של זמן הלוך ושוב (RTT) מול נקודות גישה שתומכות בתכונה, מה שמאפשר לקבוע בצורה מדויקת את המיקום היחסי.

WWAN

ממשק CHRE API מאפשר לאחזר מידע על זיהוי תאים של התא המשרת ושל התאים הסמוכים לו, ומשמש בדרך כלל למטרות מיקום גס.

אודיו

‫CHRE יכול לעבד קבוצות של נתוני אודיו ממיקרופון עם צריכת חשמל נמוכה, שבדרך כלל מבוסס על חומרה שמשמשת ליישום של SoundTrigger HAL. עיבוד נתוני אודיו ב-CHRE מאפשר לשלב אותם עם נתונים אחרים, כמו חיישני תנועה.

Bluetooth

‫CHRE מספק ממשקי API שתומכים בחלק מהפונקציות של Bluetooth, שמועילות מהעברת עומס עבודה עם צריכת אנרגיה נמוכה. ה-CHRE מאפשר לאפליקציות ננו לבצע סריקות BLE, לעקוב אחרי RSSI ולעבד נתוני פרסום של BLE בלי להפעיל את ה-AP. בנוסף, אפשר להעביר בעלות על חיבור שקע Bluetooth מבוסס ל-domain של הפחתת עומס, מה שמצריך פחות אנרגיה לתחזוקה ומאפשר לאפליקציות קטנות לתקשר באמצעות חיבור שקע BLE שהועבר.

הטמעה לדוגמה

קוד ההפניה למסגרת CHRE כלול ב-AOSP בפרויקט system/chre, והוא מיושם ב-C++11. אמנם אין חובה להשתמש בבסיס הקוד הזה, אבל מומלץ לבסס עליו את כל ההטמעות של CHRE כדי להבטיח עקביות ולזרז את ההטמעה של יכולות חדשות. אפשר לראות את הקוד הזה כאנלוגי למסגרת הליבה של Android, כי הוא הטמעה של ממשקי API שמשמשים אפליקציות בקוד פתוח, ומשמש כבסיס ותקן לתאימות. אפשר להתאים אישית את הקוד המשותף ולהרחיב אותו באמצעות יכולות ספציפיות לספק, אבל מומלץ לשמור על הקוד המשותף כמה שיותר קרוב לקוד ההפניה. בדומה ל-HAL של Android, הטמעת ההפניה של CHRE משתמשת בהפשטות שונות של הפלטפורמה כדי להתאים את עצמה לכל מכשיר שעומד בדרישות המינימליות.

פרטים טכניים ומדריך להעברת נתונים זמינים בקובץ README שכלול בפרויקט system/chre.