Android系统GPS HAL层移植笔记

转载地址:http://blog.chinaunix.net/uid-14198351-id-3371590.html


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;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值