I.MX6 GPS JNI HAL register init hacking
生活随笔
收集整理的這篇文章主要介紹了
I.MX6 GPS JNI HAL register init hacking
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
/************************************************************************************ * I.MX6 GPS JNI HAL register init hacking * 聲明: * 1. 本文主要是對Atheros GPS JNI、HAL層的代碼進行初略的跟蹤,主要想知道GPS設備* 在這兩層是如何注冊、數據解析,目前還沒分析Framework層進行分析。 * 2. 由于采用vim編輯文檔,且分析文檔的寬度超過博客園的文本寬度,如果想要閱讀,* 盡量cp到自己文檔里面,寬度足夠,用vim進行閱讀比較方便。* 3. 不要在本博客上直接閱讀,請采納2中的意見。* * 2015-11-3 深圳 陰 南山平山村 曾劍鋒 ***********************************************************************************/ \\\\\\\\\\\\-*- 目錄 -*-/ | 一、參考文章: | 二、JNI、HAL函數注冊: | 三、Atheros GPS HAL初始化流程: ------------------------------------ 一、參考文章: GPS 研究二 (Android 2.3__gingerbread) http://blog.chinaunix.net/uid-25570748-id-184090.html
android GPS HAL 回調函數實現 http://www.xuebuyuan.com/967335.html
二、JNI、HAL函數注冊: cat /home/myzr/myandroid/frameworks/base/services/jni/com_android_server_location_GpsLocationProvider.cpp... static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {int err; hw_module_t* module; method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V"); method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(III)V"); method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V"); method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V"); method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V"); method_requestUtcTime = env->GetMethodID(clazz,"requestUtcTime","()V"); err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { hw_device_t* device; <----------------------------------------+ err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); --------+ | if (err == 0) { | | gps_device_t* gps_device = (gps_device_t *)device; | | sGpsInterface = gps_device->get_gps_interface(gps_device); --------*-*-+} | | |} | | |if (sGpsInterface) { | | |sGpsXtraInterface = | | |(const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE); | | |sAGpsInterface = | | |(const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); | | |sGpsNiInterface = | | |(const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE); | | |sGpsDebugInterface = | | |(const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);| | |sAGpsRilInterface = | | |(const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE); | | |} | | | |} +-------+ | | |... | | | || | | |cat /home/myzr/myandroid/hardware/imx/libgps/gps.c | | | |... | | | |extern const GpsInterface* gps_get_hardware_interface(); ---------+ | | | |const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev) <--------*-*----*-*-+{ | | | | |return gps_get_hardware_interface(); ---------+ | | | || | | | |} | | | | || | | | |static int open_gps(const struct hw_module_t* module, char const* name, <---------------+ | |struct hw_device_t** device) | | | | |{ | | | | |struct gps_device_t *dev = malloc(sizeof(struct gps_device_t)); ----------*-*----*-+ |memset(dev, 0, sizeof(*dev)); | | | || | | |dev->common.tag = HARDWARE_DEVICE_TAG; | | | |dev->common.version = 0; | | | |dev->common.module = (struct hw_module_t*)module; | | | |dev->get_gps_interface = gps__get_gps_interface; <---------*-*----*---+| | | *device = (struct hw_device_t*)dev; | | | return 0; | | | } | | | | | | static struct hw_module_methods_t gps_module_methods = { <----- + | | | .open = open_gps <------*---------------*-*----+ }; | | | | | | struct hw_module_t HAL_MODULE_INFO_SYM = { | | | .tag = HARDWARE_MODULE_TAG, | | | .version_major = 1, | | | .version_minor = 0, | | | .id = GPS_HARDWARE_MODULE_ID, | | | .name = "Atheros GPS Module", | | | .author = "FSL MAD, Inc.", | | | .methods = &gps_module_methods, ---------------+ | | }; | | ... | | | | cat /home/myzr/myandroid/hardware/imx/libgps/athr_gps.c | | ... | | #ifdef ATHR_GPSNi | | /* | | * Registers the callbacks for HAL to use | | */ | | static void athr_gps_ni_init(GpsNiCallbacks* callbacks) | | { | | GpsState* s = _gps_state; | | | | D("%s: entered", __FUNCTION__); | | | | if (callbacks) | | { | | s->ni_init = 1; | | s->ni_callbacks = *callbacks; | | } | | } | | | | /* | | * Sends a response to HAL | | */ | | static void athr_gps_ni_respond(int notif_id, GpsUserResponseType user_response) | | { | | // D("%s: entered", __FUNCTION__); | | } | | | | static const GpsNiInterface athrGpsNiInterface = { | | sizeof(GpsNiInterface), | | athr_gps_ni_init, | | athr_gps_ni_respond, | | }; | | #endif // ATHR_GPSNi | | | | | | /** | | * 10-30 06:19:30.190: D/athr_gps(2570): | | * athr_gps_get_extension: found xtra extension | | * 10-30 06:19:30.190: D/athr_gps(2570): | | * athr_gps_get_extension: no GPS extension for agps is found | | * 10-30 06:19:30.190: D/athr_gps(2570): | | * athr_gps_get_extension: found ni extension | | * 10-30 06:19:30.190: D/athr_gps(2570): | | * athr_gps_get_extension: no GPS extension for gps-debug is found | | * 10-30 06:19:30.190: D/athr_gps(2570): | | * athr_gps_get_extension: no GPS extension for agps_ril is foun | | */ | | static const void* athr_gps_get_extension(const char* name) <---------------*-+ { | | if (strcmp(name, GPS_XTRA_INTERFACE) == 0) | | { | | #ifdef ATHR_GPSXtra | | D("%s: found xtra extension", __FUNCTION__); | | return (&athrGpsXtraInterface); | | #endif // ATHR_GPSXtra | | } | | else if (strcmp(name, GPS_NI_INTERFACE) == 0) | | { | | #ifdef ATHR_GPSNi | | D("%s: found ni extension", __FUNCTION__); | | return (&athrGpsNiInterface); | | #endif // ATHR_GPSNi | | } | | D("%s: no GPS extension for %s is found", __FUNCTION__, name); | | return NULL; | | } | | | | static const GpsInterface athrGpsInterface = { <----+ | | .size =sizeof(GpsInterface), | | | .init = athr_gps_init, | | | .start = athr_gps_start, | | | .stop = athr_gps_stop, | | | .cleanup = athr_gps_cleanup, | | | .inject_time = athr_gps_inject_time, | | | .inject_location = athr_gps_inject_location, | | | .delete_aiding_data = athr_gps_delete_aiding_data, | | | .set_position_mode = athr_gps_set_position_mode, | | | .get_extension = athr_gps_get_extension, | | | }; | | | | | | const GpsInterface* gps_get_hardware_interface() | <-------------------+ | { | | return &athrGpsInterface; -----+ | } | ... | | | cat /home/myzr/myandroid/hardware/libhardware/include/hardware/gps.h | ... | /** | * Name for the GPS XTRA interface. | */ | #define GPS_XTRA_INTERFACE "gps-xtra" | | /** | * Name for the GPS DEBUG interface. | */ | #define GPS_DEBUG_INTERFACE "gps-debug" | | /** | * Name for the AGPS interface. | */ | #define AGPS_INTERFACE "agps" | | /** | * Name for NI interface | */ | #define GPS_NI_INTERFACE "gps-ni" | | /** | * Name for the AGPS-RIL interface. | */ | #define AGPS_RIL_INTERFACE "agps_ril" <------------------------+ ... 三、Atheros GPS HAL初始化流程: cat /home/myzr/myandroid/hardware/imx/libgps/athr_gps.c ...... 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; char in[ NMEA_MAX_SIZE+1 ]; int gsa_fixed; AthTimemap_t timemap; } NmeaReader; <----+ | typedef struct { | int init; | int fd; | GpsCallbacks callbacks; | <--------+ pthread_t thread; | | pthread_t nmea_thread; | | pthread_t tmr_thread; | | int control[2]; | | int fix_freq; | | sem_t fix_sem; | | int first_fix; | | NmeaReader reader; ------+ | #ifdef ATHR_GPSXtra | int xtra_init; | GpsXtraCallbacks xtra_callbacks; | #endif | #ifdef ATHR_GPSNi | int ni_init; | GpsNiCallbacks ni_callbacks; | GpsNiNotification ni_notification; | #endif | } GpsState; --------------------+ | ...... | | static GpsState _gps_state[1]; <---+ <-----------+ | static GpsState *gps_state = _gps_state; <---+ | | ...... | | GpsCallbacks* g_gpscallback = 0; <-----------------------*-*-+ ...... | | | | | | static const GpsInterface athrGpsInterface = { | | | .size =sizeof(GpsInterface), | | | .init = athr_gps_init, -----------------+ | | | .start = athr_gps_start, | | | | .stop = athr_gps_stop, | | | | .cleanup = athr_gps_cleanup, | | | | .inject_time = athr_gps_inject_time, | | | | .inject_location = athr_gps_inject_location, | | | | .delete_aiding_data = athr_gps_delete_aiding_data, | | | | .set_position_mode = athr_gps_set_position_mode, | | | | .get_extension = athr_gps_get_extension, | | | | }; | | | | | | | | static int athr_gps_init(GpsCallbacks* callbacks) <------+ | | | { | | | GpsState* s = _gps_state; -------------+ | | | | D("gps state initializing %d",s->init); | | | | s->callbacks = *callbacks; -------------------------+ | if (!s->init) | gps_state_init(s); ----------+ | | | if(!g_gpscallback) | | g_gpscallback = callbacks; ----------*----------------+ | return 0; | } | | static void | gps_state_init( GpsState* state ) <---------+ { ... if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) { ALOGE("could not create thread control socket pair: %s", strerror(errno)); goto Fail; } state->thread = state->callbacks.create_thread_cb("athr_gps", gps_state_thread, state); if (!state->thread) | { | ALOGE("could not create gps thread: %s", strerror(errno)); | goto Fail; | } | state->callbacks.set_capabilities_cb(GPS_CAPABILITY_SCHEDULING); | D("gps state initialized"); | ... | } | | static void <-----------------------+ gps_state_thread( void* arg ) { ... state->tmr_thread = state->callbacks.create_thread_cb("athr_gps_tmr", gps_timer_thread, state);if (!state->tmr_thread) | { | ALOGE("could not create gps timer thread: %s", strerror(errno)); | started = 0; +--------------+state->init = STATE_INIT; |goto Exit; |} ||state->nmea_thread = state->callbacks.create_thread_cb("athr_nmea_thread", gps_nmea_thread, |state); | |if (!state->nmea_thread) | |{ | |ALOGE("could not create gps nmea thread: %s", strerror(errno)); | |started = 0; | |state->init = STATE_INIT; | |goto Exit; | |} | |... | |} | || |static void | |gps_nmea_thread( void* arg ) <-----------------+ |{ |GpsState *state = (GpsState *)arg; <----+ |NmeaReader *reader; -----+ | |reader = &state->reader; -----+ -----+ || |DFR("gps entered nmea thread"); | |int versioncnt = 0; | || |// now loop +------------+ |while (continue_thread) | |{ | || |if (FD_ISSET(state->fd, &readfds)) | |{ | |memset(buf,0,sizeof(buf)); | |ret = read( state->fd, buf, sizeof(buf) ); | |if (ret > 0) | |{ | |if (strstr(buf, "CFG_R")) | |{ | |ALOGI("ver %s",buf); | |} | || |for (nn = 0; nn < ret; nn++) | |nmea_reader_addc( reader, buf[nn] ); <---+ -----------+ || |/* ATHR in/out sentences*/ | |if ((buf[0] == 'O') && (buf[1] == 'A') && (buf[2] == 'P')) { | |D("OAP200 sentences found"); | |athr_reader_parse(buf, ret); | |/* | |for (nn = 0; nn < ret; nn++) | |D("%.2x ", buf[nn]); | |*/ | |}else if ((buf[0] == '#') && (buf[1] == '!') && \ | |(buf[2] == 'G') && (buf[3] == 'S') && \ | |(buf[4] == 'M') && (buf[5] == 'A')) { | |D("GSMA sentences found"); | |athr_reader_parse(buf, ret); | |} | |} | |else | |{ | |DFR("Error on NMEA read :%s",strerror(errno)); | |gps_closetty(state); | |GPS_STATUS_CB(state->callbacks, GPS_STATUS_SESSION_END); | |sleep(3); //wait Orion shutdown. | |bOrionShutdown = 1; | |continue; | |} | |} | || |if(!continue_thread) | |break; | |} | |Exit: | |DFR("gps nmea thread destroyed"); | |return; | |} | || |static void | |nmea_reader_addc( NmeaReader* r, int c ) <--------------------+ |{ |int cnt; ||if (r->overflow) { |r->overflow = (c != '\n'); |return; |} ||if (r->pos >= (int) sizeof(r->in)-1 ) { |r->overflow = 1; |r->pos = 0; |return; |} ||r->in[r->pos] = (char)c; |r->pos += 1; ||if (c == '\n') { |gps_state_lock_fix(gps_state); |nmea_reader_parse( r ); --------+ |gps_state_unlock_fix(gps_state); | |r->pos = 0; | |} | |} | || |static void | |nmea_reader_parse( NmeaReader* r ) <-------+ |{ |/* we received a complete sentence, now parse it to generate |* a new GPS fix... |*/ |NmeaTokenizer tzer[1]; |Token tok; ||if (r->pos < 9) { |return; |} ||if (gps_state->callbacks.nmea_cb) { |struct timeval tv; |unsigned long long mytimems; |gettimeofday(&tv,NULL); |mytimems = tv.tv_sec * 1000 + tv.tv_usec / 1000; |gps_state->callbacks.nmea_cb(mytimems, r->in, r->pos); |} ||nmea_tokenizer_init(tzer, r->in, r->in + r->pos); |#ifdef GPS_DEBUG_TOKEN |{ |int n; |D("Found %d tokens", tzer->count); |for (n = 0; n < tzer->count; n++) { |Token tok = nmea_tokenizer_get(tzer,n); |D("%2d: '%.*s'", n, tok.end-tok.p, tok.p); |} |} |#endif ||tok = nmea_tokenizer_get(tzer, 0); ||if (tok.p + 5 > tok.end) { |/* for $PUNV sentences */ |if ( !memcmp(tok.p, "PUNV", 4) ) { |Token tok_cfg = nmea_tokenizer_get(tzer,1); ||if (!memcmp(tok_cfg.p, "CFG_R", 5)) { |} else if ( !memcmp(tok_cfg.p, "QUAL", 4) ) { |Token tok_sigma_x = nmea_tokenizer_get(tzer, 3); ||if (tok_sigma_x.p[0] != ',') { |Token tok_accuracy = nmea_tokenizer_get(tzer, 10); |nmea_reader_update_accuracy(r, tok_accuracy); |} |} else if (!memcmp(tok_cfg.p, "TIMEMAP", 7)) |{ |Token systime = nmea_tokenizer_get(tzer, 8); // system time token |Token timestamp = nmea_tokenizer_get(tzer, 2); // UTC time token |nmea_reader_update_timemap(r, systime, timestamp); |} |}else{ |} |return; |} ||if ( !memcmp(tok.p, "GPG", 3) ) //GPGSA,GPGGA,GPGSV |bGetFormalNMEA = 1; |// ignore first two characters. |tok.p += 2; ||if ( !memcmp(tok.p, "GGA", 3) ) { |// GPS fix |Token tok_fixstaus = nmea_tokenizer_get(tzer,6); ||if (tok_fixstaus.p[0] > '0') { ||Token tok_time = nmea_tokenizer_get(tzer,1); |Token tok_latitude = nmea_tokenizer_get(tzer,2); |Token tok_latitudeHemi = nmea_tokenizer_get(tzer,3); |Token tok_longitude = nmea_tokenizer_get(tzer,4); |Token tok_longitudeHemi = nmea_tokenizer_get(tzer,5); |Token tok_altitude = nmea_tokenizer_get(tzer,9); |Token tok_altitudeUnits = nmea_tokenizer_get(tzer,10); ||nmea_reader_update_time(r, tok_time); |nmea_reader_update_latlong(r, tok_latitude, |tok_latitudeHemi.p[0], |tok_longitude, |tok_longitudeHemi.p[0]); |nmea_reader_update_altitude(r, tok_altitude, tok_altitudeUnits); |} ||} else if ( !memcmp(tok.p, "GLL", 3) ) { ||Token tok_fixstaus = nmea_tokenizer_get(tzer,6); ||if (tok_fixstaus.p[0] == 'A') { ||Token tok_latitude = nmea_tokenizer_get(tzer,1); |Token tok_latitudeHemi = nmea_tokenizer_get(tzer,2); |Token tok_longitude = nmea_tokenizer_get(tzer,3); |Token tok_longitudeHemi = nmea_tokenizer_get(tzer,4); |Token tok_time = nmea_tokenizer_get(tzer,5); ||nmea_reader_update_time(r, tok_time); |nmea_reader_update_latlong(r, tok_latitude, |tok_latitudeHemi.p[0], |tok_longitude, |tok_longitudeHemi.p[0]); |} |} else if ( !memcmp(tok.p, "GSA", 3) ) { ||Token tok_fixStatus = nmea_tokenizer_get(tzer, 2); |int i; ||if (tok_fixStatus.p[0] != '\0' && tok_fixStatus.p[0] != '1') { ||r->sv_status.used_in_fix_mask = 0ul; ||for (i = 3; i <= 14; ++i){ ||Token tok_prn = nmea_tokenizer_get(tzer, i); |int prn = str2int(tok_prn.p, tok_prn.end); ||/* only available for PRN 1-32 */ |if ((prn > 0) && (prn < 33)){ |r->sv_status.used_in_fix_mask |= (1ul << (prn-1)); |r->sv_status_changed = 1; |/* mark this parameter to identify the GSA is in fixed state */ |r->gsa_fixed = 1; |} |} ||}else { |if (r->gsa_fixed == 1) { |r->sv_status.used_in_fix_mask = 0ul; |r->sv_status_changed = 1; |r->gsa_fixed = 0; |} |} |D("%s","zengjf GSA"); |} else if ( !memcmp(tok.p, "GSV", 3) ) { ||Token tok_noSatellites = nmea_tokenizer_get(tzer, 3); |int noSatellites = str2int(tok_noSatellites.p, tok_noSatellites.end); ||if (noSatellites > 0) { ||Token tok_noSentences = nmea_tokenizer_get(tzer, 1); |Token tok_sentence = nmea_tokenizer_get(tzer, 2); ||int sentence = str2int(tok_sentence.p, tok_sentence.end); |int totalSentences = str2int(tok_noSentences.p, tok_noSentences.end); |int curr; |int i; ||if (sentence == 1) { |r->sv_status_changed = 0; |r->sv_status.num_svs = 0; |} ||curr = r->sv_status.num_svs; ||i = 0; ||while (i < 4 && r->sv_status.num_svs < noSatellites){ ||Token tok_prn = nmea_tokenizer_get(tzer, i * 4 + 4); |Token tok_elevation = nmea_tokenizer_get(tzer, i * 4 + 5); |Token tok_azimuth = nmea_tokenizer_get(tzer, i * 4 + 6); |Token tok_snr = nmea_tokenizer_get(tzer, i * 4 + 7); ||r->sv_status.sv_list[curr].prn = str2int(tok_prn.p, tok_prn.end); |r->sv_status.sv_list[curr].elevation = |str2float(tok_elevation.p, tok_elevation.end); |r->sv_status.sv_list[curr].azimuth = |str2float(tok_azimuth.p, tok_azimuth.end); |r->sv_status.sv_list[curr].snr = str2float(tok_snr.p, tok_snr.end); ||r->sv_status.num_svs += 1; ||curr += 1; ||i += 1; |} ||if (sentence == totalSentences) { |r->sv_status_changed = 1; |} |} ||} else if ( !memcmp(tok.p, "RMC", 3) ) ||Token tok_fixStatus = nmea_tokenizer_get(tzer,2); ||if (tok_fixStatus.p[0] == 'A') |{ |Token tok_time = nmea_tokenizer_get(tzer,1); |Token tok_latitude = nmea_tokenizer_get(tzer,3); |Token tok_latitudeHemi = nmea_tokenizer_get(tzer,4); |Token tok_longitude = nmea_tokenizer_get(tzer,5); |Token tok_longitudeHemi = nmea_tokenizer_get(tzer,6); |Token tok_speed = nmea_tokenizer_get(tzer,7); |Token tok_bearing = nmea_tokenizer_get(tzer,8); |Token tok_date = nmea_tokenizer_get(tzer,9); ||nmea_reader_update_date( r, tok_date, tok_time ); ||nmea_reader_update_latlong( r, tok_latitude, |tok_latitudeHemi.p[0], |tok_longitude, |tok_longitudeHemi.p[0] ); ||nmea_reader_update_bearing( r, tok_bearing ); |nmea_reader_update_speed ( r, tok_speed ); |} |D("%s","zengjf RMC"); ||} else if ( !memcmp(tok.p, "VTG", 3) ) { ||Token tok_fixStatus = nmea_tokenizer_get(tzer,9); ||if (tok_fixStatus.p[0] != '\0' && tok_fixStatus.p[0] != 'N') |{ |Token tok_bearing = nmea_tokenizer_get(tzer,1); |Token tok_speed = nmea_tokenizer_get(tzer,5); ||nmea_reader_update_bearing( r, tok_bearing ); |nmea_reader_update_speed ( r, tok_speed ); |} ||} else if ( !memcmp(tok.p, "ZDA", 3) ) { ||Token tok_time; |Token tok_year = nmea_tokenizer_get(tzer,4); ||if (tok_year.p[0] != '\0') { ||Token tok_day = nmea_tokenizer_get(tzer,2); |Token tok_mon = nmea_tokenizer_get(tzer,3); ||nmea_reader_update_cdate( r, tok_day, tok_mon, tok_year ); ||} ||tok_time = nmea_tokenizer_get(tzer,1); ||if (tok_time.p[0] != '\0') { ||nmea_reader_update_time(r, tok_time); ||} |||} else { |tok.p -= 2; |} ||if (!gps_state->first_fix && |gps_state->init == STATE_INIT && |r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) { ||ath_send_ni_notification(r); ||if (gps_state->callbacks.location_cb) { |gps_state->callbacks.location_cb( &r->fix ); |r->fix.flags = 0; |} ||gps_state->first_fix = 1; |} |} ||static void |gps_timer_thread( void* arg ) <----------------------------------+{ int need_sleep = 0; int sleep_val = 0; GpsState *state = (GpsState *)arg; DFR("gps entered timer thread"); do { while(started != 1 && continue_thread) //
{ usleep(500*1000); } gps_state_lock_fix(state); if ((state->reader.fix.flags & GPS_LOCATION_HAS_LAT_LONG) != 0) { //D("gps fix cb: 0x%x", state->reader.fix.flags); if (state->callbacks.location_cb) { state->callbacks.location_cb( &state->reader.fix ); state->reader.fix.flags = 0; state->first_fix = 1; } if (state->fix_freq == 0) { state->fix_freq = -1; } } if (state->reader.sv_status_changed != 0) { // D("gps sv status callback"); if (state->callbacks.sv_status_cb) { state->callbacks.sv_status_cb( &state->reader.sv_status ); state->reader.sv_status_changed = 0; } } need_sleep = (state->fix_freq != -1 && (state->init != STATE_QUIT) ? 1 : 0) ; sleep_val = state->fix_freq; gps_state_unlock_fix(state); if (need_sleep) { sleep(sleep_val); } else { D("won't sleep because fix_freq=%d state->init=%d",state->fix_freq, sta te->init); } ath_send_ni_notification(&state->reader); if( state->init == STATE_INIT && lastcmd == CMD_STOP && started == 1) { int gap = 0; D("Wait for NMEA coming,%d,%d,%d", state->init , lastcmd, started); while (state->init != STATE_START && bGetFormalNMEA == 0 && continue_th read && !bOrionShutdown){ usleep(300*1000); if (++gap > 100) break; } ; D("Get NMEA %d and state %d",bGetFormalNMEA,state->init); // even we don't get nmea after 30 second, still force close it bGetFormalNMEA |= (gap >= 100); if( state->init == STATE_INIT && lastcmd == CMD_STOP && started == 1) { gps_sleep(state); } else { D("User enter LM before sending sleep, so drop it"); } } } while(continue_thread); DFR("gps timer thread destroyed"); return; }
?
總結
以上是生活随笔為你收集整理的I.MX6 GPS JNI HAL register init hacking的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 近期总结:generator-web,前
- 下一篇: 移动端常用状态