准确来说 libgps(man libgps)是一个与 GPS 守护进程进行通信的 C 库。包含打开、收发、解析数据包等接口,我们只需要使用libgps提供的接口就可拿到GPS数据。但是这个库的接口的使用,依赖 GPS 守护进程的运行。而这个守护进程才是真正基于上述协议与 GPS 接收器进行通信的。
1、选配上gpsd编译进文件系统(make menuconfig)
2、在开发板启动这个守护进程
/usr/sbin/gpsd -N -n -S 2947 /dev/ttyUSB0
3、如果说你要获取gps数据,目前我的gps模块被开发板识别为/dev/ttyUSB0,你可以直接通过cat 查看得到的gps数据,前提是需要关掉gpsd服务,同时gps天线能够在室外:
4、GPS数据分析(图片来自供应商提供的手册)
$GNGGA,052656.000,3107.52352,N,12121.56231,E,1,15,0.8,106.2,M,10.4,M,,0000*48
全球定位信息,接收机的时间、位置和定位相关数据。
$GNGLL,3107.52352,N,12121.56231,E,052656.000,A,A*41
地理定位信息,位置、时间和固定状态。
$GNGSA,A,3,10,18,23,24,25,31,32,193,,,,,1.4,0.8,1.2*12
当前卫星信息,用于表示用于定位的卫星的ID。当使用GPS卫星定位时,输出$GNGSA语句,系统ID为1。使用GLONASS卫星定位时,输出SGNGSA语句,系统ID为2。使用北斗卫星进行定位时,输出SGNGSA语句,系统ID为4。
$BDGSV,5,3,17,201,46,141,,214,42,322,34,224,40,204,29,204,34,123,*64
卫星仰角、方位角和CNR信息,SGPGSV用于GPS卫星,SGLGSV用于GLONASS卫星,SGAGSV用于GALILEO卫星,$GBGSV用于北斗卫星
$GNRMC,052656.000,A,3107.52352,N,12121.56231,E,000.0,065.6,081121,,,A*78
推荐定位信息,时间,日期,位置,航向,和速度
$GNVTG,065.6,T,,M,000.0,N,000.0,K,A*16
地面速度信息,相对于地面的航向和速度
$GNZDA,052656.000,08,11,2021,00,00*43
UTC时间,年月日和时区
代码如下:因为本人需要将gps数据转换为JSON格式数据上传给前端工程师,从而在web端显示设备位置,所以得到数据后进行了处理
#include
#include "mgps.h"
#include "gps.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MESH_GPSD_LOCALTION_JSON "/www/meshgps.json"
#define LOCATION_SERVICE_EXIT "/bin/rm -rf /var/run/meshgps.pid"
#define GPSD_DATE_LOCALTION_JSON "/www/meshgps.json"
#define GPSD_SERVICE_RESTART "/etc/init.d/gpsd restart"
FILE *fp;
char coor_buf[128] = {0};
char type_buf[32] = {0};
pthread_mutex_t gps_mutex = PTHREAD_MUTEX_INITIALIZER;
int mesh_query_console_baudrate(const char *device)
{
int fd = 0;
speed_t baudrate = B115200;
struct termios tio;
if ((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
{
printf("%s open serial console failed\n", __func__);
return -1;
}
if (tcgetattr(fd, &tio) != 0)
{
printf("%s get console attr error\n", __func__);
close(fd);
return -1;
}
syslog(LOG_INFO, "console input buadrate %d output buadrate %d\n",cfgetispeed(&tio), cfgetospeed(&tio));
if (cfgetispeed(&tio) == cfgetospeed(&tio) && baudrate == cfgetispeed(&tio))
{
printf("%s correct console baudrates\n", __func__);
close(fd);
}
else
{
printf("%s console buadrate input %d output %d src %d is unavailable\n",
__func__, cfgetispeed(&tio), cfgetospeed(&tio), baudrate);
cfsetispeed(&tio, baudrate);
cfsetospeed(&tio, baudrate);
int ret = tcsetattr(fd, TCSANOW, &tio);
printf("%s after set console buadrate input %d output %d ret %d\n",
__func__, cfgetispeed(&tio), cfgetospeed(&tio), ret);
close(fd);
}
system(GPSD_SERVICE_RESTART);
return 0;
}
void *parse_location(struct gps_data_t *gps_data)
{
int i = 0;
while(1)
{
pthread_mutex_lock(&gps_mutex);
memset(coor_buf, 0, sizeof(coor_buf));
memset(type_buf, 0, sizeof(type_buf));
/*if over 6 minutes no gps data,then exit and report*/
if (i > 120)
{
printf( "receive GPS data timeout\n");
goto ERR_RET;
}
/* non block wait for 2 seconds to receive data */
if (gps_waiting(gps_data, 2 * 1000 * 1000))
{
/* read data */
if ((gps_read(gps_data, NULL, 0)) == -1)
{
printf("error occured reading gps data\n");
goto ERR_RET;
}
/* Display data from the GPS receiver. */
if ((gps_data->status == STATUS_NO_FIX))
{
printf("gps status %d mode %d latitude %f longitude %f\n", gps_data->status, gps_data->fix.mode, gps_data->fix.latitude, gps_data->fix.longitude);
}
if ((gps_data->status != STATUS_NO_FIX) && (gps_data->fix.mode == MODE_2D ||
gps_data->fix.mode == MODE_3D) &&
!isnan(gps_data->fix.latitude) && !isnan(gps_data->fix.longitude))
{
printf("latitude: %f, longitude: %f, timestamp:%ld\n",
gps_data->fix.latitude, gps_data->fix.longitude, gps_data->fix.time.tv_sec);
strcat(coor_buf, "{\"time\":\"");
sprintf(type_buf, "%ld", gps_data->fix.time.tv_sec);
strcat(coor_buf, type_buf);
strcat(coor_buf, "\",\"latitude\":\"");
sprintf(type_buf, "%lf", gps_data->fix.latitude);
strcat(coor_buf, type_buf);
strcat(coor_buf, "\"}");
if (strlen(coor_buf) != 0)
{
printf("coor_buf = %s\n",coor_buf);
fp = fopen(GPSD_DATE_LOCALTION_JSON, "w+");
fputs(coor_buf, fp);
fclose(fp);
}
goto ERR_RET;
}
else
{
i++;
}
pthread_mutex_unlock(&gps_mutex);
sleep(3);
}
}
ERR_RET:
pthread_mutex_unlock(&gps_mutex);
gps_stream(gps_data, WATCH_DISABLE, NULL);
gps_close(gps_data);
system(LOCATION_SERVICE_EXIT);
return NULL;
}
int main()
{
struct gps_data_t gps_data;
pthread_t thread;
if (mesh_query_console_baudrate("/dev/ttyUSB0"))
{
printf("gpsd error\n");
goto ERR_EXIT;
}
if ((gps_open("localhost", "2947", &gps_data)) == -1)
{
printf("gps open device fail\n");
goto ERR_EXIT;
}
if (-1 == gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL))
{
printf("%s gps stream error\n", __func__);
gps_close(&gps_data);
goto ERR_EXIT;
}
pthread_create(&thread, NULL, (void *)parse_location,(struct gps_data_t *)&gps_data);
pthread_join(thread, NULL);
return 0;
ERR_EXIT:
system(LOCATION_SERVICE_EXIT);
return -1;