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;
阅读(6183) | 评论(0) | 转发(3) |