android gps 串口,Android GPS数据上报(基于gps_qemu.c)

Android GPS数据上报(基于gps_qemu.c)

在网上找了好久关于这方面的东西,可都是介绍启动的,现在我把我理解的其数据上报的流程写下来,以作记录:

(主要基于gps_qemu.c的数据上报)

hardware/libhardware_legacy/gps/gps_qemu.c(HAL层)

相关阅读:Android GPS数据上报线程的开启流程

数据从串口传上来主要是通过函数static void* gps_state_thread( void*  arg )接收,并解析上报给

android_location_GpsLocationProvider.cpp(JNI层)的,下面首先来看gps_state_thread中数据抓取及数据解析:

else if (fd == gps_fd)

{

char  buff[32];

D("gps fd event");

for (;;) {

int  nn, ret;

ret = read( fd, buff, sizeof(buff) );//从串口获取数据)

if (ret < 0) {

if (errno == EINTR)

continue;

if (errno != EWOULDBLOCK)

LOGE("error while reading from gps daemon socket: %s:", strerror(errno));

break;

}

D("received %d bytes: %.*s", ret, ret, buff);

for (nn = 0; nn < ret; nn++)

nmea_reader_addc( reader, buff[nn] );//解析数据并上报)

}

D("gps fd event end");

}

接下来看nmea_reader_addc函数(在gps_qemu.c中):

if (c == '/n') {

nmea_reader_parse( r ); //解析数据并上报

r->pos = 0;

}

函数nmea_reader_parse( NmeaReader*  r )(在gps_qemu.c中)

if (r->callback) {

r->callback( &r->fix ); //这句就是上报数据了

r->fix.flags = 0;

}

else {

D("no callback, keeping data until needed !");

}

=====================================注释一===================================

这里有个回调函数r->callback,这个回调函数是在gps_state_thread函数中通过nmea_reader_set_callback函数设置的,nmea_reader_set_callback中有这样的语句:

r->callback = cb;//这就是设定了

而在gps_state_thread中传给nmea_reader_set_callback的state->callbacks.location_cb参数是在这里设定的

static int qemu_gps_init(GpsCallbacks* callbacks)

{

GpsState*  s = _gps_state;

if (!s->init)

gps_state_init(s);

if (s->fd < 0)

return -1;

s->callbacks = *callbacks;

return 0;

}

而函数qemu_gps_init是在qemuGpsInterface结构体中被JNI(c/c++部分)层调用的,在JNI(c/c++部分)层怎样调用,这将在注释二中解释

============================================================================

在这里,数据在HAL层的路已经走完,下面就进入到JNI(c/c++部分)层android_location_GpsLocationProvider.cpp中了

在这层中首先接收到数据的是函数location_callback:

memcpy(&sGpsLocation, location, sizeof(sGpsLocation));//这里把接收到的数据传给sGpsLocation结构体

接着再在android_location_GpsLocationProvider_wait_for_event中:

if (pendingCallbacks & kLocation)

memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy));//把数据传给sGpsLocationCopy结构体

。。。。。。。这里省略了几行。。。。。。

if (pendingCallbacks & kLocation) {

env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags,           //把数据上报给上层(注释二中解释相关函数)

(jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude,

(jdouble)sGpsLocationCopy.altitude,

(jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,

(jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp);

}

=====================================注释二===================================

在这一层里location_callback,是怎样接收到数据呢?

其实这个函数是作为一个回调函数,在HAL层中调用的,其是通过调用qemu_gps_init函数把location_callback注册到HAL层中的

我没看下调用qemu_gps_init,在函数android_location_GpsLocationProvider_init(JNI层):

if (!sGpsInterface)

sGpsInterface = gps_get_interface();//这句是获得在HAN层定义的GpsInterface指针,gps_get_interface

//定义在hardware/libhardware_legacy/gps/gps.cpp

if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)      //这里调用的init就是调用qemu_gps_init了

return false;                                                            //参数sGpsCallbacks就是包含location_callback指针的结构体了

sGpsCallbacks定义如下:

GpsCallbacks sGpsCallbacks = {

location_callback,

status_callback,

sv_status_callback,

nmea_callback

};

***********************我是分隔线************************

android_location_GpsLocationProvider_wait_for_event函数就注册成了java层中的接口了,env是由上层传下来的参数,具体请参考JNI的相关知识

下面的代码,完成了这个函数的注册:

static JNINativeMethod sMethods[] = {

。。。省略。。。

{"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event},

。。。省略。。。

};

int register_android_location_GpsLocationProvider(JNIEnv* env)

{

return jniRegisterNativeMethods(env, "com/android/internal/location/GpsLocationProvider", sMethods, NELEM(sMethods));

}

****************我是分隔线********************

env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags,           //把数据上报给上层

(jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude,

(jdouble)sGpsLocationCopy.altitude,

(jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,

(jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp);

参数method_reportLocation,是在下面的函数(android_location_GpsLocationProvider)中被映射为java的reportLocation(在GpsLocationProvider.java中)方法:

static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {

method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");

。。。省略。。。

}

在java层中GpsLocationProvider.java的reportLocation:

private void reportLocation(int flags, double latitude, double longitude, double altitude,

float speed, float bearing, float accuracy, long timestamp) {

if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude +

" timestamp: " + timestamp);

mLastFixTime = System.currentTimeMillis();

。。。省略。。。

}

这个函数是(JNI Java部分)java注册到JNI(c/C++部分)中的一个回调,我理解为只用来传递数据。

1

2

3

4

下一页

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值