基于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.

 

 

 

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值