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

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

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

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

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

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

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

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

ארכיטקטורת המסגרת של CHRE

איור 1. הארכיטקטורה של מסגרת CHRE

HAL של Context Hub

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

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

אתחול

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

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

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

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

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

Context Hub מופעל מחדש

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

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

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

מערכת build

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

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

CHRE API

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

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

סיכום הגרסה

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

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

גרסה 1.0 (Android 7)

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

גרסה 1.1 (Android 8)

הוספת יכולות מיקום באמצעות מיקום GNSS ומדידות גולמיות, סריקת Wi-Fi ומידע על רשתות סלולריות, יחד עם שיפורים כלליים שמאפשרים תקשורת בין ננו-אפליקציות ושיפורים נוספים.

גרסה 1.2 (Android 9)

נוספה תמיכה בנתונים ממיקרופון עם צריכת אנרגיה נמוכה, מדידת מרחק RTT ב-Wi-Fi, התראות על הפעלה והשבתה של נקודות גישה ושיפורים נוספים.

גרסה 1.3 (Android 10)

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

גרסה 1.4 (Android 11)

הוספת תמיכה במידע בתא 5G, תמונת מצב של ניפוי באגים ב-nanoapp ושיפורים נוספים.

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

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

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

ספרייה רגילה של 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.

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

  • כלי שירות למחרוזות ולמערך: 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 ולפונקציות ספריית סטנדרטית שאושרו.

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

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

חיישנים

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

GNSS

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

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 יכול לעבד קבוצות של נתוני אודיו ממיקרופון בעל הספק נמוך, שבדרך כלל משתמש בחומרה המשמשת להטמעת ה-HAL של SoundTrigger. עיבוד נתוני האודיו ב-CHRE יכול לאפשר שילוב שלהם עם נתונים אחרים, כמו חיישני תנועה.

הטמעת עזר

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

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