android gps 串口,Android GPS数据上报(基于gps_qemu.c)
Android GPS數(shù)據(jù)上報(bào)(基于gps_qemu.c)
在網(wǎng)上找了好久關(guān)于這方面的東西,可都是介紹啟動(dòng)的,現(xiàn)在我把我理解的其數(shù)據(jù)上報(bào)的流程寫下來,以作記錄:
(主要基于gps_qemu.c的數(shù)據(jù)上報(bào))
hardware/libhardware_legacy/gps/gps_qemu.c(HAL層)
相關(guān)閱讀:Android GPS數(shù)據(jù)上報(bào)線程的開啟流程
數(shù)據(jù)從串口傳上來主要是通過函數(shù)static void* gps_state_thread( void* ?arg )接收,并解析上報(bào)給
android_location_GpsLocationProvider.cpp(JNI層)的,下面首先來看gps_state_thread中數(shù)據(jù)抓取及數(shù)據(jù)解析:
else if (fd == gps_fd)
{
char ?buff[32];
D("gps fd event");
for (;;) {
int ?nn, ret;
ret = read( fd, buff, sizeof(buff) );//從串口獲取數(shù)據(jù))
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] );//解析數(shù)據(jù)并上報(bào))
}
D("gps fd event end");
}
接下來看nmea_reader_addc函數(shù)(在gps_qemu.c中):
if (c == '/n') {
nmea_reader_parse( r ); //解析數(shù)據(jù)并上報(bào)
r->pos = 0;
}
函數(shù)nmea_reader_parse( NmeaReader* ?r )(在gps_qemu.c中)
if (r->callback) {
r->callback( &r->fix ); //這句就是上報(bào)數(shù)據(jù)了
r->fix.flags = 0;
}
else {
D("no callback, keeping data until needed !");
}
=====================================注釋一===================================
這里有個(gè)回調(diào)函數(shù)r->callback,這個(gè)回調(diào)函數(shù)是在gps_state_thread函數(shù)中通過nmea_reader_set_callback函數(shù)設(shè)置的,nmea_reader_set_callback中有這樣的語句:
r->callback = cb;//這就是設(shè)定了
而在gps_state_thread中傳給nmea_reader_set_callback的state->callbacks.location_cb參數(shù)是在這里設(shè)定的
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;
}
而函數(shù)qemu_gps_init是在qemuGpsInterface結(jié)構(gòu)體中被JNI(c/c++部分)層調(diào)用的,在JNI(c/c++部分)層怎樣調(diào)用,這將在注釋二中解釋
============================================================================
在這里,數(shù)據(jù)在HAL層的路已經(jīng)走完,下面就進(jìn)入到JNI(c/c++部分)層android_location_GpsLocationProvider.cpp中了
在這層中首先接收到數(shù)據(jù)的是函數(shù)location_callback:
memcpy(&sGpsLocation, location, sizeof(sGpsLocation));//這里把接收到的數(shù)據(jù)傳給sGpsLocation結(jié)構(gòu)體
接著再在android_location_GpsLocationProvider_wait_for_event中:
if (pendingCallbacks & kLocation)
memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy));//把數(shù)據(jù)傳給sGpsLocationCopy結(jié)構(gòu)體
。。。。。。。這里省略了幾行。。。。。。
if (pendingCallbacks & kLocation) {
env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags, ? ? ? ? ? //把數(shù)據(jù)上報(bào)給上層(注釋二中解釋相關(guān)函數(shù))
(jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude,
(jdouble)sGpsLocationCopy.altitude,
(jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,
(jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp);
}
=====================================注釋二===================================
在這一層里location_callback,是怎樣接收到數(shù)據(jù)呢?
其實(shí)這個(gè)函數(shù)是作為一個(gè)回調(diào)函數(shù),在HAL層中調(diào)用的,其是通過調(diào)用qemu_gps_init函數(shù)把location_callback注冊(cè)到HAL層中的
我沒看下調(diào)用qemu_gps_init,在函數(shù)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) ? ? ?//這里調(diào)用的init就是調(diào)用qemu_gps_init了
return false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//參數(shù)sGpsCallbacks就是包含location_callback指針的結(jié)構(gòu)體了
sGpsCallbacks定義如下:
GpsCallbacks sGpsCallbacks = {
location_callback,
status_callback,
sv_status_callback,
nmea_callback
};
***********************我是分隔線************************
android_location_GpsLocationProvider_wait_for_event函數(shù)就注冊(cè)成了java層中的接口了,env是由上層傳下來的參數(shù),具體請(qǐng)參考JNI的相關(guān)知識(shí)
下面的代碼,完成了這個(gè)函數(shù)的注冊(cè):
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, ? ? ? ? ? //把數(shù)據(jù)上報(bào)給上層
(jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude,
(jdouble)sGpsLocationCopy.altitude,
(jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,
(jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp);
參數(shù)method_reportLocation,是在下面的函數(shù)(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();
。。。省略。。。
}
這個(gè)函數(shù)是(JNI Java部分)java注冊(cè)到JNI(c/C++部分)中的一個(gè)回調(diào),我理解為只用來傳遞數(shù)據(jù)。
1
2
3
4
下一頁
總結(jié)
以上是生活随笔為你收集整理的android gps 串口,Android GPS数据上报(基于gps_qemu.c)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: http请求过程以及请求方法和状态码
- 下一篇: (九)ROS安装rviz模拟器