基于Android2.3的车载导航---andorid GPS HAL的移植与分析(by liukun321咕唧咕唧)
主控: Samsung ARM Cortex-A8(s5pv210)
Gps: Ublox-6M
系统: android 2.3.1
内核: Linux2.6.35
bootloader: u-boot for tiny210 ver4.0
开发板: Tiny210V1 SDK2(512M DDR2RAM SLC NANDFLASH 256M)
复试结束,该忙的事忙完就到四月底了,这才有时间坐下来学点东西。这应该是本阶段做的最后一个小玩意了。前戏缩短,废话少说,进正题。
由于友善只提供了GPS驱动模块,并无源码,而且经测试友善的驱动并未完整解析GPS的几大关键数据,因此上层应用只能获得经纬度,精度,UTC时间。这样就只能在google地图,百度地图类似于这样应用提供定位。由于HAL无法返回卫星状态数据(可见卫星数,可用卫星数,卫星信号强度等),导致无法使用专业的GPS导航软件。下面提供的源码是根据gps_qemu.c修改而来的,实现GPS关键数据解析,支持凯立德,道道通等导航软件。下面会从GPS NMEA-0183协议开始到Android GPS HAL移植及模块的编译加载简要介绍Android车载导航仪是如何“炼成”的。下面附源码(理论上支持所有输出NMEA-0183格式数据的串口及USB GPS)。
源码下载:Android GPS HAL for Ublox-6M(下载链接已更新,修改部分源码内容及mk文件)
我在X宝上100块买的GPS模块属于硬GPS,也就是串口上直接输出NMEA数据的。所以首先要做的是了解NMEA的数据结构。
NMEA-0183标准数据分析实例(四中常用数据)
$信息类型,xxx,xxx,xxx,xxx,xxx,xxx,xxx,
每行开头的字符都是$,接着是信息类型,后面是数据,用逗号隔开
信息类型为:
GPGSV:可见卫星信息
GPGLL:地理定位信息
GPRMC:推荐最小定位信息
GPVTG:地面速度信息
GPGGA:GPS定位信息
GPGSA:当前卫星信息
$GPGGA,012440.00,3202.1798,N,11849.0763,E,1,05,2.7,40.2,M,0.5,M,,*6F..
1 时间: 01+8=9点24分40.00秒
2 纬度: 北纬32度02.1798分
3 经度: 东经118度49.0763分
4 定位: 1=(定位sps模式) 0=(未定位)
5 应用卫星数: 05个
6 HDOP: 2.7米
7 海拔: 40.2
8 海拔单位: M=(米)
9 WGS84水准面划分: 0.5
10 WGS84水准面划分单位 M(米)
11
12 校验位: 6F
$GPRMC,013946.00,A,3202.1855,N,11849.0769,E,0.05,218.30,111105,4.5,W,A*20..
01 时间01时39分46.00秒
02 定位状态 A=可用 V=警告(不可用)
03 纬度: 北纬(N) 32度02.1855分
04 经度: 东经(E) 118度49.0769分
05 相对位移速度: 0.05 knots
06 相对位移方向: 218.30度
07 日期: 11日11月05年(日日月月年年)
08
09
10 检查位
$GPGSA,A,3,01,03,14,20,,,,,,,,,2.6,2.5,1.0*35..
01 模式2: A=自动 M=手动
02 模式1: 1=未定位 2=二维定位 3=三维定位
03 卫星编号: 01到32
04 PDOP-位置精度稀释:(2.6) 0.5--99.9
05 HDOP-水平经度稀释:(2.6) 0.5--99.9
06 VDOP-垂直经度稀释:(1.0) 0.5--99.9 07 检验位 35
$GPGSV,2,1,08,01,62,160,42,03,23,189,42,06,23,049,32,14,24,150,35*78..
01 天空中收到讯号的卫星总数
02 定位的卫星总数
03 天空中卫星总数
04 (01,62,160,42)分别是卫星编号01-32,卫星仰角00-90度,卫星方位角000-359度,讯号噪声比00-99dB 以下类似(03,23,189,42) (06,23,049,32) (14,24,150,35)
05 Checksum检查位*78
大体了解NMEA数据以后需要我们做的就是移植GPS HAL了。在Android平台下,我们需要移植的GPS内容是位于JNI层下面的,也就是刚才提到的HAL硬件抽象层。对于GPS硬件抽象层来说不算复杂,里面包括对对串口(或USB 转串口)设备的初始化,GPS线程创建及NMEA数据读取、解析、信息回调等等工作。这在Android源码中给出了少量的参考信息,也就是 Android-2.3.1/sdk/emulator/gps/这个目录下的gps_qemu.c文件。它要为我们所用,还需要做大量的修改和升级。对于GPS HAL的设计我们首现要了解Android源码中的几个结构(结构内容就不贴出来了,大家可以参考源码),分别是:
GpsLocation; GpsStatus; GpsInterface;GpsCallbacks;GpsState; NmeaReader;
还有下面对GPS状态的几个重要的定义:
#define GPS_STATUS_NONE 0//未知状态
#define GPS_STATUS_SESSION_BEGIN 1 //已经开始导航
#define GPS_STATUS_SESSION_END 2//停止导航
#define GPS_STATUS_ENGINE_ON 3//已经通电但没有导航
#define GPS_STATUS_ENGINE_OFF 4//没有通电状态
gps是如何被开启和初始化的:
见框图:
对于gps_qemu.c 的修改就不一行行的贴源码了(内容太多)。这里只简述下需要修改的函数的函数名及其作用,修改细节大家可以参考上面链接提供的源码。
1.修改static int nmea_tokenizer_init( NmeaTokenizer* t, const char* p, const char* end )函数
if (q > p) { --------》》》if (q > =p) { //解决无法读取空白NEMA数据的bug
if (count < MAX_NMEA_TOKENS) {
t->tokens[count].p = p;
t->tokens[count].end = q;
count += 1;
}
}
2.依次修改下面函数,细节参照源码
static void nmea_reader_init( NmeaReader* r )
static void nmea_reader_set_callback( NmeaReader* r, gps_location_callback cb )
static void nmea_reader_parse( NmeaReader* r )//关键 信息回调
static void* gps_state_thread( void* arg )
static void gps_state_init( GpsState* state )//关键 完成对串口的初始化
3.修改结构NmeaReader的定义,添加新成员。
typedef struct {
int pos;
int overflow;
int utc_year;
int utc_mon;
int utc_day;
int utc_diff;
GpsLocation fix;
//********************************
GpsSvStatus sv_status;
int sv_status_changed;
#ifdef Ublox_6M
GpsCallbacks callback;
#else
//*********************************
gps_location_callback callback;
#endif
char in[ NMEA_MAX_SIZE+1 ];
} NmeaReader;
3.添加新函数static int nmea_reader_update_accuracy(NmeaReader * r, Token accuracy)
用于解析GPS定位精度信息。
4.添加Android.mk文件,内容如下:
LOCAL_PATH := $(call my-dir)
#ifneq ($(TARGET_PRODUCT),sim)
# HAL module implemenation, not prelinked and stored in
# hw/<GPS_HARDWARE_MODULE_ID>.<ro.hardware>.so
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_CFLAGS += -DQEMU_HARDWARE
LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
LOCAL_SRC_FILES := gps_qemu.c
LOCAL_MODULE := gps.default
LOCAL_MODULE_TAGS := eng
include $(BUILD_SHARED_LIBRARY)
#endif
5.将gps_qemu.c Android.mk cp到gps目录下(可新建任意名称目录),cp gps目录到已经编译过的Android源码下。
6.编译,由于我的目标板是tiny210,在Android源码目录下依次执行下面命令:
$ source 源码目录/build/envsetup.sh
$ export TARGET_PRODUCT=full_mini210 //将目标生成的位置修改自己开发板的目录
$mmm ./gps
编译完成后会在out/target/product/smdkv210/system/lib/hw/目录下生成gps.default.so库,cp gps.default.so到文件系统的system/lib/hw/目录下,生成.img镜像烧入开发板。
7.安装凯立德到开发板,并安装地图包。
8.开机测试
分别使用GPS_Test_Plus_1.2.1和凯立德测试GPS。
附图:
1.GPS_Test_Plus_1.2.1测试,卫星信息概览
2.可视卫星,可用卫星分布测试
3.基本定位信息
4.GPS卫星授时测试
5.海拔及速度测试
6.凯立德导航测试
7.GPS基本信息测试
8.定位位置测试
9.Ublox-6M模块
10.
更多推荐
所有评论(0)