Yocto开发笔记之《驱动调试-GPS数据采集》(QQ交流群:519230208)
开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处。
QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样
========================================================
参考资料:
- GPS数据包分析:http://www.cnblogs.com/csMapx/archive/2011/11/02/2232663.html
- 手机定位原理,关于GPS&GLONASS&北斗:http://www.cnblogs.com/radiolover/p/4307453.html
GSP 数据解析(搜索 NMEA parser)
- C Project : http://nmea.sourceforge.net/#downloads
C++ Project : http://www.visualgps.net/WhitePapers/NMEAParser/NMEAParser.htm
单片机(郭天详):http://download.csdn.net/detail/suzhouzhouchunhua/2370503
Makefile中添加以下内容:
- CC=arm-poky-linux-gnueabi-gcc --sysroot=/home/summer/test-yocto/qemuarm
- LD=arm-poky-linux-gnueabi-ld --sysroot=/home/summer/test-yocto/qemuarm
- CFLAGS=-O2 -pipe -g -feliminate-unused-debug-types
- CXXFLAGS=-O2 -pipe -g -feliminate-unused-debug-types
ERROR记录与解决方法
- error:
- lib/libnmea.a(generate.o):在函数‘nmea_gsv_npack’中:
- generate.c:(.text+0x7f0):对‘ceil’未定义的引用
- collect2: error: ld returned exit status
- make: *** [samples_generate] 错误
- rm samples/generate/main.o
- Makefile中添加红色,ubuntu编译器不能识别加在前边。。。晕,macos完全不用修改
- samples_%: samples/%/main.o
- $(CC) $< $(LIBS) -o build/$@ -lm
- Error case :
- , Lat: -nan, Lon: nan, Sig: , Fix:
- $GPRMC,213922.000,A,4221.1129,N,07102.9146,W,0.00,,,,,A*6F
- Trace:
- $GPGGA,213923.000,4221.1129,N,07102.9146,W,,,3.9,129.7,M,-33.7,M,,*6F
- Trace:
- , Lat: -nan, Lon: nan, Sig: , Fix:
- $GPGSA,A,,,,,,,,,,,,,,4.1,3.9,1.0*3A
- Trace:
- , Lat: -nan, Lon: nan, Sig: , Fix:
- $GPRMC,213923.000,A,4221.1129,N,07102.9146,W,0.00,,,,,A*6E
- Trace:
- $GPGGA,213924.000,4221.1129,N,07102.9146,W,,,3.9,129.7,M,-33.7,M,,*
- Trace:
- , Lat: -nan, Lon: nan, Sig: , Fix:
- $GPGSA,A,,,,,,,,,,,,,,4.0,3.9,1.0*3B
- Trace:
- , Lat: -nan, Lon: nan, Sig: , Fix:
- $GPRMC,213924.000,A,4221.1129,N,07102.9146,W,0.00,,,,,A*
- Trace:
- $GPGGA,213925.000,4221.1129,N,07102.9146,W,,,3.9,129.7,M,-33.7,M,,*
- Trace:
- , Lat: -nan, Lon: nan, Sig: , Fix:
- $GPGSA,A,,,,,,,,,,,,,,4.0,3.9,1.0*3B
- Trace:
- $GPRMC,213925.000,A,4221.1129,N,07102.9146,W,0.00,,,,,A*
- Trace:
- , Lat: -nan, Lon: nan, Sig: , Fix:
- $GPGGA,213926.000,4221.1112,N,07102.9177,W,,,3.9,136.5,M,-33.7,M,,*6C
- Trace:
- , Lat: -nan, Lon: nan, Sig: , Fix:
- ---------------------------------------------------------------------------------
- ---------------------------------------------------------------------------------
- Right case:
- $GPGSV,,,,,,,,,,,,,,,,,,,*7F
- Trace:
- $GPGSV,,,,,,,,,,,,,,,*
- Trace:
- , Lat: 0.739180, Lon: -1.240032, Sig: , Fix:
- $GPRMC,213921.000,A,4221.1129,N,07102.9146,W,0.00,,,,,A*6C
- Trace:
- , Lat: 0.739180, Lon: -1.240032, Sig: , Fix:
- $GPGGA,213922.000,4221.1129,N,07102.9146,W,,,3.9,129.7,M,-33.7,M,,*6E
- Trace:
- $GPGSA,A,,,,,,,,,,,,,,4.1,3.9,1.0*3A
- Trace:
- , Lat: 0.739180, Lon: -1.240032, Sig: , Fix:
- $GPRMC,213922.000,A,4221.1129,N,07102.9146,W,0.00,,,,,A*6F
- Trace:
- $GPGGA,213923.000,4221.1129,N,07102.9146,W,,,3.9,129.7,M,-33.7,M,,*6F
- Trace:
- , Lat: 0.739180, Lon: -1.240032, Sig: , Fix:
- $GPGSA,A,,,,,,,,,,,,,,4.1,3.9,1.0*3A
- Trace:
- , Lat: 0.739180, Lon: -1.240032, Sig: , Fix:
- $GPRMC,213923.000,A,4221.1129,N,07102.9146,W,0.00,,,,,A*6E
- Trace:
- $GPGGA,213924.000,4221.1129,N,07102.9146,W,,,3.9,129.7,M,-33.7,M,,*
- Trace:
- , Lat: 0.739180, Lon: -1.240032, Sig: , Fix:
- $GPGSA,A,,,,,,,,,,,,,,4.0,3.9,1.0*3B
- Trace:
- , Lat: 0.739180, Lon: -1.240032, Sig: , Fix:
- $GPRMC,213924.000,A,4221.1129,N,07102.9146,W,0.00,,,,,A*
- /*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /* this implements a GPS hardware library for the Android emulator.
- * the following code should be built as a shared library that will be
- * placed into /system/lib/hw/gps.goldfish.so
- *
- * it will be loaded by the code in hardware/libhardware/hardware.c
- * which is itself called from android_location_GpsLocationProvider.cpp
- ******************************************************************************
- ******************************************************************************
- *
- * Modified by liukun321 GJGJ
- * http://blog.csdn.net/liukun321
- *
- ******************************************************************************
- ******************************************************************************/
- #include <errno.h>
- #include <pthread.h>
- #include <fcntl.h>
- #include <sys/epoll.h>
- #include <math.h>
- #include <time.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <termios.h>
- #include <errno.h>
- #define LOG_TAG "gps_Ublox6M"
- #include <cutils/log.h>
- #include <cutils/sockets.h>
- #include <hardware/gps.h>
- #include <hardware/qemud.h>
- #include <hardware/hardware.h>
- /* the name of the qemud-controlled socket */
- #define QEMU_CHANNEL_NAME "gps"
- #define GPS_DEBUG 0
- #define Ublox_6M 1
- #if GPS_DEBUG
- # define D(...) LOGD(__VA_ARGS__)
- #else
- # define D(...) ((void))
- #endif
- /*****************************************************************/
- /*****************************************************************/
- /***** *****/
- /***** N M E A T O K E N I Z E R *****/
- /***** *****/
- /*****************************************************************/
- /*****************************************************************/
- typedef struct {
- const char* p;
- const char* end;
- } Token;
- #define MAX_NMEA_TOKENS 16
- typedef struct {
- int count;
- Token tokens[ MAX_NMEA_TOKENS ];
- } NmeaTokenizer;
- /*********************************************************************/
- GpsStatus g_status;
- static int
- nmea_tokenizer_init( NmeaTokenizer* t, const char* p, const char* end )
- {
- int count = ;
- char* q;
- // the initial '$' is optional
- if (p < end && p[] == '$')
- p += ;
- // remove trailing newline
- if (end > p && end[-] == '\n') {
- end -= ;
- if (end > p && end[-] == '\r')
- end -= ;
- }
- // get rid of checksum at the end of the sentecne
- if (end >= p+ && end[-] == '*') {
- end -= ;
- }
- while (p < end) {
- const char* q = p;
- q = memchr(p, ',', end-p);
- if (q == NULL)
- q = end;
- if (q >= p) {//////////////////////////////////////////////////////////////////////////////
- if (count < MAX_NMEA_TOKENS) {
- t->tokens[count].p = p;
- t->tokens[count].end = q;
- count += ;
- }
- }
- if (q < end)
- q += ;
- p = q;
- }
- t->count = count;
- return count;
- }
- static Token
- nmea_tokenizer_get( NmeaTokenizer* t, int index )
- {
- Token tok;
- static const char* dummy = "";
- if (index < || index >= t->count) {
- tok.p = tok.end = dummy;
- } else
- tok = t->tokens[index];
- return tok;
- }
- static int
- str2int( const char* p, const char* end )
- {
- int result = ;
- int len = end - p;
- for ( ; len > ; len--, p++ )
- {
- int c;
- if (p >= end)
- goto Fail;
- c = *p - '';
- if ((unsigned)c >= )
- goto Fail;
- result = result* + c;
- }
- return result;
- Fail:
- return -;
- }
- static double
- str2float( const char* p, const char* end )
- {
- int result = ;
- int len = end - p;
- char temp[];
- if (len >= (int)sizeof(temp))
- return .;
- memcpy( temp, p, len );
- temp[len] = ;
- return strtod( temp, NULL );
- }
- /*****************************************************************/
- /*****************************************************************/
- /***** *****/
- /***** N M E A P A R S E R *****/
- /***** *****/
- /*****************************************************************/
- /*****************************************************************/
- #define NMEA_MAX_SIZE 83
- 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+ ];
- } NmeaReader;
- static void
- nmea_reader_update_utc_diff( NmeaReader* r )
- {
- time_t now = time(NULL);
- struct tm tm_local;
- struct tm tm_utc;
- long time_local, time_utc;
- gmtime_r( &now, &tm_utc );
- localtime_r( &now, &tm_local );
- time_local = tm_local.tm_sec +
- *(tm_local.tm_min +
- *(tm_local.tm_hour +
- *(tm_local.tm_yday +
- *tm_local.tm_year)));
- time_utc = tm_utc.tm_sec +
- *(tm_utc.tm_min +
- *(tm_utc.tm_hour +
- *(tm_utc.tm_yday +
- *tm_utc.tm_year)));
- r->utc_diff = time_local - time_utc;
- }
- static void
- nmea_reader_init( NmeaReader* r )
- {
- memset( r, , sizeof(*r) );
- r->pos = ;
- r->overflow = ;
- r->utc_year = -;
- r->utc_mon = -;
- r->utc_day = -;
- #ifdef Ublox_6M
- r->callback.sv_status_cb = NULL;//////////////////////////////////////////
- r->callback.nmea_cb = NULL;
- r->callback.location_cb = NULL;
- r->callback.status_cb = NULL;
- #else
- r->callback = NULL;
- #endif
- r->fix.size = sizeof(r->fix);
- nmea_reader_update_utc_diff( r );
- }
- static void
- nmea_reader_set_callback( NmeaReader* r, gps_location_callback cb )
- {
- #ifdef Ublox_6M
- r->callback.location_cb = cb;//////////////////////////////////////////////////
- #else
- r->callback = cb;
- #endif
- if (cb != NULL && r->fix.flags != ) {
- D("%s: sending latest fix to new callback", __FUNCTION__);
- #ifdef Ublox_6M
- r->callback.location_cb( &r->fix );/////////////////////////////////////////////
- #else
- r->fix.flags = ;
- #endif
- }
- }
- static int
- nmea_reader_update_time( NmeaReader* r, Token tok )
- {
- int hour, minute;
- double seconds;
- struct tm tm;
- time_t fix_time;
- if (tok.p + > tok.end)
- return -;
- if (r->utc_year < ) {
- // no date yet, get current one
- time_t now = time(NULL);
- gmtime_r( &now, &tm );
- r->utc_year = tm.tm_year + ;
- r->utc_mon = tm.tm_mon + ;
- r->utc_day = tm.tm_mday;
- }
- hour = str2int(tok.p, tok.p+);
- minute = str2int(tok.p+, tok.p+);
- seconds = str2float(tok.p+, tok.end);
- tm.tm_hour = hour;
- tm.tm_min = minute;
- tm.tm_sec = (int) seconds;
- tm.tm_year = r->utc_year - ;
- tm.tm_mon = r->utc_mon - ;
- tm.tm_mday = r->utc_day;
- tm.tm_isdst = -;
- fix_time = mktime( &tm ) + r->utc_diff;
- r->fix.timestamp = (long long)fix_time * ;
- return ;
- }
- static int
- nmea_reader_update_date( NmeaReader* r, Token date, Token time )
- {
- Token tok = date;
- int day, mon, year;
- if (tok.p + != tok.end) {
- D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
- return -;
- }
- day = str2int(tok.p, tok.p+);
- mon = str2int(tok.p+, tok.p+);
- year = str2int(tok.p+, tok.p+) + ;
- if ((day|mon|year) < ) {
- D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
- return -;
- }
- r->utc_year = year;
- r->utc_mon = mon;
- r->utc_day = day;
- return nmea_reader_update_time( r, time );
- }
- static double
- convert_from_hhmm( Token tok )
- {
- double val = str2float(tok.p, tok.end);
- int degrees = (int)(floor(val) / );
- double minutes = val - degrees*.;
- double dcoord = degrees + minutes / 60.0;
- return dcoord;
- }
- static int
- nmea_reader_update_latlong( NmeaReader* r,
- Token latitude,
- char latitudeHemi,
- Token longitude,
- char longitudeHemi )
- {
- double lat, lon;
- Token tok;
- tok = latitude;
- if (tok.p + > tok.end) {
- D("latitude is too short: '%.*s'", tok.end-tok.p, tok.p);
- return -;
- }
- lat = convert_from_hhmm(tok);
- if (latitudeHemi == 'S')
- lat = -lat;
- tok = longitude;
- if (tok.p + > tok.end) {
- D("longitude is too short: '%.*s'", tok.end-tok.p, tok.p);
- return -;
- }
- lon = convert_from_hhmm(tok);
- if (longitudeHemi == 'W')
- lon = -lon;
- r->fix.flags |= GPS_LOCATION_HAS_LAT_LONG;
- r->fix.latitude = lat;
- r->fix.longitude = lon;
- return ;
- }
- static int
- nmea_reader_update_altitude( NmeaReader* r,
- Token altitude,
- Token units )
- {
- double alt;
- Token tok = altitude;
- if (tok.p >= tok.end)
- return -;
- r->fix.flags |= GPS_LOCATION_HAS_ALTITUDE;
- r->fix.altitude = str2float(tok.p, tok.end);
- return ;
- }
- static int
- nmea_reader_update_bearing( NmeaReader* r,
- Token bearing )
- {
- double alt;
- Token tok = bearing;
- if (tok.p >= tok.end)
- return -;
- r->fix.flags |= GPS_LOCATION_HAS_BEARING;
- r->fix.bearing = str2float(tok.p, tok.end);
- return ;
- }
- static int
- nmea_reader_update_speed( NmeaReader* r,
- Token speed )
- {
- double alt;
- Token tok = speed;
- if (tok.p >= tok.end)
- return -;
- r->fix.flags |= GPS_LOCATION_HAS_SPEED;
- r->fix.speed = str2float(tok.p, tok.end);
- return ;
- }
- static int nmea_reader_update_accuracy(NmeaReader * r, Token accuracy)
- {
- double acc;
- Token tok = accuracy;
- if(tok.p >= tok.end)
- return -;
- r->fix.accuracy = str2float(tok.p, tok.end);
- if(r->fix.accuracy == 99.99){
- return ;
- }
- r->fix.flags |= GPS_LOCATION_HAS_ACCURACY;
- return ;
- }
- /* this is the state of our connection to the qemu_gpsd daemon */
- typedef struct {
- int init;
- int fd;
- GpsCallbacks callbacks;
- pthread_t thread;
- int control[];
- } GpsState;
- static GpsState _gps_state[];
- static void
- nmea_reader_parse( NmeaReader* r )
- {
- /* we received a complete sentence, now parse it to generate
- * a new GPS fix...
- */
- NmeaTokenizer tzer[];
- Token tok;
- D("Received: '%.*s'", r->pos, r->in);
- if (r->pos < ) {
- D("Too short. discarded.");
- return;
- }
- nmea_tokenizer_init(tzer, r->in, r->in + r->pos);
- #if GPS_DEBUG
- {
- int n;
- D("Found %d tokens", tzer->count);
- for (n = ; 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, );
- if (tok.p + > tok.end) {
- D("sentence id '%.*s' too short, ignored.", tok.end-tok.p, tok.p);
- return;
- }
- // ignore first two characters.
- tok.p += ;
- if ( !memcmp(tok.p, "GGA", ) ) {
- // GPS fix
- Token tok_time = nmea_tokenizer_get(tzer,);
- Token tok_latitude = nmea_tokenizer_get(tzer,);
- Token tok_latitudeHemi = nmea_tokenizer_get(tzer,);
- Token tok_longitude = nmea_tokenizer_get(tzer,);
- Token tok_longitudeHemi = nmea_tokenizer_get(tzer,);
- Token tok_altitude = nmea_tokenizer_get(tzer,);
- Token tok_altitudeUnits = nmea_tokenizer_get(tzer,);
- nmea_reader_update_time(r, tok_time);
- nmea_reader_update_latlong(r, tok_latitude,
- tok_latitudeHemi.p[],
- tok_longitude,
- tok_longitudeHemi.p[]);
- nmea_reader_update_altitude(r, tok_altitude, tok_altitudeUnits);
- } else if ( !memcmp(tok.p, "GSA", ) ) {
- // do something ?
- #ifdef Ublox_6M
- {
- D("may%s,%d,%s,gsa\n",__FILE__,__LINE__,__FUNCTION__);
- Token tok_fixStatus = nmea_tokenizer_get(tzer, );
- int i;
- if (tok_fixStatus.p[] != '\0' && tok_fixStatus.p[] != '') {
- Token tok_accuracy = nmea_tokenizer_get(tzer, );//position dilution of precision dop
- nmea_reader_update_accuracy(r, tok_accuracy);
- r->sv_status.used_in_fix_mask = 0ul;
- D("\n");
- for (i = ; i <= ; ++i){
- Token tok_prn = nmea_tokenizer_get(tzer, i);
- int prn = str2int(tok_prn.p, tok_prn.end);
- D("gsa,prn=%d,",prn);
- if (prn > ){
- r->sv_status.used_in_fix_mask |= (1ul << ( prn-));
- r->sv_status_changed = ;
- }
- }D("\n");
- D("%s: fix mask is %x", __FUNCTION__, r->sv_status.used_in_fix_mask);
- // D(" [log hit][%s:%d] fix.flags=0x%x ", __FUNCTION__, __LINE__, r->fix.flags);
- }
- D(" [log hit][%s:%d] fix.flags=0x%x ", __FUNCTION__, __LINE__, r->fix.flags);
- }
- #endif
- } //////////////////////////////////////////////////////////////////////////////////////////////////
- #ifdef Ublox_6M
- else if ( !memcmp(tok.p, "GSV", ) ) {
- D("may%s,%d,%s,gsV\n",__FILE__,__LINE__,__FUNCTION__);
- Token tok_noSatellites = nmea_tokenizer_get(tzer, );
- int noSatellites = str2int(tok_noSatellites.p, tok_noSatellites.end);
- D("%d,inview=%d,\n",__LINE__,noSatellites);
- if (noSatellites > ) {
- Token tok_noSentences = nmea_tokenizer_get(tzer, );
- Token tok_sentence = nmea_tokenizer_get(tzer, );
- int sentence = str2int(tok_sentence.p, tok_sentence.end);
- int totalSentences = str2int(tok_noSentences.p, tok_noSentences.end);
- D("%d,gsv_index=%d,gsv_total=%d\n",__LINE__,sentence,totalSentences);
- int curr;
- int i;
- if (sentence == ) {
- D("msg_index=%d\n",sentence);
- // r->sv_status_changed = 0;
- r->sv_status.num_svs = ;
- r->sv_status.ephemeris_mask=0ul;
- r->sv_status.almanac_mask=0ul;
- }
- curr = r->sv_status.num_svs;
- i = ;
- while (i < && r->sv_status.num_svs < noSatellites){
- Token tok_prn = nmea_tokenizer_get(tzer, i * + );
- Token tok_elevation = nmea_tokenizer_get(tzer, i * + );
- Token tok_azimuth = nmea_tokenizer_get(tzer, i * + );
- Token tok_snr = nmea_tokenizer_get(tzer, i * + );
- 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.ephemeris_mask|=(1ul << (r->sv_status.sv_list[curr].prn-));
- r->sv_status.almanac_mask|=(1ul << (r->sv_status.sv_list[curr].prn-));
- r->sv_status.num_svs += ;
- D("**********curr=%d\n",curr);
- D("%d,prn=%d:snr=%f\n",__LINE__,r->sv_status.sv_list[curr].prn,r->sv_status.sv_list[curr].snr);
- curr += ;
- i += ;
- }
- if (sentence == totalSentences) {
- D("msg=%d,msgindex=%d",totalSentences,sentence);
- #ifdef Ublox_6M
- r->callback.sv_status_cb=_gps_state->callbacks.sv_status_cb;
- if (r->sv_status_changed !=) {
- if (r->callback.sv_status_cb) {
- #if GPS_DEBUG
- D("%d,SV_STATSU,change=%d\n",__LINE__,r->sv_status_changed);
- int nums=r->sv_status.num_svs;
- D("num_svs=%d,emask=%x,amask=%x,inusemask=%x\n",r->sv_status.num_svs,r->sv_status.ephemeris_mask,r->sv_status.almanac_mask,r->sv_status.used_in_fix_mask);
- D("************88\n");
- while(nums)
- {
- nums--;
- D("prn=%d:snr=%f\n",r->sv_status.sv_list[nums].prn,r->sv_status.sv_list[nums].snr);
- }D("************88\n");
- #endif
- r->callback.sv_status_cb( &(r->sv_status) );
- r->sv_status_changed = ;
- }else {
- D("no callback, keeping status data until needed !");
- }
- }
- #endif
- }
- D("%s: GSV message with total satellites %d", __FUNCTION__, noSatellites);
- }
- }
- #endif////////////////////////////////////////////////////////////////////////////////////////////
- else if ( !memcmp(tok.p, "GLL", ) ) {
- Token tok_fixstaus = nmea_tokenizer_get(tzer,);
- if (tok_fixstaus.p[] == 'A') {
- Token tok_latitude = nmea_tokenizer_get(tzer,);
- Token tok_latitudeHemi = nmea_tokenizer_get(tzer,);
- Token tok_longitude = nmea_tokenizer_get(tzer,);
- Token tok_longitudeHemi = nmea_tokenizer_get(tzer,);
- Token tok_time = nmea_tokenizer_get(tzer,);
- nmea_reader_update_time(r, tok_time);
- nmea_reader_update_latlong(r, tok_latitude, tok_latitudeHemi.p[], tok_longitude, tok_longitudeHemi.p[]);
- }
- }
- /////////////////////////////////////////////////////////////////////////////////
- else if ( !memcmp(tok.p, "RMC", ) ) {
- #ifndef Ublox_6M
- Token tok_time = nmea_tokenizer_get(tzer,);
- Token tok_fixStatus = nmea_tokenizer_get(tzer,);
- Token tok_latitude = nmea_tokenizer_get(tzer,);
- Token tok_latitudeHemi = nmea_tokenizer_get(tzer,);
- Token tok_longitude = nmea_tokenizer_get(tzer,);
- Token tok_longitudeHemi = nmea_tokenizer_get(tzer,);
- Token tok_speed = nmea_tokenizer_get(tzer,);
- Token tok_bearing = nmea_tokenizer_get(tzer,);
- Token tok_date = nmea_tokenizer_get(tzer,);
- D("in RMC, fixStatus=%c", tok_fixStatus.p[]);
- if (tok_fixStatus.p[] == 'A')
- {
- nmea_reader_update_date( r, tok_date, tok_time );
- nmea_reader_update_latlong( r, tok_latitude,
- tok_latitudeHemi.p[],
- tok_longitude,
- tok_longitudeHemi.p[] );
- nmea_reader_update_bearing( r, tok_bearing );
- nmea_reader_update_speed ( r, tok_speed );
- }
- #else
- Token tok_time = nmea_tokenizer_get(tzer,);
- Token tok_fixStatus = nmea_tokenizer_get(tzer,);
- Token tok_latitude = nmea_tokenizer_get(tzer,);
- Token tok_latitudeHemi = nmea_tokenizer_get(tzer,);
- Token tok_longitude = nmea_tokenizer_get(tzer,);
- Token tok_longitudeHemi = nmea_tokenizer_get(tzer,);
- Token tok_speed = nmea_tokenizer_get(tzer,);
- Token tok_bearing = nmea_tokenizer_get(tzer,);
- Token tok_date = nmea_tokenizer_get(tzer,);
- D("in RMC, fixStatus=%c", tok_fixStatus.p[]);
- if (tok_fixStatus.p[] == 'A')
- {
- nmea_reader_update_date( r, tok_date, tok_time );
- nmea_reader_update_latlong( r, tok_latitude,
- tok_latitudeHemi.p[],
- tok_longitude,
- tok_longitudeHemi.p[] );
- nmea_reader_update_bearing( r, tok_bearing );
- nmea_reader_update_speed ( r, tok_speed );
- #ifdef Ublox_6M
- r->callback.location_cb=_gps_state->callbacks.location_cb;
- r->callback.nmea_cb=_gps_state->callbacks.nmea_cb;
- r->callback.status_cb=_gps_state->callbacks.status_cb;
- if (r->callback.status_cb) {
- D("report,status,flags=%d\n",r->fix.flags);
- r->callback.status_cb( (struct GpsStatus *)&(r->fix.flags) );
- }
- if (r->callback.location_cb) {
- D("location_cb report:r->fix.flags=%d,r->latitude=%f,r->longitude=%f,r->altitude=%f,r->speed=%f,r->bearing=%f,r->accuracy=%f\n",r->fix.flags,r->fix.latitude,r->fix.longitude,r->fix.altitude,r->fix.speed,r->fix.bearing,r->fix.accuracy);
- r->callback.location_cb( &r->fix );
- D("%d,cc=%d",__LINE__,cc);
- r->fix.flags = ;
- }
- if (r->callback.nmea_cb) {
- D("report,timestamp=%llx,%llu\n",r->fix.timestamp,r->fix.timestamp);
- r->callback.nmea_cb( r->fix.timestamp,r->in,r->pos );
- }
- #else
- r->callback=_gps_state.callbacks->location_cb;
- //r->callback.nmea_cb=_gps_state->callbacks.nmea_cb;
- if (r->callback) {D("if2 (r->callback.location_cb)\n");
- r->callback( &r->fix );
- r->fix.flags = ;
- }
- #endif
- }
- #endif
- }
- else
- {
- tok.p -= ;
- D("unknown sentence '%.*s", tok.end-tok.p, tok.p);
- }
- if (r->fix.flags != ) {
- #if GPS_DEBUG
- char temp[];
- char* p = temp;
- char* end = p + sizeof(temp);
- struct tm utc;
- p += snprintf( p, end-p, "sending fix" );
- if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) {
- p += snprintf(p, end-p, " lat=%g lon=%g", r->fix.latitude, r->fix.longitude);
- }
- if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) {
- p += snprintf(p, end-p, " altitude=%g", r->fix.altitude);
- }
- if (r->fix.flags & GPS_LOCATION_HAS_SPEED) {
- p += snprintf(p, end-p, " speed=%g", r->fix.speed);
- }
- if (r->fix.flags & GPS_LOCATION_HAS_BEARING) {
- p += snprintf(p, end-p, " bearing=%g", r->fix.bearing);
- }
- if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) {
- p += snprintf(p,end-p, " accuracy=%g", r->fix.accuracy);
- }
- gmtime_r( (time_t*) &r->fix.timestamp, &utc );
- p += snprintf(p, end-p, " time=%s", asctime( &utc ) );
- LOGD("%s",temp);
- #endif
- #ifndef Ublox_6M
- if (r->callback ) {
- r->callback( &r->fix );
- r->fix.flags = ;
- }
- else {
- D("no callback, keeping data until needed !");
- }
- #endif
- }
- }
- static void
- nmea_reader_addc( NmeaReader* r, int c )
- {
- if (r->overflow) {
- r->overflow = (c != '\n');
- return;
- }
- if (r->pos >= (int) sizeof(r->in)- ) {
- r->overflow = ;
- r->pos = ;
- return;
- }
- r->in[r->pos] = (char)c;
- r->pos += ;
- if (c == '\n') {
- nmea_reader_parse( r );
- r->pos = ;
- }
- }
- /*****************************************************************/
- /*****************************************************************/
- /***** *****/
- /***** C O N N E C T I O N S T A T E *****/
- /***** *****/
- /*****************************************************************/
- /*****************************************************************/
- /* commands sent to the gps thread */
- enum {
- CMD_QUIT = ,
- CMD_START = ,
- CMD_STOP =
- };
- static void
- gps_state_done( GpsState* s )
- {
- // tell the thread to quit, and wait for it
- char cmd = CMD_QUIT;
- void* dummy;
- write( s->control[], &cmd, );
- pthread_join(s->thread, &dummy);
- // close the control socket pair
- close( s->control[] ); s->control[] = -;
- close( s->control[] ); s->control[] = -;
- // close connection to the QEMU GPS daemon
- close( s->fd ); s->fd = -;
- s->init = ;
- }
- static void
- gps_state_start( GpsState* s )
- {
- char cmd = CMD_START;
- int ret;
- do { ret=write( s->control[], &cmd, ); }
- while (ret < && errno == EINTR);
- if (ret != )
- D("%s: could not send CMD_START command: ret=%d: %s",
- __FUNCTION__, ret, strerror(errno));
- }
- static void
- gps_state_stop( GpsState* s )
- {
- char cmd = CMD_STOP;
- int ret;
- do { ret=write( s->control[], &cmd, ); }
- while (ret < && errno == EINTR);
- if (ret != )
- D("%s: could not send CMD_STOP command: ret=%d: %s",
- __FUNCTION__, ret, strerror(errno));
- }
- static int
- epoll_register( int epoll_fd, int fd )
- {
- struct epoll_event ev;
- int ret, flags;
- /* important: make the fd non-blocking */
- flags = fcntl(fd, F_GETFL);
- fcntl(fd, F_SETFL, flags | O_NONBLOCK);
- ev.events = EPOLLIN;
- ev.data.fd = fd;
- do {
- ret = epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &ev );
- } while (ret < && errno == EINTR);
- return ret;
- }
- static int
- epoll_deregister( int epoll_fd, int fd )
- {
- int ret;
- do {
- ret = epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL );
- } while (ret < && errno == EINTR);
- return ret;
- }
- /* this is the main thread, it waits for commands from gps_state_start/stop and,
- * when started, messages from the QEMU GPS daemon. these are simple NMEA sentences
- * that must be parsed to be converted into GPS fixes sent to the framework
- */
- static void*
- gps_state_thread( void* arg )
- {
- GpsState* state = (GpsState*) arg;
- NmeaReader reader[];
- int epoll_fd = epoll_create();
- int started = ;
- int gps_fd = state->fd;
- int control_fd = state->control[];
- nmea_reader_init( reader );
- // register control file descriptors for polling
- epoll_register( epoll_fd, control_fd );
- epoll_register( epoll_fd, gps_fd );
- D("gps thread running");
- // now loop
- for (;;) {
- struct epoll_event events[];
- int ne, nevents;
- nevents = epoll_wait( epoll_fd, events, , - );
- if (nevents < ) {
- if (errno != EINTR)
- LOGE("epoll_wait() unexpected error: %s", strerror(errno));
- continue;
- }
- D("gps thread received %d events", nevents);
- for (ne = ; ne < nevents; ne++) {
- if ((events[ne].events & (EPOLLERR|EPOLLHUP)) != ) {
- LOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?");
- goto Exit;
- }
- if ((events[ne].events & EPOLLIN) != ) {
- int fd = events[ne].data.fd;
- if (fd == control_fd)
- {
- char cmd = ;
- int ret;
- D("gps control fd event");
- do {
- ret = read( fd, &cmd, );
- } while (ret < && errno == EINTR);
- if (cmd == CMD_QUIT) {
- D("gps thread quitting on demand");
- goto Exit;
- }
- else if (cmd == CMD_START) {
- if (!started) {
- D("gps thread starting location_cb=%p", state->callbacks.location_cb);
- started = ;
- //******************************************************************
- g_status.status=GPS_STATUS_SESSION_BEGIN;//\BF\AAʼ\B5\BC\BA\BD
- state->callbacks.status_cb(&g_status);
- //******************************************************************
- nmea_reader_set_callback( reader, state->callbacks.location_cb );
- LOGE("%d",gps_fd);
- }
- }
- else if (cmd == CMD_STOP) {
- if (started) {
- D("gps thread stopping");
- started = ;
- //********************************************************************
- g_status.status=GPS_STATUS_SESSION_END; //ֹͣ
- state->callbacks.status_cb(&g_status);
- //********************************************************************
- nmea_reader_set_callback( reader, NULL );
- }
- }
- }
- else if (fd == gps_fd)
- {
- char buff[];
- D("gps fd event");
- for (;;) {
- int nn, ret;
- ret = read( fd, buff, sizeof(buff) );
- if (ret < ) {
- 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 = ; nn < ret; nn++)
- nmea_reader_addc( reader, buff[nn] );
- }
- D("gps fd event end");
- }
- else
- {
- LOGE("epoll_wait() returned unkown fd %d ?", fd);
- }
- }
- }
- }
- Exit:
- return NULL;
- }
- static void
- gps_state_init( GpsState* state )
- {
- state->init = ;
- state->control[] = -;
- state->control[] = -;
- state->fd = -;
- int ret = -;
- struct termios gps_termios;
- //*****************************************************************************
- state->fd= open("/dev/s3c2410_serial1",O_RDWR|O_NOCTTY|O_NDELAY);//\D5\E2\C0\EF\D3õ\C4\CA\C7UART1
- if( state->fd < ){
- LOGE("open port /dev/s3c2410_serial1 ERROR..state->fd=%d\n",state->fd);
- exit();
- }else
- LOGE("open port:/dev/s3c2410_serial1 succceed..state->fd=%d\n",state->fd);
- if(fcntl( state->fd,F_SETFL,)<)
- LOGE("fcntl F_SETFL\n");
- {
- LOGI(">>>> Port setup..\n");
- int err;
- tcflush(state->fd, TCIOFLUSH);//\D2\D4\CF\C2\CA\C7\C5\E4\D6ô\AE\BFڵIJ\CE\CA\FD
- if ((err = tcgetattr(state->fd,&gps_termios)) != )
- {
- LOGI("tcgetattr(%d) = %d,errno %d\r\n",state->fd,err,errno);
- close(state->fd);
- }
- gps_termios.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
- gps_termios.c_oflag &= ~OPOST;
- gps_termios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
- gps_termios.c_cflag &= ~(CSIZE|PARENB);
- gps_termios.c_cflag |= CS8;
- gps_termios.c_cflag &= ~CRTSCTS;//no flow control
- tcsetattr(state->fd, TCSANOW, &gps_termios);
- tcflush(state->fd, TCIOFLUSH);
- tcsetattr(state->fd, TCSANOW, &gps_termios);
- tcflush(state->fd, TCIOFLUSH);
- tcflush(state->fd, TCIOFLUSH);
- if (cfsetispeed(&gps_termios,B9600))//\BE\DF\CC\E5\B5IJο\BCGPS\CEĵ\B5
- {
- LOGE("cfsetispeed.. errno..\r\n");
- close(state->fd);
- //return(-1);
- }
- // Set the output baud rates in the termios.
- if (cfsetospeed(&gps_termios,B9600))
- {
- LOGE("cfsetispeed.. errno..\r\n");
- close(state->fd);
- //return(-1);
- }
- tcsetattr(state->fd,TCSANOW,&gps_termios);
- LOGE("Port setup finished..\n");
- }
- if (state->fd < ) {
- LOGD("no gps emulation detected");
- return;
- }
- //**********************************************************************
- if ( socketpair( AF_LOCAL, SOCK_STREAM, , state->control ) < ) {
- LOGE("could not create thread control socket pair: %s", strerror(errno));
- goto Fail;
- }
- /* if ( pthread_create( &state->thread, NULL, gps_state_thread, state ) != 0 ) {
- LOGE("could not create gps thread: %s", strerror(errno));
- goto Fail;
- }*/
- //***********************************************************************
- LOGE("gps state initialized before");
- state->thread=state->callbacks.create_thread_cb("gps_state_thread",gps_state_thread,state);
- //**************************************************************************
- // D("gps state initialized");
- LOGE("gps state initialized");
- return;
- Fail:
- gps_state_done( state );
- }
- /*****************************************************************/
- /*****************************************************************/
- /***** *****/
- /***** I N T E R F A C E *****/
- /***** *****/
- /*****************************************************************/
- /*****************************************************************/
- static int
- qemu_gps_init(GpsCallbacks* callbacks)
- {
- GpsState* s = _gps_state;
- /**************************************************/
- s->callbacks = *callbacks; //ע\B2\E1\BBص\F7\BA\AF\CA\FD,JNI\B4\AB\CF\C2\C0\B4\B5Ļص\F7\BA\AF\CA\FD
- g_status.status=GPS_STATUS_ENGINE_ON;//\C9\E8\D6\C3״̬ ͨ\B5絫\BB\B9û\BF\AAʼ\B5\BC\BA\BD
- s->callbacks.status_cb(&g_status);
- /******************************************************/
- if (!s->init)
- gps_state_init(s);
- if (s->fd < )
- return -;
- // s->callbacks = *callbacks;
- return ;
- }
- static void
- qemu_gps_cleanup(void)
- {
- GpsState* s = _gps_state;
- if (s->init)
- gps_state_done(s);
- }
- static int
- qemu_gps_start()
- {
- GpsState* s = _gps_state;
- if (!s->init) {
- D("%s: called with uninitialized state !!", __FUNCTION__);
- return -;
- }
- D("%s: called", __FUNCTION__);
- gps_state_start(s);
- return ;
- }
- static int
- qemu_gps_stop()
- {
- GpsState* s = _gps_state;
- if (!s->init) {
- D("%s: called with uninitialized state !!", __FUNCTION__);
- return -;
- }
- D("%s: called", __FUNCTION__);
- gps_state_stop(s);
- return ;
- }
- static int
- qemu_gps_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty)
- {
- return ;
- }
- static int
- qemu_gps_inject_location(double latitude, double longitude, float accuracy)
- {
- return ;
- }
- static void
- qemu_gps_delete_aiding_data(GpsAidingData flags)
- {
- }
- static int qemu_gps_set_position_mode(GpsPositionMode mode, GpsPositionRecurrence recurrence,uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time)//(GpsPositionMode mode, int fix_frequency)
- {
- // FIXME - support fix_frequency
- return ;
- }
- static const void*
- qemu_gps_get_extension(const char* name)
- {
- // no extensions supported
- return NULL;
- }
- static const GpsInterface qemuGpsInterface = {
- sizeof(GpsInterface),
- qemu_gps_init,
- qemu_gps_start,
- qemu_gps_stop,
- qemu_gps_cleanup,
- qemu_gps_inject_time,
- qemu_gps_inject_location,
- qemu_gps_delete_aiding_data,
- qemu_gps_set_position_mode,
- qemu_gps_get_extension,
- };
- const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
- {
- return &qemuGpsInterface;
- }
- 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, , sizeof(*dev));
- dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = ;
- dev->common.module = (struct hw_module_t*)module;
- // dev->common.close = (int (*)(struct hw_device_t*))close_lights;
- dev->get_gps_interface = gps__get_gps_interface;
- *device = (struct hw_device_t*)dev;
- return ;
- }
- static struct hw_module_methods_t gps_module_methods = {
- .open = open_gps
- };
- const struct hw_module_t HAL_MODULE_INFO_SYM = {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = ,
- .version_minor = ,
- .id = GPS_HARDWARE_MODULE_ID,
- .name = "Goldfish GPS Module",
- .author = "The Android Open Source Project",
- .methods = &gps_module_methods,
- };
Yocto开发笔记之《驱动调试-GPS数据采集》(QQ交流群:519230208)的更多相关文章
- 运维开发笔记整理-URL配置
运维开发笔记整理-URL配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.URL路由 对于高质量的Web应用来说,使用简洁,优雅的URL的路由是一个非常值得重视的细节.Dja ...
- Yocto开发笔记之《快速入门,环境搭建 & 编译》(QQ交流群:519230208)
开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:,为避免广告骚扰,申请时请注明 “开发者” 字样 ======================================== ...
- Yocto开发笔记之《根文件系统裁剪》(QQ交流群:519230208)
开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...
- Yocto开发笔记之《嵌入式linux libcurl编程》(QQ交流群:519230208)
开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...
- Yocto开发笔记之《Makefile编写》(QQ交流群:519230208)
开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...
- Yocto开发笔记之《Tip-bitbake常用命令》(QQ交流群:519230208)
开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...
- [Openwrt 项目开发笔记]:MySQL配置(六)
[Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在本人的项目中,运行在路由器上的服务器采用Ngi ...
- 《linux就该这么学》课堂笔记12 网卡配置、防火墙配置
1.网卡配置(四种方法,选其一即可,配置后须重启网络服务使其生效) 1)修改配置文件./etc/sysconfig/network-scripts/ifcfg-网卡名称 2)nmtui [RHEL7] ...
- Yocto开发笔记之《网卡配置》(QQ交流群:519230208)
QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 ============================================== # ifconfig -a # ...
随机推荐
- TRUNK的作用功能.什么是TRUNK
TRUNK的作用功能.什么是TRUNK(转) [复制链接] 发表于 2011-11-24 11:01 | 来自 51CTO网页 在技术领域中把TRUNK翻译为中文是“主干.干线.中继线.长途线 ...
- SEO站点优化学习总结
1.网站收录查询 在搜索引擎里面输入Site:域名 即可. 尾巴——学习SEO可以看看以下几个网站: 卢松松博客[一个草根的博客]:http://lusongsong.com/ 站长之家[里面有站长统 ...
- hihocoder 1260
之前做过的oj, acm题目忘了很多了, 又要开始要刷题了, go on! #1260 : String Problem I 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描 ...
- STL中algorithm里的查找
首先,选择查找算法时,区间是否排序是一个至关重要的因素.可以按是否需要排序区间分为两组: A. count,find B. binary_search,lower_bound,upper_bound, ...
- HIbernate的基本包——八个,详细条目
antlr-2.7.6commons-collections-3.1dom4j-1.6.1hibernate3javassist-3.9.0.GAjta-1.1slf4j-api-1.5.8slf4j ...
- Bete冲刺第七阶段
Bete冲刺第七阶段 今日工作: web: 新增通知处理接口 ios: 重写登录逻辑,添加创建行程填写.注册 POP界面 目前所遇问题: web: web目前进展顺利,暂时还没有遇到编码的问题. iO ...
- LAMP安装各种问题解决方案
LAMP环境配置安装注意安装步骤及说明事项. LAMP安装各种问题解决 1. 访问ftp报错 解决: 关闭selinux vi /etc/selinux/config 内容修改为: selinux=d ...
- Linux(Ubuntu)下如何安装JDK
一.下载 首先,当然是要下载了. 按照需要选择不同的版本.笔者选择的是 jdk-7u45,如图: 二. 解压 将下载下来的 .tar.gz 文件解压. 使用如下命令解压: sudo tar zxvf ...
- Java的反射机制(Reflection)
反射机制 指可以在运动时加载.探知.使用编译期间完全未知的类 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够获取这个类的属性和方法:对于任意一个对象可以调用它的任意一个 ...
- Linux_cheat命令安装和使用
1.安装python yum -y install python 2.安装epel源.安装pip yum install epel-release -y yum install python ...