• R/O
  • HTTP
  • SSH
  • HTTPS

scilog: Commit

Overoで動作するデータ収録プログラム
サブCPUからGPS時刻付きADデータを取得してSDに記録する。


Commit MetaInfo

Revisão1502df658e0de66863f3c51d862ce91239f4c0a5 (tree)
Hora2011-12-09 17:20:22
AutorNaoya Takamura <ntaka206@user...>
CommiterNaoya Takamura

Mensagem de Log

1sec and high smpling file record add.

Mudança Sumário

Diff

--- a/Makefile
+++ b/Makefile
@@ -30,9 +30,9 @@ INCDIR = ${STAGEDIR}/include
3030
3131 TARGET = scilog
3232
33-OBJS = scilog.o spi.o thread_rcv.o
33+OBJS = scilog.o spi.o thread_rcv.o ring.o ad_ring.o thread_rec.o sts.o ad_file.o conf.o
3434
35-HDRS = mes_print.h debug_print.h spi.h my_thread.h
35+HDRS = mes_print.h debug_print.h spi.h my_thread.h ring.h ad_ring.h thread_rec.h sts.h ad_file.h conf.h
3636
3737 ${TARGET} : $(OBJS) $(HDRS)
3838 ${CC} ${CFLAGS} ${OBJS} -L ${LIBDIR} -o ${TARGET}
--- /dev/null
+++ b/ad_file.c
@@ -0,0 +1,260 @@
1+/*
2+ 1secファイル
3+ 高速サンプルファイル
4+
5+#define DEBUG_FILE_MIN
6+ 定義するとファイルが1日単位ではなく指定された分単位になる
7+ ただし、ファイルのサイズは1日と同じサイズのまま
8+#deifne DEBUG_FILE_MIN_PERIOD
9+ ファイルの単位
10+ 単位 分
11+
12+*/
13+#include <stdio.h>
14+#include <string.h>
15+#include <sys/types.h>
16+#include <sys/stat.h>
17+#include <stdlib.h>
18+#include <syslog.h>
19+#include <errno.h>
20+#include <unistd.h>
21+
22+#include "ad_ring.h"
23+#include "ad_file.h"
24+#include "debug_print.h"
25+#include "conf.h"
26+
27+// mkdir_p()で使用する
28+#define MKDIR_MODE "755"
29+
30+/**** util
31+*/
32+/*
33+ 指定さえれたディレクトリを作成
34+ 親がないときは親まで作る
35+ char *mode
36+ 755とか
37+ return
38+ 0=OK
39+ -1=ERROR
40+*/
41+static int mkdir_p(const char *path, char *mode)
42+{
43+ struct stat st;
44+ char cmd[128];
45+
46+ // コピー先ディレクトリ存在しなければ作成する
47+ if (stat(path, &st) == -1) {
48+ PDEBUG("mkdir_p(): make dir %s\n", path);
49+
50+ sprintf(cmd, "mkdir -p -m %s %s > /dev/null 2> /dev/null &", mode, path);
51+ switch(system(cmd)) {
52+ case 127:
53+ // shell exec error
54+ PDEBUG("mkdir_p(): shell exec error\n");
55+ syslog(LOG_ERR, "mkdir_p(): system() shell exec error");
56+ return -1;
57+ case -1:
58+ // error
59+ PDEBUG("mkdir_p(): error\n");
60+ syslog(LOG_ERR, "mkdir_p(): system() error");
61+ return -1;
62+ default:
63+ // 作成されるまで待つ
64+ sleep(3);
65+ return 0;
66+ }
67+ }
68+ return 0;
69+}
70+
71+
72+/**** 1秒ファイル関係 ************************************************************
73+*/
74+/*
75+ 1秒データファイル オープン
76+
77+ Return:
78+ 1 = Error
79+ 0 = OK
80+ */
81+int sec_file_open(FILE **fp, AdData *D)
82+{
83+ char szDir[64];
84+ struct stat st;
85+ char fname[64];
86+ char path[128];
87+
88+ // サブディレクトリ作成
89+ sprintf(szDir, "%s/%s/%04d/%02d", DIR_DATA, sid_getp(), D->t.tm_year+1900, D->t.tm_mon+1);
90+ // ディレクトリ存在しなければ作成する
91+ if (stat(szDir, &st) == -1) mkdir_p(szDir, MKDIR_MODE);
92+
93+ // ファイル名作成
94+#ifdef DEBUG_FILE_MIN
95+ sprintf(fname, "%04d%02d%02d_%02d%02d.sec",
96+ D->t.tm_year+1900, D->t.tm_mon+1, D->t.tm_mday, D->t.tm_hour, D->t.tm_min / DEBUG_FILE_MIN_PERIOD * DEBUG_FILE_MIN_PERIOD);
97+#else
98+ sprintf(fname, "%04d%02d%02d.sec", D->t.tm_year+1900, D->t.tm_mon+1, D->t.tm_mday);
99+#endif
100+ // フルパス作成
101+ strcpy(path, szDir);
102+ strcat(path, "/");
103+ strcat(path, fname);
104+ PDEBUGF("path=%s\n", path);
105+
106+ *fp = fopen(path, "a");
107+ if (*fp == NULL) {
108+ syslog(LOG_ERR, "%s(): fopen() ERROR. %s", __FUNCTION__, strerror(errno));
109+ return 1;
110+ }
111+ return 0;
112+}
113+/*
114+ Return:
115+ 1 = Error
116+ 0 = OK
117+ */
118+int sec_file_out(FILE *fp, char *out, int len)
119+{
120+ int ret;
121+
122+ if (fp == NULL) return 1;
123+ if ((ret = fwrite(out, 1, len, fp)) < len) {
124+ syslog(LOG_ERR, "%s(): fwrite() return %d < %d. %s", __FUNCTION__, ret, len, strerror(errno));
125+ return 1;
126+ }
127+ return 0;
128+}
129+/*
130+ 1秒データファイル クローズ
131+
132+ Return:
133+ 1 = Error
134+ 0 = OK
135+ */
136+int sec_file_close(FILE *fp)
137+{
138+ if (fp == NULL) return 1;
139+ fclose(fp);
140+ return 0;
141+}
142+
143+/*
144+ 1secファイル記録用データ作る
145+*/
146+int sec_make_rec_data(AdData *ad, char *buf)
147+{
148+ char buf2[32];
149+ int ch;
150+
151+ sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d,%3lu,%02X",
152+ ad->gps.year, ad->gps.month, ad->gps.day, ad->gps.hour, ad->gps.min, ad->gps.sec,
153+ ad->gps.tacc, ad->gps.valid);
154+ for(ch = 0; ch < AD_CHNUM; ch++) {
155+ sprintf(buf2, ",%+7ld", ad->data1sec[ch]);
156+ strcat(buf, buf2);
157+ }
158+ strcat(buf, "\n");
159+ return 0;
160+}
161+/**** 高速サンプルファイル関係 ************************************************************
162+*/
163+/*
164+ Return:
165+ 1 = Error
166+ 0 = OK
167+ */
168+int high_file_open(FILE **fp, AdData *D)
169+{
170+ char szDir[64];
171+ struct stat st;
172+ char fname[64];
173+ char path[128];
174+
175+ // サブディレクトリ作成
176+ sprintf(szDir, "%s/%s/%04d/%02d", DIR_DATA, sid_getp(), D->t.tm_year+1900, D->t.tm_mon+1);
177+ // ディレクトリ存在しなければ作成する
178+ if (stat(szDir, &st) == -1) mkdir_p(szDir, MKDIR_MODE);
179+
180+ // ファイル名作成
181+#ifdef DEBUG_FILE_MIN
182+ sprintf(fname, "%04d%02d%02d_%02d%02d.sec",
183+ D->t.tm_year+1900, D->t.tm_mon+1, D->t.tm_mday, D->t.tm_hour, D->t.tm_min / DEBUG_FILE_MIN_PERIOD * DEBUG_FILE_MIN_PERIOD);
184+#else
185+ sprintf(fname, "%04d%02d%02d%02d.high", D->t.tm_year+1900, D->t.tm_mon+1, D->t.tm_mday, D->t.tm_hour);
186+#endif
187+ // フルパス作成
188+ strcpy(path, szDir);
189+ strcat(path, "/");
190+ strcat(path, fname);
191+ PDEBUGF("path=%s\n", path);
192+
193+ *fp = fopen(path, "a");
194+ if (*fp == NULL) {
195+ syslog(LOG_ERR, "%s(): fopen() ERROR. %s", __FUNCTION__, strerror(errno));
196+ return 1;
197+ }
198+ return 0;
199+}
200+/*
201+ Return:
202+ 1 = Error
203+ 0 = OK
204+ */
205+int high_file_out(FILE *fp, char *out, int len)
206+{
207+ int ret;
208+
209+ if (fp == NULL) return 1;
210+ if ((ret = fwrite(out, 1, len, fp)) < len) {
211+ syslog(LOG_ERR, "%s(): fwrite() return %d < %d. %s", __FUNCTION__, ret, len, strerror(errno));
212+ return 1;
213+ }
214+ return 0;
215+}
216+/*
217+ Return:
218+ 1 = Error
219+ 0 = OK
220+ */
221+int high_file_close(FILE *fp)
222+{
223+ if (fp == NULL) return 1;
224+ fclose(fp);
225+ return 0;
226+}
227+
228+/*
229+ 記録用データ作る
230+*/
231+int high_make_rec_data(AdData *ad, char *ptr)
232+{
233+ unsigned char *src;
234+ int ch, i, j;
235+
236+ *ptr++ = ad->gps.year & 0xFF;
237+ *ptr++ = (ad->gps.year >> 8) & 0xFF;
238+ *ptr++ = ad->gps.month;
239+ *ptr++ = ad->gps.day;
240+ *ptr++ = ad->gps.hour;
241+ *ptr++ = ad->gps.min;
242+ *ptr++ = ad->gps.sec;
243+ *ptr++ = ad->gps.nano;
244+ *ptr++ = ad->gps.valid;
245+ //
246+ src = ad->data;
247+ for(ch = 0; ch < AD_CHNUM; ch++) {
248+ for(i = 0; i < AD_SAMPLE; i++) {
249+ for(j = 0; j < AD_BYTES; j++) {
250+ *ptr++ = *src++;
251+ }
252+ src++;
253+ }
254+ }
255+ return 0;
256+}
257+
258+
259+
260+
--- /dev/null
+++ b/ad_file.h
@@ -0,0 +1,53 @@
1+#if !defined(__AD_FILE_H__)
2+#define __AD_FILE_H__
3+
4+#include "ad_ring.h"
5+
6+// データ記録用dir 末尾に/付けない
7+#ifdef DUMMY
8+ #define DIR_DATA "/home/ntaka/dev/arm2011n/data"
9+#else
10+ #define DIR_DATA "/home/data"
11+#endif
12+
13+#if 0
14+// NAV-TIMEUTCパケットのファイル記録用データタイプ
15+typedef struct {
16+ unsigned long tow; // ms GPS Millisecond Time of Week
17+ unsigned long tacc; // ns Time Accuracy Estimate
18+ long nano; // ns Nanoseconds of second, range -1e9 .. 1e9 (UTC)
19+ unsigned int year __attribute__((aligned(1))); // 12 UTC
20+ unsigned char month __attribute__((aligned(1))); // 16
21+ unsigned char day __attribute__((aligned(1)));
22+ unsigned char hour __attribute__((aligned(1)));
23+ unsigned char min __attribute__((aligned(1)));
24+ unsigned char sec __attribute__((aligned(1)));
25+ unsigned char valid __attribute__((aligned(1))); // Validity Flags
26+ // bit0 validTOW 1 = Valid Time of Week
27+ // bit1 validWKN 1 = Valid Week Number
28+ // bit2 validUTC 1 = Valid UTC (Leap Seconds already known)
29+} UbloxNavTimeUtcRecType __attribute__((aligned(1)));
30+
31+// 高速サンプルデータ記録用データタイプ
32+typedef struct {
33+ UbloxNavTimeUtcRecType gps; // GPSタイムスタンプ
34+ unsigned char data[AD_CHNUM][AD_SAMPLE][AD_BYTES]; // AD
35+} HighSampleRecType;
36+
37+#define HIGH_WRITE_LEN szieof(HighSampleRecType)
38+#endif
39+
40+#define HIGH_WRITE_LEN (9 + AD_CHNUM*AD_SAMPLE*AD_BYTES) // 仮で50Hz 記録周波数で変わるので要変更!!!!!!!!!!!!!!
41+
42+
43+int sec_file_open(FILE **fp, AdData *D);
44+int sec_file_out(FILE *fp, char *out, int len);
45+int sec_file_close(FILE *fp);
46+int sec_make_rec_data(AdData *ad, char *buf);
47+
48+int high_file_open(FILE **fp, AdData *D);
49+int high_file_out(FILE *fp, char *out, int len);
50+int high_file_close(FILE *fp);
51+int high_make_rec_data(AdData *ad, char *buf);
52+
53+#endif
--- /dev/null
+++ b/ad_ring.c
@@ -0,0 +1,200 @@
1+#include <pthread.h>
2+#include <semaphore.h>
3+
4+
5+#include "ring.h"
6+#include "ad_ring.h"
7+#include "mes_print.h"
8+
9+// Ring Buffer読み込みポインタ個数
10+#define AD_RING_READ_NUM 2
11+// Ring Buffer読み込みポインター 1sec記録用
12+#define AD_RING_READ_PTR1 0
13+// Ring Buffer読み込みポインター 1min記録用
14+#define AD_RING_READ_PTR2 1
15+
16+static AdData ad_ring_buf[AD_RING_NUM];
17+
18+// ミューテックス
19+static pthread_mutex_t mutex_ad_ring = PTHREAD_MUTEX_INITIALIZER;
20+
21+// Ring buffer
22+static RING_T *ring;
23+
24+int ad_ring_init(void)
25+{
26+pthread_mutex_lock(&mutex_ad_ring);
27+ ring = ring_create(AD_RING_READ_NUM);
28+ if (ring == NULL) {
29+ PERRF("ERROR ring_create() == NULL\n");
30+pthread_mutex_unlock(&mutex_ad_ring);
31+ return -1;
32+ }
33+ ring_init(ring, AD_RING_NUM);
34+pthread_mutex_unlock(&mutex_ad_ring);
35+ return 0;
36+}
37+void ad_ring_clear_sec(void)
38+{
39+ ring_clear(ring, AD_RING_READ_PTR1);
40+}
41+void ad_ring_clear_high(void)
42+{
43+ ring_clear(ring, AD_RING_READ_PTR2);
44+}
45+void ad_ring_clear_latest(void)
46+{
47+ ring_latest_set(ring, -1);
48+}
49+
50+// 読み出し位置 1secデータ記録で使用
51+int ad_ring_read_get_sec(void)
52+{
53+ return ring_read_get(ring, AD_RING_READ_PTR1);
54+}
55+void ad_ring_read_set_sec(int i)
56+{
57+ ring_read_set(ring, AD_RING_READ_PTR1, i);
58+}
59+void ad_ring_read_plus_sec(void)
60+{
61+ ring_read_plus(ring, AD_RING_READ_PTR1);
62+}
63+// 読み出し位置 高速データ記録で使用
64+int ad_ring_read_get_high(void)
65+{
66+ return ring_read_get(ring, AD_RING_READ_PTR2);
67+}
68+void ad_ring_read_set_high(int i)
69+{
70+ ring_read_set(ring, AD_RING_READ_PTR2, i);
71+}
72+void ad_ring_read_plus_high(void)
73+{
74+ ring_read_plus(ring, AD_RING_READ_PTR2);
75+}
76+
77+// 書き込み位置 AD受信で使用
78+int ad_ring_write_get(void)
79+{
80+ return ring_write_get(ring);
81+}
82+void ad_ring_write_plus(void)
83+{
84+ ring_write_plus(ring);
85+}
86+// 読み込んでいないデータ数
87+int ad_ring_num_get_sec(void)
88+{
89+ return ring_num_get(ring, AD_RING_READ_PTR1);
90+}
91+// 読み込んでいないデータ数
92+int ad_ring_num_get_high(void)
93+{
94+ return ring_num_get(ring, AD_RING_READ_PTR2);
95+}
96+// 最新データ位置 表示
97+int ad_ring_latest_get(void)
98+{
99+ return ring_latest_get(ring);
100+}
101+void ad_ring_latest_set(int i)
102+{
103+ ring_latest_set(ring, i);
104+}
105+// データ取得
106+AdData* ad_ring_get(int ptr)
107+{
108+ AdData* p;
109+pthread_mutex_lock(&mutex_ad_ring);
110+ p = &ad_ring_buf[ptr];
111+pthread_mutex_unlock(&mutex_ad_ring);
112+ return p;
113+}
114+/*
115+ バッファにデータコピー
116+*/
117+void ad_ring_set(AdData *data)
118+{
119+ int i;
120+
121+pthread_mutex_lock(&mutex_ad_ring);
122+ i = ring_write_get(ring);
123+ ad_ring_buf[i] = *data;
124+ // 最新データ位置セット
125+ ring_latest_set(ring, i);
126+pthread_mutex_unlock(&mutex_ad_ring);
127+}
128+
129+/*
130+ パケットバッファフル?
131+ 1=Full
132+ 0=not Full
133+*/
134+int ad_ring_is_full(void)
135+{
136+ return ring_is_full(ring, AD_RING_READ_PTR1);
137+}
138+
139+
140+/**** CUnit test
141+*/
142+#ifdef CUNIT
143+static void test_ad_ring(void)
144+{
145+ ad_ring_init();
146+
147+ // CLEAR
148+ ad_ring_clear_sec();
149+ CU_ASSERT(ad_ring_read_get_sec() == 0);
150+ ad_ring_clear_high();
151+ CU_ASSERT(ad_ring_read_get_high() == 0);
152+ ad_ring_clear_latest();
153+ CU_ASSERT(ad_ring_latest_get() == -1);
154+
155+ // PLUS
156+ ad_ring_read_plus_sec();
157+ CU_ASSERT(ad_ring_read_get_sec() == 1);
158+ ad_ring_read_plus_high();
159+ CU_ASSERT(ad_ring_read_get_high() == 1);
160+ ad_ring_write_plus();
161+ CU_ASSERT(ad_ring_write_get() == 1);
162+
163+ // 境界値でPLUS
164+ ad_ring_read_set_sec(AD_RING_NUM - 1);
165+ ad_ring_read_plus_sec();
166+ CU_ASSERT(ad_ring_read_get_sec() == 0);
167+
168+ ad_ring_read_set_high(AD_RING_NUM - 1);
169+ ad_ring_read_plus_high();
170+ CU_ASSERT(ad_ring_read_get_high() == 0);
171+
172+ ring->write = AD_RING_NUM - 1;
173+ ad_ring_write_plus();
174+ CU_ASSERT(ad_ring_write_get() == 0);
175+
176+ //
177+ ring->write = 1;
178+ ring->read[AD_RING_READ_PTR1] = 0;
179+ CU_ASSERT(ad_ring_num_get_sec() == 1);
180+
181+ ring->write = 0;
182+ ring->read[AD_RING_READ_PTR1] = AD_RING_NUM - 1;
183+ CU_ASSERT(ad_ring_num_get_sec() == 1);
184+
185+ ring->write = 1;
186+ ring->read[AD_RING_READ_PTR2] = 0;
187+ CU_ASSERT(ad_ring_num_get_high() == 1);
188+
189+ ring->write = 0;
190+ ring->read[AD_RING_READ_PTR2] = AD_RING_NUM - 1;
191+ CU_ASSERT(ad_ring_num_get_high() == 1);
192+
193+}
194+
195+void ad_ring_test(CU_pSuite test_suite)
196+{
197+ CU_add_test(test_suite, "test_ad_ring", test_ad_ring);
198+
199+}
200+#endif
--- /dev/null
+++ b/ad_ring.h
@@ -0,0 +1,70 @@
1+#if !defined(__AVG_RING_H__)
2+#define __AVG_RING_H__
3+
4+#include <time.h>
5+
6+// リングバッファサイズ 個数
7+#define AD_RING_NUM (60 * 5)
8+
9+#define AD_CHNUM 6 // AD CH数
10+#define AD_SAMPLE 50 // AD ICの出力レート [Hz]
11+#define AD_BYTES 3 // AD 1sample dataのバイト数
12+
13+// NAV-TIMEUTCパケットのデータ格納
14+typedef struct {
15+ unsigned long tow; // ms GPS Millisecond Time of Week
16+ unsigned long tacc; // ns Time Accuracy Estimate
17+ long nano; // ns Nanoseconds of second, range -1e9 .. 1e9 (UTC)
18+ unsigned int year; // UTC
19+ unsigned char month; //
20+ unsigned char day;
21+ unsigned char hour;
22+ unsigned char min;
23+ unsigned char sec;
24+ unsigned char valid; // Validity Flags
25+ // bit0 validTOW 1 = Valid Time of Week
26+ // bit1 validWKN 1 = Valid Week Number
27+ // bit2 validUTC 1 = Valid UTC (Leap Seconds already known)
28+} UbloxNavTimeUtc;
29+
30+// リングバッファのデータタイプ
31+typedef struct {
32+ UbloxNavTimeUtc gps; // GPSタイムスタンプ SPIで受信
33+ struct tm t; // タイムスタンプ struct tmの月は(0〜11)なので注意 年は1900からのオフセット
34+ long data1sec[AD_CHNUM]; // 1sec平均値 SPIで受信
35+ long data[AD_CHNUM][AD_SAMPLE]; // AD_SAMPLE[Hz]の生データ SPIで受信
36+ long avg[AD_CHNUM][AD_SAMPLE]; // 平均後データ
37+} AdData;
38+
39+
40+
41+int ad_ring_init(void);
42+
43+void ad_ring_clear_sec(void);
44+void ad_ring_clear_high(void);
45+void ad_ring_clear_latest(void);
46+
47+int ad_ring_read_get_sec(void);
48+void ad_ring_read_set_sec(int i);
49+void ad_ring_read_plus_sec(void);
50+int ad_ring_num_get_sec(void);
51+
52+int ad_ring_read_get_high(void);
53+void ad_ring_read_set_high(int i);
54+void ad_ring_read_plus_high(void);
55+int ad_ring_num_get_high(void);
56+
57+int ad_ring_write_get(void);
58+void ad_ring_write_plus(void);
59+int ad_ring_latest_get(void);
60+void ad_ring_latest_set(int i);
61+AdData* ad_ring_get(int ptr);
62+void ad_ring_set(AdData *data);
63+int ad_ring_full(void);
64+
65+#ifdef CUNIT
66+ #include <CUnit/CUnit.h>
67+ void ad_ring_test(CU_pSuite test_suite);
68+#endif
69+
70+#endif
--- /dev/null
+++ b/conf.c
@@ -0,0 +1,154 @@
1+#include <pthread.h>
2+#include <semaphore.h>
3+#include <string.h>
4+#include <syslog.h>
5+#include <stdio.h>
6+
7+#include "conf.h"
8+#include "debug_print.h"
9+
10+//
11+/**** Station ID ***************************************************
12+*/
13+#define SID_MAX 16
14+static char gsid[SID_MAX + 1];
15+
16+// ミューテックス
17+static pthread_mutex_t mutex_sid = PTHREAD_MUTEX_INITIALIZER;
18+
19+void sid_set(char *s)
20+{
21+pthread_mutex_lock(&mutex_sid);
22+ strncpy(gsid, s, SID_MAX);
23+ gsid[SID_MAX] = 0;
24+pthread_mutex_unlock(&mutex_sid);
25+}
26+void sid_get(char *s)
27+{
28+pthread_mutex_lock(&mutex_sid);
29+ strncpy(s, gsid, SID_MAX);
30+ s[SID_MAX] = 0;
31+pthread_mutex_unlock(&mutex_sid);
32+}
33+char *sid_getp(void)
34+{
35+ return gsid;
36+}
37+
38+//
39+/**** 設定ファイル *******************************************
40+*/
41+/*
42+ 文字列の前から空白を取り除く
43+*/
44+static void trims_space(char *name)
45+{
46+ char c;
47+ char *name0;
48+ int len;
49+
50+ name0 = name;
51+ len = strlen(name);
52+
53+ // 最初の非空白文字までポインタ移動
54+ while (*name) {
55+ c = *name;
56+ if (c != ' ') break;
57+ name++;
58+ len--;
59+ }
60+ if (len < 0) return;
61+ // 移動
62+ if (name0 != name) memmove(name0, name, len);
63+ // 末尾に0入れる
64+ name0[len] = 0;
65+}
66+/*
67+ 文字列の後ろから空白を取り除く
68+*/
69+static void trime_space(char *name)
70+{
71+ char c;
72+ int len, i;
73+
74+ // 文字列末尾
75+ len = strlen(name);
76+ name += (len - 1);
77+ // 最初の非空白文字までポインタ移動
78+ for(i = len - 1; i >= 0; i--) {
79+ c = *name;
80+ if (c != ' ') break;
81+ name--;
82+ }
83+ // 末尾に0入れる
84+ *(name + 1) = 0;
85+}
86+/*
87+ 文字列の前後から空白を取り除く
88+*/
89+static void trim_space(char *name)
90+{
91+ if (name == NULL) return;
92+ trims_space(name);
93+ trime_space(name);
94+}
95+/*
96+ 文字列の末尾からCR LFを除く
97+*/
98+static void trim_crlf(char *name)
99+{
100+ int i;
101+ int len;
102+ char *src, *dst;
103+
104+ if (name == NULL) return;
105+ len = strlen(name);
106+ src = name;
107+ dst = name;
108+ for(i = 0; i < len; i++) {
109+ if (*src != 0x0d && *src != 0x0a) {
110+ *dst = *src;
111+ dst++;
112+ }
113+ src++;
114+ }
115+ *dst = 0;
116+}
117+
118+/*
119+ 読み込み
120+
121+return
122+ -1=ERR
123+ 0=OK
124+*/
125+int conf_read(void)
126+{
127+ FILE *fp;
128+ char buf[256];
129+ char buf2[256];
130+
131+ fp = fopen(CONF_FILE, "rt");
132+ if (fp == NULL) {
133+ syslog(LOG_ERR, "conf_read(): conf file not found. %s", CONF_FILE);
134+ return -1;
135+ }
136+
137+ syslog(LOG_INFO, "conf_read():");
138+ while(fgets(buf, sizeof(buf), fp)) {
139+ // CR LF除く
140+ trim_crlf(buf);
141+ trim_space(buf);
142+ PDEBUG(buf);
143+ PDEBUG("\n");
144+ // Station ID
145+ if (sscanf(buf, "sid = %s", buf2) == 1) {
146+ sid_set(buf2);
147+ syslog(LOG_INFO, "sid=%s", sid_getp());
148+ }
149+ }
150+ fclose(fp);
151+ return 0;
152+}
153+
154+
--- /dev/null
+++ b/conf.h
@@ -0,0 +1,13 @@
1+#if !defined(__CONF_H__)
2+#define __CONF_H__
3+
4+// 設定ファイル
5+#define CONF_FILE "/etc/meas.conf"
6+
7+void sid_set(char *s);
8+void sid_get(char *s);
9+char *sid_getp(void);
10+int conf_read(void);
11+
12+
13+#endif
--- /dev/null
+++ b/makefile.host
@@ -0,0 +1,35 @@
1+CC = gcc
2+
3+# -DDUMMY ダミーデータで動作する
4+all: CFLAGS = -DDUMMY
5+cunit: CFLAGS = -DCUNIT
6+
7+LDFLAGS =
8+LIBS = -lm -lpthread
9+TEST_LIBS = $(LIBS) -lcunit
10+
11+SRCS0 = thread_rcv.c spi.c ring.c ad_ring.c rec.c sts.c ad_file.c
12+SRCS = scilog.c $(SRCS0)
13+TEST_SRCS = test.c $(SRCS0)
14+
15+HDRS = mes_print.h debug_print.h my_thread.h spi.h ring.h ad_ring.h rec.h sts.h ad_file.h
16+
17+OBJS = $(SRCS:.c=.o)
18+TEST_OBJS = $(TEST_SRCS:.c=.o)
19+
20+PROGRAM = scilog
21+TEST_PROG = test
22+
23+all: $(PROGRAM)
24+
25+cunit: $(TEST_PROG)
26+
27+$(PROGRAM): $(OBJS) $(HDRS)
28+ $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $(PROGRAM)
29+
30+$(TEST_PROG): $(TEST_OBJS) $(HDRS)
31+ $(CC) $(TEST_OBJS) $(LDFLAGS) $(TEST_LIBS) -o $(TEST_PROG)
32+
33+clean:; rm -f *.o *~ $(PROGRAM) $(TEST_PROG)
34+
35+### End of Makefile
--- a/my_thread.h
+++ b/my_thread.h
@@ -3,4 +3,9 @@
33
44 void* thread_rcv(void* pParam);
55
6+#ifdef CUNIT
7+ #include <CUnit/CUnit.h>
8+ void thread_rcv_test(CU_pSuite test_suite);
9+#endif
10+
611 #endif
--- /dev/null
+++ b/ring.c
@@ -0,0 +1,142 @@
1+/*
2+ Ring Buffer用基本機能
3+ write位置
4+ read位置
5+*/
6+#include <stdlib.h>
7+#include <pthread.h>
8+#include <semaphore.h>
9+
10+#include "ring.h"
11+
12+#define READ_NUM_MAX 256
13+// ミューテックス
14+static pthread_mutex_t mutex_ring = PTHREAD_MUTEX_INITIALIZER;
15+
16+/*
17+ int read_num
18+ 読み込みポインタの個数
19+*/
20+RING_T* ring_create(int read_num)
21+{
22+ RING_T *t;
23+ if (read_num <= 0) return NULL;
24+ if (read_num > READ_NUM_MAX) return NULL;
25+
26+ t = malloc(sizeof(RING_T));
27+ if (t != NULL) {
28+ // readポインタ確保
29+ t->read = malloc(sizeof(int) * read_num);
30+ if (t->read == NULL) {
31+ free(t);
32+ return NULL;
33+ }
34+ t->read_num = read_num;
35+ }
36+ return t;
37+}
38+void ring_destroy(RING_T *t)
39+{
40+ free(t->read);
41+ free(t);
42+}
43+/*
44+ int num: バッファの個数
45+*/
46+void ring_init(RING_T *t, int num)
47+{
48+ int i;
49+
50+pthread_mutex_lock(&mutex_ring);
51+ t->write = 0;
52+ for(i = 0; i < t->read_num; i++) {
53+ t->read[i] = 0;
54+ }
55+ t->latest = -1;
56+ t->num = num;
57+pthread_mutex_unlock(&mutex_ring);
58+}
59+void ring_clear(RING_T *t, int no)
60+{
61+ ring_read_set(t, no, ring_write_get(t));
62+}
63+/*
64+ 読み出し位置
65+ int no
66+ readポインタ番号
67+*/
68+int ring_read_get(RING_T *t, int no)
69+{
70+ int i;
71+pthread_mutex_lock(&mutex_ring);
72+ i = t->read[no];
73+pthread_mutex_unlock(&mutex_ring);
74+ return i;
75+}
76+void ring_read_set(RING_T *t, int no, int i)
77+{
78+pthread_mutex_lock(&mutex_ring);
79+ t->read[no] = i;
80+pthread_mutex_unlock(&mutex_ring);
81+}
82+void ring_read_plus(RING_T *t, int no)
83+{
84+pthread_mutex_lock(&mutex_ring);
85+ t->read[no]++;
86+ if (t->read[no] >= t->num) t->read[no] = 0;
87+pthread_mutex_unlock(&mutex_ring);
88+}
89+
90+// 書き込み位置
91+int ring_write_get(RING_T *t)
92+{
93+ int i;
94+pthread_mutex_lock(&mutex_ring);
95+ i = t->write;
96+pthread_mutex_unlock(&mutex_ring);
97+ return i;
98+}
99+void ring_write_plus(RING_T *t)
100+{
101+pthread_mutex_lock(&mutex_ring);
102+ t->write++;
103+ if (t->write >= t->num) t->write = 0;
104+pthread_mutex_unlock(&mutex_ring);
105+}
106+// 読み込んでいないデータ数
107+int ring_num_get(RING_T *t, int no)
108+{
109+ int i;
110+
111+pthread_mutex_lock(&mutex_ring);
112+ i = t->write - t->read[no];
113+ if (i < 0) i += t->num;
114+pthread_mutex_unlock(&mutex_ring);
115+ return i;
116+}
117+// 最新データ位置
118+int ring_latest_get(RING_T *t)
119+{
120+ int i;
121+pthread_mutex_lock(&mutex_ring);
122+ i = t->latest;
123+pthread_mutex_unlock(&mutex_ring);
124+ return i;
125+}
126+void ring_latest_set(RING_T *t, int i)
127+{
128+pthread_mutex_lock(&mutex_ring);
129+ t->latest = i;
130+pthread_mutex_unlock(&mutex_ring);
131+}
132+
133+/*
134+ パケットバッファフル?
135+ 1=Full
136+ 0=not Full
137+*/
138+int ring_is_full(RING_T *t, int no)
139+{
140+ if (ring_num_get(t, no) >= t->num - 1) return 1;
141+ return 0;
142+}
--- /dev/null
+++ b/ring.h
@@ -0,0 +1,33 @@
1+
2+
3+#if !defined(__RING_H__)
4+#define __RING_H__
5+
6+typedef struct {
7+ // 読み出し位置 複数設定できる
8+ int *read;
9+ // 書き込み位置
10+ int write;
11+ // 最新データ位置
12+ int latest;
13+ // バッファ個数
14+ int num;
15+ // readポインタ個数
16+ int read_num;
17+} RING_T;
18+
19+RING_T* ring_create(int read_num);
20+void ring_destroy(RING_T *t);
21+void ring_init(RING_T *t, int num);
22+void ring_clear(RING_T *t, int no);
23+int ring_read_get(RING_T *t, int no);
24+void ring_read_set(RING_T *t, int no, int i);
25+void ring_read_plus(RING_T *t, int no);
26+int ring_write_get(RING_T *t);
27+void ring_write_plus(RING_T *t);
28+int ring_num_get(RING_T *t, int no);
29+int ring_latest_get(RING_T *t);
30+void ring_latest_set(RING_T *t, int i);
31+int ring_is_full(RING_T *t, int no);
32+
33+#endif
Binary files a/scilog and b/scilog differ
--- a/scilog.c
+++ b/scilog.c
@@ -22,6 +22,11 @@
2222
2323 #include "my_thread.h"
2424 #include "spi.h"
25+#include "ad_ring.h"
26+#include "sts.h"
27+#include "thread_rec.h"
28+#include "conf.h"
29+#include "ad_file.h"
2530
2631 // debug_print.h内で#define DEBUG_PRINTしているので
2732 // リリース時は、debug_print.hでコメントする
@@ -39,7 +44,7 @@
3944
4045 /**** 設定デフォルト値
4146 */
42-//#define SID_DEF "DEF"
47+#define SID_DEF "DEF"
4348
4449
4550 //
@@ -83,11 +88,18 @@ int main (int argc, char *argv[])
8388 // lcd_print("sciLogger");
8489 // lcd_pos(0, 3);
8590
91+ ad_ring_init();
92+ sts_init();
93+
94+//printf("%d\n", sizeof(UbloxNavTimeUtcRecType));
95+//printf("%d\n", sizeof(HighSampleRecType));
96+//goto END;
97+
8698 // デフォルト設定
87-// sid_set(SID_DEF);
99+ sid_set(SID_DEF);
88100 // 設定ファイル読み込み
89-// conf_read();
90-// PDEBUG("sid=%s\n", sid_getp());
101+ conf_read();
102+ PDEBUG("sid=%s\n", sid_getp());
91103 // lcd_print("*");
92104
93105 PDEBUG("sciLogger %s START\n", VERSION);
@@ -116,9 +128,7 @@ int main (int argc, char *argv[])
116128 //
117129 /**** メインループ 記録 ************************
118130 */
119- while(1) {
120- sleep(1);
121- } // メインループ終わり
131+ thread_rec(NULL);
122132 END:
123133 sig_handler(0);
124134
--- a/spi.h
+++ b/spi.h
@@ -18,36 +18,17 @@
1818 // SPIで実際に受信したデータ長を取得
1919 #define CMD_RECEIVED_LEN_GET 20
2020
21-// SPIで受信するデータ長 固定長
21+// SPIで受信するデータ長 固定長 $含む
2222 #define SPI_DATA_LEN 945
2323 // SPI受信データの先頭文字
2424 #define SPI_HEAD_CHAR '$'
2525
26-// NAV-TIMEUTCパケットのデータ格納
27-typedef struct {
28- unsigned long tow; // 0 ms GPS Millisecond Time of Week
29- unsigned long tacc; // 4 ns Time Accuracy Estimate
30- long nano; // 8 ns Nanoseconds of second, range -1e9 .. 1e9 (UTC)
31- unsigned int year; // 12 UTC
32- unsigned char month; // 16
33- unsigned char day;
34- unsigned char hour;
35- unsigned char min;
36- unsigned char sec;
37- unsigned char valid; // Validity Flags
38- // bit0 validTOW 1 = Valid Time of Week
39- // bit1 validWKN 1 = Valid Week Number
40- // bit2 validUTC 1 = Valid UTC (Leap Seconds already known)
41-} UbloxNavTimeUtc;
26+// SPI受信データの先頭からのオフセット
27+#define SPI_OFS_GPS (18-17)
28+#define SPI_OFS_1SEC (38-17)
29+#define SPI_OFS_DATA (62-17)
4230
43-#define AD_CHNUM 6
44-#define AD_SAMPLE 50 // AD ICの出力レート [Hz]
4531
46-typedef struct {
47- UbloxNavTimeUtc t; // タイムスタンプ
48- long data1sec[AD_CHNUM]; // 1sec平均値
49- long data[AD_CHNUM][AD_SAMPLE]; // AD_SAMPLE[Hz]のデータ
50-} ADbufType;
5132
5233
5334 int spi_get_fd(void);
--- /dev/null
+++ b/sts.c
@@ -0,0 +1,40 @@
1+#include "sts.h"
2+
3+/*
4+ ステータス
5+*/
6+static int sts;
7+
8+void sts_init(void)
9+{
10+ sts = STS_TIME_FIX;
11+}
12+/*
13+ ステータス返す
14+*/
15+int sts_get(void)
16+{
17+ return sts;
18+}
19+
20+// LCD表示用
21+char *sts_get_str(void)
22+{
23+ switch(sts) {
24+ case STS_TIME_FIX:
25+ return "WAIT TIME FIX";
26+ case STS_REC_INIT:
27+ return "REC INIT ";
28+ case STS_REC:
29+ return "RECORDING ";
30+ case STS_REC_OFF:
31+ return "RECORD OFF ";
32+ case STS_FILE_ERR:
33+ return "WRITE ERROR ";
34+ }
35+ return "UNKNOWN ";
36+}
37+void sts_set(int sts0)
38+{
39+ sts = sts0;
40+}
--- /dev/null
+++ b/sts.h
@@ -0,0 +1,17 @@
1+#if !defined(__STS_H__)
2+#define __STS_H__
3+
4+#define STS_TIME_FIX 1
5+#define STS_REC_INIT 3
6+#define STS_REC 4
7+#define STS_REC_OFF 5
8+#define STS_FILE_ERR 6
9+
10+
11+void sts_init(void);
12+int sts_get(void);
13+char *sts_get_str(void);
14+void sts_set(int sts0);
15+
16+#endif
17+
Binary files /dev/null and b/test differ
--- /dev/null
+++ b/test.c
@@ -0,0 +1,23 @@
1+
2+#include <stdio.h>
3+#include <CUnit/CUnit.h>
4+#include <CUnit/Console.h>
5+
6+#include "my_thread.h"
7+#include "spi.h"
8+#include "ad_ring.h"
9+
10+int main (int argc, char *argv[])
11+{
12+ CU_pSuite test_suite;
13+ CU_initialize_registry();
14+ test_suite = CU_add_suite("scilog", NULL, NULL);
15+
16+ thread_rcv_test(test_suite);
17+ ad_ring_test(test_suite);
18+
19+ CU_console_run_tests();
20+
21+ CU_cleanup_registry();
22+
23+}
--- a/thread_rcv.c
+++ b/thread_rcv.c
@@ -5,18 +5,38 @@
55 #include <fcntl.h>
66 #include <syslog.h>
77 #include <sys/types.h>
8+#include <string.h>
89
910 #include "spi.h"
11+#include "ad_ring.h"
1012
11-
12-static int decode(char *buf, ADbufType *ad)
13+/*
14+ Little Endian
15+ 3byte -> signed long(4byte)
16+*/
17+static long b3_to_long32(unsigned char *ptr)
18+{
19+ char buf[4];
20+
21+ buf[0] = *ptr++;
22+ buf[1] = *ptr++;
23+ buf[2] = *ptr;
24+ if (*ptr & 0x80) {
25+ buf[3] = 0xFF;
26+ } else {
27+ buf[3] = 0;
28+ }
29+ return *((long*)buf);
30+}
31+static int decode(char *buf, AdData *ad)
1332 {
1433 UbloxNavTimeUtc *gps;
1534 u_int8_t *ptr;
1635 int ch;
36+ int i;
1737
1838 ptr = (u_int8_t*)buf;
19- gps = &(ad->t);
39+ gps = &(ad->gps);
2040
2141 if (*ptr++ != SPI_HEAD_CHAR) return -1;
2242 // GPS
@@ -36,18 +56,42 @@ static int decode(char *buf, ADbufType *ad)
3656 ptr += 4;
3757 }
3858 // 50Hz data
59+ for(ch = 0; ch < AD_CHNUM; ch++) {
60+ for(i = 0; i < AD_SAMPLE; i++) {
61+ ad->data[ch][i] = b3_to_long32(ptr);
62+ ptr += 3;
63+ }
64+ }
65+ // Checksum
3966
67+ // gps->struct tm
68+ ad->t.tm_year = gps->year - 1900;
69+ ad->t.tm_mon = gps->month - 1; // struct tmの月は(0〜11)なので注意
70+ ad->t.tm_mday = gps->day;
71+ ad->t.tm_hour = gps->hour;
72+ ad->t.tm_min = gps->min;
73+ ad->t.tm_sec = gps->sec;
74+
4075 return 0;
4176 }
77+/*
78+ int freq
79+ 平均化後の周波数 Hz
80+*/
81+static void do_avg(int freq, AdData *ad)
82+{
83+// 仮コード
84+ memcpy(ad->avg, ad->data, AD_CHNUM*AD_SAMPLE*AD_BYTES);
85+}
4286 void* thread_rcv(void* pParam)
4387 {
4488 while(1) {
4589 fd_set fds;
4690 char buf[SPI_DATA_LEN+256];
4791 int i;
48- int ch;
92+// int ch;
4993 int fd_spi;
50-ADbufType ad;
94+ AdData ad, *ad_ptr;
5195
5296 fd_spi = spi_get_fd();
5397 // select の準備
@@ -67,7 +111,11 @@ ADbufType ad;
67111 // ring_zero();
68112 // データ取得
69113 spi_rx_get(buf);
114+ // デコード
70115 decode(buf, &ad);
116+ // 平均 仮コード 要変更
117+ do_avg(AD_SAMPLE, &ad);
118+#if 0
71119 printf("%04d/%02d/%02d %02d:%02d:%02d.%09ld,%6lums,%6luns,%02X",
72120 ad.t.year, ad.t.month, ad.t.day, ad.t.hour, ad.t.min, ad.t.sec, ad.t.nano,
73121 ad.t.tow, ad.t.tacc, ad.t.valid);
@@ -75,6 +123,22 @@ for(ch = 0; ch < AD_CHNUM; ch++) {
75123 printf(",%+7ld", ad.data1sec[ch]);
76124 }
77125 printf("\r\n");
126+for(ch = 0; ch < AD_CHNUM; ch++) {
127+ printf(",%+7ld", ad.data[ch][0]);
128+}
129+printf("\r\n");
130+for(ch = 0; ch < AD_CHNUM; ch++) {
131+ printf(",%+7ld", ad.data[ch][49]);
132+}
133+printf("\r\n");
134+#endif
135+ // ADリングバッファに書き込み
136+ ad_ptr = ad_ring_get(ad_ring_write_get());
137+ *ad_ptr = ad;
138+ // 最新データ位置
139+ ad_ring_latest_set(ad_ring_write_get());
140+ // 書き込み位置+1
141+ ad_ring_write_plus();
78142
79143 } // while((i = sub_dnum_get()) > 0) {
80144 } // if(FD_ISSET(fd_sub, &fds)) {
@@ -82,3 +146,60 @@ printf("\r\n");
82146 return NULL;
83147 }
84148
149+//
150+/**** CUnit test
151+*/
152+#ifdef CUNIT
153+#include <CUnit/CUnit.h>
154+
155+static void test_b3_to_long32(void)
156+{
157+ long l;
158+ char buf[SPI_DATA_LEN+256];
159+ AdData ad;
160+ int i;
161+
162+ buf[0] = 0x56;
163+ buf[1] = 0x34;
164+ buf[2] = 0x12;
165+ l = b3_to_long32(buf);
166+ CU_ASSERT(l == 0x00123456);
167+
168+ buf[0] = 0x56;
169+ buf[1] = 0x34;
170+ buf[2] = 0x82;
171+ l = b3_to_long32(buf);
172+ CU_ASSERT(l == (long)0xFF823456);
173+
174+ buf[0] = 0xFF;
175+ buf[1] = 0xFF;
176+ buf[2] = 0xFF;
177+ l = b3_to_long32(buf);
178+ CU_ASSERT(l == -1);
179+
180+ buf[0] = '$';
181+ i = SPI_OFS_DATA;
182+ buf[i++] = 0x56;
183+ buf[i++] = 0x34;
184+ buf[i++] = 0x12;
185+ decode(buf, &ad);
186+ CU_ASSERT(ad.data[0][0] == 0x123456);
187+
188+ buf[0] = '$';
189+ i = SPI_OFS_DATA + AD_CHNUM * AD_SAMPLE * 3;
190+ i -= 3;
191+ buf[i++] = 0x56;
192+ buf[i++] = 0x34;
193+ buf[i++] = 0x12;
194+ decode(buf, &ad);
195+ CU_ASSERT(ad.data[AD_CHNUM-1][AD_SAMPLE-1] == 0x123456);
196+}
197+
198+void thread_rcv_test(CU_pSuite test_suite)
199+{
200+
201+ CU_add_test(test_suite, "test_b3_to_long32", test_b3_to_long32);
202+
203+}
204+
205+#endif
--- /dev/null
+++ b/thread_rec.c
@@ -0,0 +1,251 @@
1+
2+#include <stdio.h>
3+#include <syslog.h>
4+#include <unistd.h>
5+#include <string.h>
6+
7+#include "ad_ring.h"
8+#include "sts.h"
9+#include "debug_print.h"
10+#include "ad_file.h"
11+
12+// 1secファイル書き込み間隔 sec
13+#define SEC_FLUSH_NUM 1
14+//#define SEC_FLUSH_NUM 60
15+
16+// 高速サンプルファイル書き込み間隔 sec
17+#define HIGH_FLUSH_NUM 1
18+
19+// 日付変化検出用
20+static struct tm high_tm;
21+static struct tm sec_tm;
22+
23+//
24+/**** 時刻校正待ち
25+ パケット中の時刻が有効になるのを待つ
26+
27+ Return:
28+ 次の状態
29+*/
30+int ProcTimeFix(void)
31+{
32+ AdData *d;
33+ static int latest = -1;
34+ /*
35+ 時刻校正終わったら、記録開始
36+ */
37+ if (latest == ad_ring_latest_get()) return STS_TIME_FIX;
38+ latest = ad_ring_latest_get();
39+ if (latest >= 0) {
40+ // 最新データの時刻取得
41+ d = ad_ring_get(latest);
42+ // GPS Validチェック
43+ if (d->gps.valid & 0x07) {
44+ PDEBUG("ProcTimeFix: rec init.\n");
45+ return STS_REC_INIT;
46+ }
47+ }
48+ return STS_TIME_FIX;
49+}
50+
51+//
52+/**** 記録初期化
53+
54+ Return:
55+ 次の状態
56+*/
57+int ProcRecInit(void)
58+{
59+ AdData *d;
60+
61+ if (ad_ring_latest_get() >= 0) {
62+ // 記録開始
63+ ad_ring_clear_sec();
64+ ad_ring_clear_high();
65+
66+ // 最新データの時刻取得
67+ d = ad_ring_get(ad_ring_latest_get());
68+ // 日付変化検出用変数初期化
69+ high_tm = d->t;
70+ sec_tm = d->t;
71+
72+ PDEBUG("ProcRecInit: rec start.\n");
73+ return STS_REC;
74+ }
75+ return STS_REC_INIT;
76+}
77+
78+/**** 記録中
79+ 定期的にカードに書き込み
80+
81+ Return:
82+ 次の状態
83+*/
84+int ProcRec(void)
85+{
86+ AdData *d;
87+ FILE *fp = NULL;
88+ char buf[HIGH_WRITE_LEN+128];
89+
90+//
91+/**** 1secデータ記録
92+*/
93+ /*
94+ パケットバッファにデータたまった?
95+ */
96+ if (ad_ring_num_get_sec() >= SEC_FLUSH_NUM) {
97+ // データ取り出し
98+ d = ad_ring_get(ad_ring_read_get_sec());
99+ // ファイルオープン
100+ sec_file_open(&fp, d);
101+
102+ // 書き込みループ
103+ while(ad_ring_num_get_sec() > 0) {
104+ // データ取り出し
105+ d = ad_ring_get(ad_ring_read_get_sec());
106+PDEBUG("%04d/%02d/%02d %02d:%02d:%02d.%09ld,%6lums,%6luns,%02X",
107+ d->gps.year, d->gps.month, d->gps.day, d->gps.hour, d->gps.min, d->gps.sec, d->gps.nano,
108+ d->gps.tow, d->gps.tacc, d->gps.valid);
109+int ch;
110+for(ch = 0; ch < AD_CHNUM; ch++) {
111+ PDEBUG(",%+7ld", d->data1sec[ch]);
112+}
113+PDEBUG("\r\n");
114+
115+ // 日にち変わった ファイル切換する
116+#ifdef DEBUG_FILE_MIN
117+ // デバッグ用 ?分ごとファイル切り替え
118+ if ((d->t.tm_min % DEBUG_FILE_MIN_PERIOD) == 0 && (d->t.tm_sec == 0) && (d->t.tm_min != sec_tm.tm_min)) {
119+#else
120+ if (d->t.tm_year != sec_tm.tm_year || d->t.tm_mon != sec_tm.tm_mon || d->t.tm_mday != sec_tm.tm_mday) {
121+#endif
122+ // 日付変わったのでファイル切り替える
123+ // 前のファイル閉じる
124+ if (fp != NULL) sec_file_close(fp);
125+ // ファイルオープン
126+ if (sec_file_open(&fp, d)) {
127+ PDEBUG("REC: FG file change ERROR\n");
128+ syslog(LOG_INFO, "REC: FG file change ERROR\n");
129+ } else {
130+ PDEBUG("REC: FG file change OK\n");
131+ syslog(LOG_INFO, "REC: FG file change OK\n");
132+ }
133+ }
134+ // ファイルに書き込むデータ作成
135+ sec_make_rec_data(d, buf);
136+ // ファイルに1データ書き込み Open/Closeなし
137+ if (sec_file_out(fp, buf, strlen(buf))) {
138+ /* 書き込みエラー */
139+ // 読み出し位置クリア
140+ ad_ring_clear_sec();
141+ // ファイル閉じる
142+ sec_file_close(fp);
143+ //
144+ PDEBUG("ProcRec: 1sec file write err\n");
145+ syslog(LOG_INFO, "REC: 1sec file write error\n");
146+ return STS_FILE_ERR;
147+ }
148+ // 読み込み位置進める
149+ ad_ring_read_plus_sec();
150+ // タイムスタンプ記録
151+ sec_tm = d->t;
152+ }
153+ // ファイル閉じる
154+ sec_file_close(fp);
155+ //
156+ PDEBUG("ProcRec: 1sec file write.\n");
157+ }
158+//
159+/**** 高速サンプルデータ記録
160+*/
161+ /*
162+ パケットバッファにデータたまった?
163+ */
164+ if (ad_ring_num_get_high() >= HIGH_FLUSH_NUM) {
165+ // データ取り出し
166+ d = ad_ring_get(ad_ring_read_get_high());
167+ // ファイルオープン
168+ high_file_open(&fp, d);
169+
170+ // 書き込みループ
171+ while(ad_ring_num_get_high() > 0) {
172+ // データ取り出し
173+ d = ad_ring_get(ad_ring_read_get_high());
174+ // 時が変わった ファイル切換する
175+#ifdef DEBUG_FILE_MIN
176+ // デバッグ用 ?分ごとファイル切り替え
177+ if ((d->t.tm_min % DEBUG_FILE_MIN_PERIOD) == 0 && (d->t.tm_high == 0) && (d->t.tm_min != hightm.tm_min)) {
178+#else
179+ if (d->t.tm_year != high_tm.tm_year || d->t.tm_mon != high_tm.tm_mon || d->t.tm_mday != high_tm.tm_mday
180+ || d->t.tm_hour != high_tm.tm_hour) {
181+#endif
182+ // 時が変わったのでファイル切り替える
183+ // 前のファイル閉じる
184+ if (fp != NULL) high_file_close(fp);
185+ // ファイルオープン
186+ if (high_file_open(&fp, d)) {
187+ PDEBUG("REC: FG file change ERROR\n");
188+ syslog(LOG_INFO, "REC: HIGH file change ERROR\n");
189+ } else {
190+ PDEBUG("REC: FG file change OK\n");
191+ syslog(LOG_INFO, "REC: HIGH file change OK\n");
192+ }
193+ }
194+ // ファイルに書き込むデータ作成
195+ high_make_rec_data(d, buf);
196+ // ファイルに1データ書き込み Open/Closeなし
197+ if (high_file_out(fp, buf, HIGH_WRITE_LEN)) {
198+ /* 書き込みエラー */
199+ // 読み出し位置クリア
200+ ad_ring_clear_high();
201+ // ファイル閉じる
202+ high_file_close(fp);
203+ //
204+ PDEBUG("ProcRec: HIGH file write err\n");
205+ syslog(LOG_INFO, "REC: HIGH file write error\n");
206+ return STS_FILE_ERR;
207+ }
208+ // 読み込み位置進める
209+ ad_ring_read_plus_high();
210+ // タイムスタンプ記録
211+ high_tm = d->t;
212+ }
213+ // ファイル閉じる
214+ high_file_close(fp);
215+ //
216+ PDEBUG("ProcRec: HIGH file write.\n");
217+ }
218+
219+ return STS_REC;
220+}
221+
222+void* thread_rec(void* pParam)
223+{
224+ while(1) {
225+ usleep(10*1000);
226+ switch (sts_get()) {
227+ /* 時刻校正中 */
228+ case STS_TIME_FIX:
229+ sts_set(ProcTimeFix());
230+ break;
231+ /* 記録初期化 */
232+ case STS_REC_INIT:
233+ sts_set(ProcRecInit());
234+ break;
235+ /* 記録中 */
236+ case STS_REC:
237+ sts_set(ProcRec());
238+ break;
239+ /* 記録OFF中 */
240+ case STS_REC_OFF:
241+// sts_set(ProcRecOff());
242+ break;
243+ /* ファイルエラー発生中 */
244+ case STS_FILE_ERR:
245+// sts_set(ProcErr());
246+ break;
247+ default:
248+ break;
249+ }
250+ } // メインループ終わり
251+}
--- /dev/null
+++ b/thread_rec.h
@@ -0,0 +1,11 @@
1+#if !defined(__REC_H__)
2+#define __REC_H__
3+
4+
5+
6+int ProcTimeFix(void);
7+int ProcRecInit(void);
8+int ProcRec(void);
9+void* thread_rec(void* pParam);
10+
11+#endif
Show on old repository browser