בסמארטפונים יש מספר מעבדים, שכל אחד מהם מותאם לביצוע משימות שונות. עם זאת, מערכת Android פועלת רק על מעבד אחד: מעבד האפליקציות (AP). המעבד מותאם לביצועים מעולים בתרחישי שימוש שבהם המסך פועל, כמו משחקים, אבל הוא צורך יותר מדי חשמל כדי לתמוך בתכונות שדורשות פרצי עיבוד קצרים ותכופים כל הזמן, גם כשהמסך כבוי. מעבדים קטנים יותר יכולים להתמודד עם עומסי העבודה האלה בצורה יעילה יותר, ולהשלים את המשימות שלהם בלי להשפיע באופן משמעותי על חיי הסוללה. עם זאת, סביבות התוכנה במעבדים האלה עם צריכת חשמל נמוכה מוגבלות יותר ויכולות להשתנות מאוד, ולכן קשה לפתח אפליקציות חוצות-פלטפורמות.
סביבת זמן הריצה של Context Hub (CHRE) מספקת פלטפורמה משותפת להרצת אפליקציות במעבד עם צריכת חשמל נמוכה, עם API פשוט, סטנדרטי וידידותי להטמעה. CHRE מאפשר ליצרני מכשירים ולשותפים מהימנים שלהם להעביר את העיבוד ממעבד האפליקציות כדי לחסוך בסוללה ולשפר תחומים שונים בחוויית המשתמש, וגם להפעיל תכונות שפועלות תמיד ומודעות להקשר, במיוחד תכונות שכוללות יישום של למידת מכונה לחישה סביבתית.
קונספטים מרכזיים
CHRE היא סביבת התוכנה שבה אפליקציות נייטיב קטנות, שנקראות nanoapps, פועלות במעבד עם צריכת חשמל נמוכה ומקיימות אינטראקציה עם המערכת הבסיסית באמצעות CHRE API משותף. כדי להאיץ את ההטמעה התקינה של ממשקי ה-API של CHRE, הטמעה חוצת-פלטפורמות של CHRE כלולה ב-AOSP. ההטמעה לדוגמה כוללת קוד משותף והפשטות של החומרה והתוכנה הבסיסיות באמצעות סדרה של שכבות הפשטה של פלטפורמה (PAL). אפליקציות ננו קשורות כמעט תמיד לאחת או יותר אפליקציות לקוח שפועלות ב-Android, שמבצעות אינטראקציה עם CHRE ואפליקציות ננו באמצעות ממשקי API של מערכת ContextHubManager עם גישה מוגבלת.
באופן כללי, אפשר להשוות בין הארכיטקטורה של CHRE לבין הארכיטקטורה של Android בכללותה. עם זאת, יש כמה הבדלים חשובים:
- CHRE תומך בהרצה רק של אפליקציות ננו שפותחו בקוד מקורי (C או C++). אין תמיכה ב-Java.
- בגלל מגבלות אבטחה ומגבלות על משאבים, לא ניתן להשתמש ב-CHRE באפליקציות שרירותיות של צד שלישי ל-Android. רק אפליקציות מהימנות של המערכת יכולות לגשת אליו.
חשוב גם להבחין בין המושג CHRE לבין רכזת חיישנים. למרות שבדרך כלל משתמשים באותו חומרה כדי להטמיע את ה-sensor hub ואת CHRE, CHRE עצמו לא מספק את יכולות החיישן שנדרשות על ידי Android Sensors HAL. CHRE קשור ל-Context Hub HAL, והוא פועל כלקוח של מסגרת חיישנים ספציפית למכשיר כדי לקבל נתוני חיישנים בלי לערב את ה-AP.
איור 1. ארכיטקטורת המסגרת של CHRE
Context Hub HAL
שכבת הפשטת החומרה (HAL) של מרכז ההקשר היא הממשק בין מסגרת Android לבין הטמעת CHRE של המכשיר, שמוגדרת בכתובת hardware/interfaces/contexthub.
ה-HAL של Context Hub מגדיר את ממשקי ה-API שבאמצעותם מסגרת Android מגלה את רכזי ההקשר הזמינים ואת האפליקציות הזעירות שלהם, מנהלת אינטראקציה עם האפליקציות הזעירות האלה באמצעות העברת הודעות ומאפשרת טעינה וביטול טעינה של אפליקציות זעירות. הטמעה לדוגמה של Context Hub HAL שפועלת עם ההטמעה לדוגמה של CHRE זמינה בכתובת system/chre/host.
במקרה של סתירה בין התיעוד הזה לבין הגדרת ה-HAL, הגדרת ה-HAL היא הקובעת.
אתחול
כשמערכת Android מופעלת, הפונקציה getHubs() HAL מופעלת על ידי ContextHubService כדי לקבוע אם יש במכשיר רכזות הקשר. זוהי קריאה חוסמת חד-פעמית, ולכן היא צריכה להסתיים במהירות כדי למנוע עיכוב באתחול, והיא צריכה להחזיר תוצאה מדויקת, כי אי אפשר להציג רכזי הקשר חדשים לאחר מכן.
טעינה ופריקה של אפליקציות ננו
מרכז הקשר יכול לכלול קבוצה של אפליקציות ננו שכלולות בתמונת המכשיר ונטענות כשה-CHRE מתחיל. האפליקציות האלה נקראות אפליקציות ננו שנטענות מראש, והן צריכות להיכלל בתשובה הראשונה האפשרית ל-queryApps().
ה-HAL של Context Hub תומך גם בטעינה ובפריקה דינמיות של אפליקציות ננו בזמן ריצה, באמצעות הפונקציות loadNanoApp() ו-unloadNanoApp(). אפליקציות ננו מסופקות ל-HAL בפורמט בינארי שספציפי לחומרה של CHRE וליישום התוכנה של המכשיר.
אם ההטמעה של טעינת אפליקציית ננו כוללת כתיבה לזיכרון לא נדיף, כמו אחסון פלאש שמחובר למעבד שמריץ את CHRE, אז הטמעת CHRE תמיד תופעל עם אפליקציות ננו דינמיות במצב מושבת. המשמעות היא שאף שורה בקוד של אפליקציית ה-nano לא מופעלת עד שמתקבלת בקשה דרך HAL.enableNanoapp() אפליקציות ננו שנטענו מראש יכולות להתחיל לפעול במצב מופעל.
הפעלה מחדש של Context Hub
במהלך פעולה רגילה, לא צפוי שה-CHRE יופעל מחדש, אבל יכול להיות שיהיה צורך בכך כדי להתאושש מתנאים לא צפויים, כמו ניסיון לגשת לכתובת זיכרון לא ממופה. במקרים כאלה, CHRE מופעל מחדש באופן עצמאי מ-Android. שכבת ה-HAL מודיעה ל-Android על כך באמצעות האירוע RESTARTED, שאותו היא חייבת לשלוח רק אחרי ש-CHRE אותחל מחדש עד לנקודה שבה הוא יכול לקבל בקשות חדשות, כמו queryApps().
סקירה כללית על מערכת CHRE
הארכיטקטורה של CHRE מבוססת על אירועים, כאשר יחידת החישוב העיקרית היא אירוע שמועבר לנקודת הכניסה לטיפול באירועים של אפליקציית ננו. למרות שמסגרת CHRE יכולה להיות מרובת-הליכים, אפליקציית ננו אף פעם לא מופעלת מכמה הליכים במקביל. מסגרת CHRE מתקשרת עם אפליקציית nano נתונה דרך אחת משלוש נקודות הכניסה של אפליקציית nano (nanoappStart(), nanoappHandleEvent() ו-nanoappEnd()) או דרך קריאה חוזרת שסופקה בקריאה קודמת ל-CHRE API. אפליקציות nano מתקשרות עם מסגרת CHRE ועם המערכת הבסיסית דרך CHRE API. CHRE API מספק קבוצה של יכולות בסיסיות וגם כלים לגישה לאותות הקשריים, כולל חיישנים, GNSS, Wi-Fi, WWAN ואודיו. אפשר להרחיב אותו עם יכולות נוספות שספציפיות לספק לשימוש בננו-אפליקציות שספציפיות לספק.
מערכת build
בעוד ש-Context Hub HAL ורכיבים נדרשים אחרים בצד ה-AP נוצרים לצד Android, לקוד שפועל ב-CHRE יכולות להיות דרישות שגורמות לו להיות לא תואם למערכת הבנייה של Android, כמו הצורך בשרשרת כלים מיוחדת. לכן, פרויקט CHRE ב-AOSP מספק מערכת build פשוטה שמבוססת על GNU Make כדי לקמפל אפליקציות nano, ובאופן אופציונלי, את מסגרת CHRE לספריות שאפשר לשלב במערכת. יצרני מכשירים שמוסיפים תמיכה ב-CHRE צריכים לשלב ב-AOSP תמיכה במערכת build למכשירי היעד שלהם.
ממשק CHRE API כתוב בתקן השפה C99, וההטמעה לדוגמה משתמשת בקבוצת משנה מוגבלת של C++11 שמתאימה לאפליקציות עם משאבים מוגבלים.
CHRE API
ממשק ה-API של CHRE הוא אוסף של קובצי כותרות C שמגדירים את ממשק התוכנה בין אפליקציית nano לבין המערכת. הוא נועד להפוך את הקוד של אפליקציות ננו לתואם בכל המכשירים שתומכים ב-CHRE, כלומר לא צריך לשנות את קוד המקור של אפליקציית ננו כדי לתמוך בסוג חדש של מכשיר, אבל יכול להיות שיהיה צורך לבצע קומפילציה מחדש במיוחד עבור קבוצת ההוראות של המעבד או ממשק הבינארי של האפליקציה (ABI) של מכשיר היעד. הארכיטקטורה של CHRE ועיצוב ה-API גם מבטיחים תאימות בינארית של אפליקציות ננו בין גרסאות שונות של CHRE API. כלומר, אין צורך לבצע קומפילציה מחדש של אפליקציית ננו כדי להפעיל אותה במערכת שמטמיעה גרסה אחרת של CHRE API בהשוואה ל-API היעד שאליו מתבצעת הקומפילציה של אפליקציית הננו. במילים אחרות, אם קובץ בינארי של אפליקציית ננו פועל במכשיר שתומך ב-CHRE API בגרסה 1.3, והמכשיר הזה משודרג כך שיתמוך ב-CHRE API בגרסה 1.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 ולפונקציות מאושרות של ספריית תקנים.
תכונות אופציונליות
כדי לקדם חומרה ותוכנה, ממשק ה-API של CHRE מחולק לאזורי תכונות, שנחשבים לאופציונליים מנקודת המבט של ה-API. יכול להיות שלא תצטרכו את התכונות האלה כדי לתמוך בהטמעה תואמת של CHRE, אבל יכול להיות שתצטרכו אותן כדי לתמוך באפליקציית ננו מסוימת. גם אם פלטפורמה לא תומכת בקבוצה מסוימת של ממשקי API, אפליקציות ננו שמפנות לפונקציות האלה צריכות להיות מסוגלות להיבנות ולהיטען.
חיישנים
ה-API של CHRE מאפשר לבקש נתונים מחיישנים, כולל מד תאוצה, ג'ירוסקופ, מגנטומטר, חיישן אור סביבתי וחיישן קרבה. ממשקי ה-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
ממשק ה-API של CHRE מאפשר לאחזר מידע על זיהוי תאים של התא המשרת ושל התאים הסמוכים לו, ומשמש בדרך כלל למטרות מיקום ברמת דיוק גסה.
אודיו
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.