Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1495776
  • 博文数量: 267
  • 博客积分: 3010
  • 博客等级: 少校
  • 技术积分: 3089
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-05 17:09
个人简介

尊天命,尽人事

文章分类

全部博文(267)

文章存档

2017年(6)

2015年(4)

2014年(27)

2013年(52)

2012年(59)

2011年(120)

分类: 嵌入式

2013-05-05 15:12:47

Android系统源码都有虚拟机GPS HAL层文件gps_qemu.c,移植GPS HAL层修改该文件就可以了。
下面将从上到下说明主要修改的地方。

修改LOG TAG
#define  LOG_TAG  "gps_qemu" -> #define  LOG_TAG  "gps_S5PV210"

修正static int nmea_tokenizer_init函数bug,避免空白token无法解析。
while (p < end) {
        const char*  q = p;

        q = memchr(p, ',', end-p);
        if (q == NULL)
            q = end;

        if (q > p) {       -> if (q >= p) {
            if (count < MAX_NMEA_TOKENS) {
                t->tokens[count].p   = p;
                t->tokens[count].end = q;
                count += 1;
            }
        }

添加卫星状态
typedef struct {
    int     pos;
    int     overflow;
    int     utc_year;
    int     utc_mon;
    int     utc_day;
    int     utc_diff;
   
    int         sv_status_changed;
    gps_sv_status_callback sv_status_cb; //回调函数

       
    GpsLocation  fix;
    gps_location_callback  callback;
    char    in[ NMEA_MAX_SIZE+1 ];
} NmeaReader;

修正static void nmea_reader_update_utc_diff( NmeaReader*  r )函数bug,解决本地时间计算错误问题。
r->utc_diff = time_utc - time_local; -> r->utc_diff = time_local - time_utc;

在static void nmea_reader_parse( NmeaReader*  r )函数添加GSV和GSA数据解析代码
if ( !memcmp(tok.p, "GSV", 3) ) {

        D("may%s,%d,%s,gsV\n",__FILE__,__LINE__,__FUNCTION__);
            Token tok_noSatellites = nmea_tokenizer_get(tzer, 3);
            int noSatellites = str2int(tok_noSatellites.p, tok_noSatellites.end);
               D("%d,inview=%d,\n",__LINE__,noSatellites);     
            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);
           D("%d,gsv_index=%d,gsv_total=%d\n",__LINE__,sentence,totalSentences);  
             int curr;
             int i;
                     
             if (sentence == 1) {
        D("msg_index=%d\n",sentence);
           //  r->sv_status_changed = 0;
             r->sv_status.num_svs = 0;
            r->sv_status.ephemeris_mask=0ul;
            r->sv_status.almanac_mask=0ul;
             }
             
                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.ephemeris_mask|=(1ul << (r->sv_status.sv_list[curr].prn-1));
            r->sv_status.almanac_mask|=(1ul << (r->sv_status.sv_list[curr].prn-1));          
            r->sv_status.num_svs += 1;
         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 += 1;
             
                 i += 1;
             }
             
             if (sentence == totalSentences) {
        D("msg=%d,msgindex=%d",totalSentences,sentence);
        #ifdef Svpnd_Version
        r->sv_status_cb=_gps_state->callbacks.sv_status_cb;
         
             if (r->sv_status_changed !=0) {
                   if (r->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->sv_status_cb( &(r->sv_status) );
                       r->sv_status_changed = 0;
                     }else {
                        D("no callback, keeping status data until needed !");
                   }
         
                }
     #endif
             }
             
             D("%s: GSV message with total satellites %d", __FUNCTION__, noSatellites); 
             
            }          
             
           
    #endif
             
            }
    #ifdef Svpnd_Version
    else if ( !memcmp(tok.p, "GSA", 3) ) {
   
                /* do something ? */
                {
        D("may%s,%d,%s,gsa\n",__FILE__,__LINE__,__FUNCTION__);
                Token tok_fixStatus = nmea_tokenizer_get(tzer, 2);
                int i;
         
                if (tok_fixStatus.p[0] != '\0' && tok_fixStatus.p[0] != '1') {
         
                    Token tok_accuracy = nmea_tokenizer_get(tzer, 15);//position dilution of precision dop
         
                    nmea_reader_update_accuracy(r, tok_accuracy);
         
                    r->sv_status.used_in_fix_mask = 0ul;
            D("\n");
                    for (i = 3; i <= 14; ++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 > 0){
                            r->sv_status.used_in_fix_mask |= (1ul << ( prn-1));
                            r->sv_status_changed = 1;
                           
                       }
         
                   }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);
         
            }
   
                /* do something ? */        
   
    }


修改static void gps_state_init函数
state->fd = qemud_channel_open(QEMU_CHANNEL_NAME); -> state->fd = gps_hardware_init();
gps_hardware_init()初始化硬件,下面是一个可用的实例
static int gps_hardware_init()
{
    struct termios newtio; 
    int fd;
    int baud=B9600;
    char detect_buf[128];
    char c=0;
    unsigned int try_time=127;
    int baud_wrong=3;
    unsigned int i=0;
    int timeout = 5;
    fd = open("/dev/s3c2410_serial3", O_RDONLY);  

reset:
    if(!(timeout--))
        return fd;
    bzero(&newtio, sizeof(newtio)); 
    newtio.c_lflag &= ~(ECHO | ICANON); 
    newtio.c_cflag = baud | CS8 | CLOCAL | CREAD; 
    newtio.c_iflag = IGNPAR; 
    newtio.c_oflag = 0; 
    newtio.c_oflag &= ~(OPOST); 
    newtio.c_cc[VTIME]    = 5;   /* inter-character timer unused */ 
    newtio.c_cc[VMIN]     = 0;   /* blocking read until 9 chars received */ 
    tcflush(fd, TCIFLUSH); 
    tcsetattr(fd,TCSANOW,&newtio); 
   
    /*buadrate detect*/
#if 1
    LOGE("Here1\n");
    if(baud_wrong)
    {
        memset(detect_buf,0,sizeof(detect_buf));
        try_time=127;
          while (try_time--)
          {
            i=i & 0x7f;
            read(fd,&c,1); /* com port */
            detect_buf[i++] = c;
            if(c == '\n')
            {
                if((memcmp(detect_buf,"$GPGSA,",7)==0) || (memcmp(detect_buf,"$GPGGA,",7)==0) || (memcmp(detect_buf,"$GPRMC,",7)==0) || (memcmp(detect_buf,"$GPGSV,",7)==0))
                {   
                    baud_wrong-=1;
                    if(baud_wrong)
                    {
                        memset(detect_buf,0,sizeof(detect_buf));
                        try_time=127;
                        continue;
                    }
                    break;
                }   
                i=0;
            }
          }
          LOGE("Here2\n");
        if(baud_wrong)
        {
            if(baud == B9600)
                baud = B4800;
            else
                baud = B9600;
            baud_wrong=3;
            sleep(3);
            goto reset;
        }
        LOGE("Here3\n");
    }
    LOGE("Here4\n");
#endif   

    return fd;
}


创建进程
if ( pthread_create( &state->thread, NULL, gps_state_thread, state ) != 0 ) {
        LOGE("could not create gps thread: %s", strerror(errno));
        goto Fail;
    }
->
state->thread = callbacks->create_thread_cb( "gps_state_thread", gps_state_thread, state );

    if ( !state->thread ) {
        E("could not create gps thread: %s", strerror(errno));
        goto Fail;
    }

    state->callbacks = *callbacks;


阅读(3569) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~