在智能硬件开发中,GPS功能移植是个常见但容易踩坑的环节。最近我在WT-11-AK设备上完成了全志A133平台Android 10.0系统的GPS HAL层移植,整个过程从源码集成到串口调试,积累了不少实战经验。这篇文章就来详细分享这个移植过程,手把手教你搞定GPS模块的集成与配置。
全志A133是面向智能终端设备的四核处理器,在车载导航、智能POS等场景应用广泛。Android 10.0作为目前主流的嵌入式系统版本,其HAL层架构相比早期版本有了较大变化。GPS模块的移植主要涉及三个关键环节:HAL层代码集成、manifest配置和串口适配。其中gnsshal库的移植是核心,它负责Android系统与GPS硬件模块的通信桥梁。
移植过程中最大的挑战在于硬件与软件的匹配。不同GPS模块使用的串口可能不同(常见的有ttyS1-ttyS4),波特率设置也需要与模块规格一致。我使用的WT-11-AK开发板上,GPS模块连接的是ttyS3串口,这也是后续配置中需要特别注意的地方。
首先需要获取gnsshal库源码,可以从开源社区或厂商提供的资源中下载。我使用的版本来自CSDN资源站,包含两个关键文件:Android.bp构建脚本和gps_zkw.c核心驱动文件。建议将整个gnsshal库放在external目录下,保持Android源码树的整洁。
完整的目录结构应该是:
code复制external/gnsshal/
├── Android.bp
└── gps_zkw.c
Android.bp是GNSS HAL的构建描述文件,内容大致如下:
makefile复制cc_library_shared {
name: "android.hardware.gnss@1.0-impl",
relative_install_path: "hw",
proprietary: true,
srcs: ["gps_zkw.c"],
shared_libs: [
"liblog",
"libcutils",
"libhardware",
"libutils",
"android.hardware.gnss@1.0",
],
cflags: [
"-Werror",
"-Wno-unused-parameter",
],
}
接下来需要修改设备相关的mk文件。以ceres_c3.mk为例,需要添加GPS模块的编译配置:
diff复制diff --git a/ceres_c3.mk b/ceres_c3.mk
index 1c396ad..8d0a5e7 100644
--- a/ceres_c3.mk
+++ b/ceres_c3.mk
@@ -158,6 +158,9 @@ PRODUCT_PROPERTY_OVERRIDES += \
PRODUCT_PACKAGES += \
SoundRecorder
+PRODUCT_PACKAGES += \
+ gps.ceres
+
#PRODUCT_PACKAGES += AllwinnerGmsIntegration
同时需要在hal.mk中添加GNSS HAL服务的编译项:
diff复制diff --git a/hal.mk b/hal.mk
index 6d949af..d64eaf0 100644
--- a/hal.mk
+++ b/hal.mk
@@ -78,6 +78,11 @@ PRODUCT_PACKAGES += \
PRODUCT_PACKAGES += \
android.hardware.usb@1.0-service
+# GPS HAL
+PRODUCT_PACKAGES += \
+ android.hardware.gnss@1.0-impl \
+ android.hardware.gnss@1.0-service
+
#health
PRODUCT_PACKAGES += \
android.hardware.health@2.0-service \
Android 10.0使用HIDL(HAL Interface Definition Language)作为硬件抽象层的接口规范。我们需要在manifest.xml中添加GNSS HAL的HIDL接口声明:
diff复制diff --git a/configs/manifest.xml b/configs/manifest.xml
index 9a208c4..6ecc457 100644
--- a/configs/manifest.xml
+++ b/configs/manifest.xml
@@ -27,6 +27,15 @@
</interface>
</hal>
<hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IGnss</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl">
<name>android.hardware.audio.effect</name>
<transport>hwbinder</transport>
<version>5.0</version>
这个配置告诉系统:我们提供了一个实现android.hardware.gnss@1.0接口的HAL服务,使用hwbinder进行进程间通信,实例名为default。
在Android 10.0上,SELinux策略变得更加严格,需要为GNSS服务添加相应的权限。在device/全志/ceres_c3/sepolicy目录下,需要新增或修改以下策略文件:
一个典型的gnsshal.te文件内容如下:
sepolicy复制type gnsshal, domain;
type gnsshal_exec, exec_type, file_type;
init_daemon_domain(gnsshal)
allow gnsshal self:capability { net_raw net_admin };
allow gnsshal device:chr_file { read write open ioctl };
allow gnsshal sysfs:file rw_file_perms;
GPS模块通常通过UART串口与主控芯片通信。在gps_zkw.c中,需要根据实际硬件连接修改串口配置:
c复制/* the name of the controlled socket */
#define GPS_CHANNEL_NAME "/dev/ttyS3" // 根据实际连接的串口修改
#define GPS_BAUD_RATE B9600 // 波特率需与模块规格一致
#define GPS_DATA_BITS 8 // 数据位
#define GPS_PARITY 'N' // 无校验
#define GPS_STOP_BITS 1 // 停止位
全志A133平台通常有多个UART接口,常见的连接方式有:
在WT-11-AK开发板上,GPS模块连接的是ttyS3。如果使用其他开发板,需要根据原理图确认具体的串口编号。
在开始软件调试前,务必确认硬件连接正确:
可以使用万用表测量串口的电压:
完成移植后,可以使用GpsTest等工具验证GPS功能。我推荐使用GpsTest 1.5.4版本,它能直观显示卫星信号强度、定位精度等信息。测试时需要注意:
Windows平台可以使用GNSSToolKit_Lite.exe直接读取GPS串口数据,这对调试很有帮助:
根据我的经验,GPS性能优化可以从以下几个方面入手:
一个常见的问题是天线阻抗不匹配导致信号衰减。可以使用网络分析仪测量天线驻波比(VSWR),理想值应小于2.0。如果发现信号弱,可以尝试以下方法:
在实际项目中,我遇到过各种GPS相关的问题,这里分享几个典型案例:
问题1:GPS模块无响应
问题2:能收到数据但无法定位
问题3:定位漂移严重
问题4:冷启动时间过长
调试时可以启用GPS HAL的详细日志,在gps_zkw.c中添加:
c复制#define DEBUG_LOG 1
#if DEBUG_LOG
#define LOGD(fmt, args...) ALOGD("%s: " fmt, __func__, ##args)
#else
#define LOGD(fmt, args...)
#endif
对于需要更高精度的应用场景,可以考虑以下进阶配置:
AGPS服务集成
在Android系统中配置SUPL服务器地址,可以从Google或其他AGPS服务提供商获取星历数据,显著缩短首次定位时间。配置示例:
xml复制<!-- 在frameworks/base/core/res/res/values/config.xml中添加 -->
<string name="config_agpsSuplServer" translatable="false">supl.google.com</string>
<integer name="config_agpsSuplPort">7276</integer>
多星座支持
现代GPS模块通常支持GPS/GLONASS/BeiDou/Galileo多系统。在HAL层可以启用这些配置:
c复制// 在gps_zkw.c的初始化函数中设置
gps_conf.CAPABILITIES |= GPS_CAPABILITY_GLONASS | GPS_CAPABILITY_BEIDOU;
低功耗模式
对于电池供电设备,可以配置GPS的功耗模式:
c复制#define GPS_POWER_MODE GPS_POWER_MODE_LOW // 低功耗模式
#define GPS_INTERVAL 1000 // 位置更新间隔(ms)
DOP值过滤
在HAL层添加精度过滤,避免输出质量差的位置数据:
c复制if (pdop > 3.0 || hdop > 2.5 || vdop > 4.0) {
LOGD("Poor accuracy, skip this fix");
return;
}
在实际项目中,GPS性能的优化是个持续的过程。建议与模块厂商保持沟通,他们通常能提供针对特定环境的调优建议。比如天线匹配电路的调整、屏蔽罩的设计等硬件优化措施,往往能带来明显的性能提升。