ublox GPS模块不带惯导功能在开机启动有时搜不到星的解决办法

 ̄綄美尐妖づ 提交于 2019-12-10 17:24:19

背景:

公司开发的产品因为硬件不给力导致有些机器在刚开机(重新冷启动)之后,明显在空旷的地方都提示很长时间搜不到星的问题。

由于产品开发周期的问题,只能使用其它补救方案,目前由ublox模组厂家提供解决方案,开机阶段定位搜星不到时增加AGPS定位功能。

方法如下:

在GPS的Hardware层添加以下代码:

增加AGPS功能:
t7\android\hardware\aw\gps\gps.c

//static GpsState _gps_state[1];
//static GpsState *gps_state = _gps_state;
//static int sleep_lock = 1;	//Changed by Tommy 0;
//static int lastcmd = 0;
//static int bGetFormalNMEA = 1;
//static int started = 0;
//static int continue_thread = 1;
//static int bOrionShutdown = 0;
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define CAS_AGPS_SERVER "www.gnss-aide.com" //杭州中科微电子的GPS服务器,使用中科微的模块
#define CAS_AGPS_PORT_NO 2621   //端口
#define USER_NAME "freetrial"   //用户名
#define PASS_WORD "123456"      //密码
#define LOCATION_LAT "persist.sys.lat"  //位置经纬度信息
#define LOCATION_LON "persist.sys.lon"
#define LAT_DEF "22.595395"
#define LON_DEF "114.005019" //默认是小数点后6位


#define STEP_0_UNKNOWN 0
#define STEP_1_GETHOST 1
#define STEP_2_CONNECT 2
#define STEP_3_SENDNET 3
#define STEP_4_CANREAD 4
static uint8_t agps_step = STEP_1_GETHOST; //自定义状态

int sockfd = -1;
struct sockaddr_in serv_addr;

#define AGPS_READ_MAX 1024
#define AGPS_BUF_MAX 5120
static pthread_t agps_thread_id;

void disconnectAGPS(void)
{
	DFR("agps_step=%d", agps_step);
	if(sockfd > 0)close(sockfd);
	sockfd = -1;
	agps_step = STEP_0_UNKNOWN;
	//pthread_exit(agps_thread_id);
}

void connectAGPS(int uartFd)
{
	DFR("agps_step=%d", agps_step);
	switch(agps_step){
		case STEP_1_GETHOST:
			if(agps_step == STEP_1_GETHOST){ //获取主机名称和端口号
				struct hostent *server = gethostbyname(CAS_AGPS_SERVER);
				if(server != NULL){
					DFR("Copy agps server information to socket address struct");
					memset((char *) &serv_addr, 0, sizeof(serv_addr));
					serv_addr.sin_family = AF_INET;
					memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr, server->h_length);
					serv_addr.sin_port = htons(CAS_AGPS_PORT_NO);
					agps_step = STEP_2_CONNECT;
				} else {
					DFR("ERROR, no such host.");
					agps_step = STEP_1_GETHOST;
				}
			}
		break;

		case STEP_2_CONNECT: //第二步,创建套接字接口
			if(sockfd < 0){
				sockfd = socket(AF_INET, SOCK_STREAM, 0);
				if(sockfd < 0){
					DFR("ERROR, opening socket. %s", strerror(errno));
				}
			}else{
				if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
					DFR("ERROR, cannot connect to server. %s", strerror(errno));
				} else {
					agps_step = STEP_3_SENDNET;
					DFR("connect to server.");
				}
			}
		break;

		case STEP_3_SENDNET:  //从套接字接口获取AGPS定位信息
			if(agps_step == STEP_3_SENDNET){
				char *pStr;
				int writeNum = 0;
				char message[128];
				char lat_buf[92]={0};
				char lon_buf[92]={0};
                //正常时高德地图发来的数据LOCATION_LAT有时有小数点后9位的情况,需要将小数点后强制截取成6位,否则会引起异常
				property_get(LOCATION_LAT, lat_buf, LAT_DEF);
				writeNum = strlen(lat_buf);
				if(writeNum > 9){
					memset(lat_buf+9, 0, writeNum-9);
					DFR("lat_buf=%s, writeNum=%d", lat_buf, writeNum);
				}
				pStr = strchr(lat_buf, '.'); //有时AGPS信息并不是小数点后4位,强制截取小数点后4位
				if(pStr == NULL){
					memset(lat_buf, 0, writeNum);
					memcpy(lat_buf, LAT_DEF, sizeof(LAT_DEF));
				}
				
                 //正常时高德地图发来的数据LOCATION_LON有时有小数点后9位的情况,需要将小数点后强制截取成6位,否则会引起异常
				property_get(LOCATION_LON, lon_buf, LON_DEF);
				writeNum = strlen(lon_buf);
				if(writeNum > 10){
					memset(lon_buf+10, 0, writeNum-10);
					DFR("lon_buf=%s, writeNum=%d", lon_buf, writeNum);
				}
				pStr = strchr(lon_buf, '.'); //有时AGPS信息并不是小数点后4位,强制截取小数点后4位
				if(pStr == NULL){
					memset(lon_buf, 0, writeNum);
					memcpy(lon_buf, LON_DEF, sizeof(LON_DEF));
				}
                
                //经纬度信息组合成一个字符串
				sprintf(message, "user=%s;pwd=%s;lat=%s;lon=%s;", USER_NAME, PASS_WORD, lat_buf, lon_buf);
				DFR("Build agps Message: %s", message);
                
                //写入套接字接口
				writeNum = write(sockfd, message, strlen(message));
				if(writeNum > 0){
					agps_step = STEP_4_CANREAD;
					return;
				}
				DFR("ERROR, writing to socket.");
			}
		break;

		case STEP_4_CANREAD: //再次从套接字接口获取定位信息
			if(agps_step == STEP_4_CANREAD){
				char read_buffer[AGPS_READ_MAX]={0};
				int agps_buffer_length = 0;
				int readNum, counter;
				char agps_buffer[AGPS_BUF_MAX]={0};
				char *pCur = agps_buffer;
				for(counter=0; counter<5; counter++){
					memset(read_buffer, 0, AGPS_READ_MAX);
                    //从服务器的套接字接口获取
					readNum = read(sockfd, read_buffer, AGPS_READ_MAX);
					if(readNum < 0){
						DFR("ERROR, reading from socket.");
						break;
					}else if(readNum == 0 ){
						DFR("All agps data are received. Total bytes: %d", agps_buffer_length);
						break;
					} else {
						if(agps_buffer_length + readNum > AGPS_BUF_MAX){
							DFR("agps_buffer=%d is too small, agps_buffer_length=%d, readNum=%d", AGPS_BUF_MAX, agps_buffer_length, readNum);
							readNum = AGPS_BUF_MAX - agps_buffer_length;
						}
						memcpy(pCur, read_buffer, readNum);
						pCur += readNum;
						agps_buffer_length += readNum;
						DFR("Received %d bytes from agps server.", readNum);
					}
				}
				
				if(agps_buffer_length != 0 && uartFd > 0){
                    //最后写入GPS模组中
					readNum = write(uartFd, agps_buffer, agps_buffer_length);
					DFR("Now, can send these data to gnss module through tty. %d", readNum);
					disconnectAGPS();
				}
			}
		break;
	}
}

static void gps_agps_thread(void *arg) //启动一个线程
{
	GpsState *state = (GpsState *)arg;
	while(continue_thread){
		if(started == 1){
			if(agps_step == STEP_0_UNKNOWN)break;
			connectAGPS(state->fd);
		}
		sleep(1);
	}
	DFR("agps thread exit, agps_step=%d", agps_step);
}

....................................
static void gps_state_thread(void *arg)
{
	GpsState *state = (GpsState*)arg;
	int gps_fd = state->fd;
	int control_fd = state->control[1];
	epoll_ctrlfd = epoll_create(1);
	epoll_nmeafd = epoll_create(1);
	epoll_register(epoll_ctrlfd, control_fd);

	DFR("gps thread running, continue_thread=%d", continue_thread);

	state->tmr_thread = state->callbacks.create_thread_cb("athr_gps_tmr", gps_timer_thread, state);
	if(!state->tmr_thread){
		DFR("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_thr", gps_nmea_thread, state);
	if(!state->nmea_thread){
		DFR("could not create gps nmea thread: %s", strerror(errno));
		started = 0;
		state->init = STATE_INIT;
		goto Exit;
	}

	started = 0;
	state->init = STATE_INIT;
    
    //启动AGPS线程
	agps_thread_id = state->callbacks.create_thread_cb("athr_agps_thr", gps_agps_thread, state);
	if(!agps_thread_id){
		DFR("create agps thread error");
	}
    //////////////////
	for(;;){


 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!