gpsdデーモンとのインターフェースにlibgpsを使用したかったのです。そのため、特定の衛星から値を抽出するために、小さなテスト アプリケーションを実装しました。
HOWTOページのドキュメントは、それを教えてくれます
注意が必要な部分は、ブロッキング読み取りから取得したものを解釈することです。注意が必要な理由は、すべての読み取りがデーモンから完全な JSON オブジェクトを 1 つだけ取得することが保証されていないためです。1 つの応答オブジェクト、複数、またはその一部、または 1 つ以上の後にフラグメントが続く場合があります。
ドキュメントで推奨されているように、他のPACKET_SET
処理を行う前にマスク ビットがチェックされます。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <gps.h>
#include <pthread.h>
pthread_t t_thread;
struct t_args {
unsigned int ID;
};
unsigned int status = 0;
int elevation;
int p_nmea(void *targs);
void start_test(void)
{
struct t_args *args = malloc(sizeof *args);
status = 1;
args->ID = 10;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if (pthread_create(&t_thread, &attr, (void *)&p_nmea, args) != 0)
{
perror("create: \n");
}
}
int test_result(int * Svalue)
{
int res;
if(status == 1)
{
void * t_res;
if(pthread_tryjoin_np(t_thread, &t_res) != 0)
{
status = 1;
}
else
{
if((int)t_res == 1)
{
res = 3;
*Svalue = elevation;
elevation = 0;
}
else
{
res = 4;
}
}
}
return res;
}
int p_nmea(void *targs)
{
struct t_args *thread_args = targs;
struct gps_data_t gpsdata;
int ret = -1;
int count = 10;
int i,j;
if(gps_open((char *)"localhost", (char *)DEFAULT_GPSD_PORT, &gpsdata) != 0)
{
(void)fprintf(stderr, "cgps: no gpsd running or network error: %d, %s\n", errno, gps_errstr(errno));
return (-1);
}
else
{
(void)gps_stream(&gpsdata, WATCH_ENABLE, NULL);
do
{
if(!gps_waiting(&gpsdata, 1000000))
{
(void)gps_close(&gpsdata);
}
else
{
if(gps_read(&gpsdata) == -1)
{
return (-1);
}
else
{
if(gpsdata.set & PACKET_SET)
{
for (i = 0; i < MAXCHANNELS; i++)
{
for (j = 0; j < gpsdata->satellites_visible; j++)
{
if(gpsdata->PRN[i] == thread_args.ID)
{
elevation = (int)gpsdata->elevation[i];
ret = 1;
break;
}
}
if(gpsdata->PRN[i] == thread_args.ID)
{
break;
}
}
}
}
}
--count;
}while(count != 0);
}
(void)gps_stream(&gpsdata, WATCH_DISABLE, NULL);
(void)gps_close(&gpsdata);
(void)free(thread_args);
(void)pthread_exit((void*) ret);
}
ドキュメンテーションでも推奨されているように、コード例として cgps と gpxlogger を調べましたが、libgps の微妙な点はわかりません。gps_waiting()
少なくとも 1 つの応答オブジェクト全体を取得するために、前に while ループが追加されました。pthread を導入する前に、応答を返すまでに数秒かかるtest_result()
直後に関数を呼び出すことに注意しました。スレッドを使用すると、すぐに返されるstart_test()
と思っていましたが、そうではありません。私はまだ数秒を失っています。さらに、マニュアルページにあるので、私は自発的に使用します3
3
4
pthread_tryjoin_np()
pthread_tryjoin_np() 関数は、スレッドとの非ブロック結合を実行します
誰か助けてくれませんか、何か間違っていると思いますが、まだどの部分については言えませんか? 基本的に、最初の値を返す前に do while ループを少なくとも 4 回実行するのはなぜですか?
編集1:
ドキュメント HOWTO をもう一度読んだ後、次の行を強調表示します。
データ待機チェックと両方の読み取りブロックがあるという事実は、アプリケーションが GPS 以外の入力ソースを処理する必要がある場合、おそらく gps_data 構造体のミューテックス ロックを使用してスレッドで読み取りループを分離する必要があることを意味します。 .
私は少し混乱しています。それは本当にどういう意味ですか?