上一篇博文中,我們已經跟大家分享了如何在 i.MX8QM Android 上實現 GPS 地圖導航功能,本文我們將持續跟大家分享關於 i.MX8QM 系列相關的內容:分析 i.MX8QM Android 平臺上 GPS 啟動流程。本文我們將用到的軟硬體分別是:
硬體平臺:IMX8QMMEK EVM BOARD
軟體環境:IMX-P9.0.0_2.1.0-AUTO-GA
系統在啟動後會首先啟動 LocationManager,這項服務是在 SystemServer.java 中啟動的,對應到的代碼如下圖所示,
frameworks/base/services/java/com/android/server/SystemServer.java
調用到 LocationManagerService 函數,
frameworks/base/services/core/java/com/android/server/LocationManagerService.java
然後再來看看 systemRunning 函數,
frameworks/base/services/core/java/com/android/server/LocationManagerService.java
這裡調用到 loadProvidersLocked 函數,同樣在 LocationManagerService.java 文件下,
這裡可以看到 GnssLocationProvider.isSupported 函數,主要就是通過這個函數來檢測 GPS 位置服務是否準備就緒,isSupported 函數如下,
frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java
接著是進入到 JNI 函數,android_location_GnssLocationProvider_is_supported,
frameworks/base/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
這裡會判斷 gnssHal 的值是否存在,如果存在則返回值為 true。
這裡還有一個重要的函數,初始化 service 對象,HIDL_FETCH_IGnss,
hardware/interfaces/gnss/1.0/default/Gnss.cpp
這裡通過 hw_get_module 方法,獲取到對應模塊的 so 庫
hardware/libhardware/hardware.c
對應 PATH 定義如下,這裡使用的是 64 位的,只要將對應的 so 文件放到對應的 /vendor/lib64/hw 目錄下即可,
接下來執行了 open 函數,module->methods->open,這裡就會執行 gps module 裡面的 open_gps 函數,
hardware/libhardware/modules/gps/gps.c
在之後,使用 hw_device_t 結構體構建出 gnss 服務對象,gnss 的初始化方法中會調用 dev 的 get_gps_interface 方法,獲取 hal 的方法接口對象,
hardware/interfaces/gnss/1.0/default/Gnss.cpp
到這裡,GnssLocationProvider.isSupported 函數就已經執行完畢,我們獲取到了 GPS 的接口,如果找到 GPS 硬體,那麼就會繼續往下執行 GnssLocationProvider 函數
在構造完 GpsLocationProvider 之後將其 add 到全局變量 ArrayList mProviders 中,備以後調用。
然後啟動了 Geocoder Provider, Network Location Provider 和 Fused Location Provider 三個 service。
執行完 loadProvidersLocked 函數之後回到 systemRunning 函數繼續執行 updateProvidersLocked 函數,
frameworks/base/services/core/java/com/android/server/LocationManagerService.java
依靠前面的代碼我們可以推測在 mProviders 裡面應該存在一個 gpsProvider 和 PassiveProvider,而 gpsProvider 是未被 enable 的。而 passiveProvider 是 enable 的。
這邊我們對 gpsProvider 進行討論,他執行的是 updateProviderListenersLocked(name,true) 然後當有發生改變,就是 changesMade=true 時,它發送了廣播,內容是告訴大家 LocationManager 發生了變化,讓需要的接收者自己接收。
繼續跟進 updateProviderListenersLocked(name,true)函數
這邊我們看 if(enable)內的主題部分。enable 為真, 則啟動了 GPS 服務。然後執行 p.enable() 函數。
frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java
我們看到 enable 函數中只是調用了 sendMessage。跟進函數,可看到 sendMessage 函數獲取 mWakeLock,然後發送給 mHandler。
收到消息後,Hnadler 會自動去調用 handleMessage 去處理收到的消息。
根據構造的消息,這裡將執行 hanleEnable()
這邊 handleEnable 函數主要做了兩件事。
1. 調用 JNI 層的 native_init() 方法去初始化 GPS。
2. 試圖啟動 agps 服務。
native_init() 方法實現如下:
frameworks/base/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
完成初始化操作之後,gnssHal 的值為非空,通過判斷 gnssHal 的值來確定是否初始化成功。
以上就是關於 i.MX8QM Android 平臺上 GPS 啟動流程分析說明。
接下來我們也會不斷更新更多關於 i.MX8 系列的開發博文,同時我們也會持續推出更多 ADAS 相關(S32V234、Hi3566V100、Hi3559AV100、Hi3518EV300、硬體、軟體、算法等)的技術開發博文,如需更深入的技術交流,歡迎在關注給我留言。
【參考資料】:
1. GPS 研究二(Android 2.3__gingerbread)
2. Android 2.3 gps 啟動流程
3. hidl
大聯大旗下世平集團 ATU 部門可以提供相關設計方案和技術支持,需要請聯繫 atu.cn@wpi-group.com