avoid ctime in GPS UART (#4824)

Co-authored-by: Nathan Schulte <nmschulte@desmas.net>
This commit is contained in:
rusefillc 2022-11-23 14:20:36 -04:00 committed by GitHub
parent b8dee91e09
commit 261222bb04
4 changed files with 50 additions and 48 deletions

View File

@ -20,10 +20,10 @@
* see #testGpsParser * see #testGpsParser
*/ */
#include "pch.h" #include "pch.h"
#include <time.h>
#include "nmea.h" #include "nmea.h"
#include "rtc_helper.h"
static long hex2int(const char *a, int len) { static long hex2int(const char * a, const int len) {
int i; int i;
long val = 0; long val = 0;
@ -35,16 +35,6 @@ static long hex2int(const char *a, int len) {
return val; return val;
} }
static int str2int(const char *a, int len) {
int i = 0, k = 0;
while (i<len) {
k = (k<<3)+(k<<1)+(*a)-'0';
a++;
i++;
}
return k;
}
static float gps_deg_dec(float deg_point) { static float gps_deg_dec(float deg_point) {
float ddeg; float ddeg;
float sec = modff(deg_point, &ddeg) * 60; float sec = modff(deg_point, &ddeg) * 60;
@ -180,14 +170,14 @@ Navigational Status S=Safe C=Caution U=Unsafe V=Not valid
void nmea_parse_gprmc(char const * const nmea, loc_t *loc) { void nmea_parse_gprmc(char const * const nmea, loc_t *loc) {
char const * p = (char *)nmea; char const * p = (char *)nmea;
char dStr[GPS_MAX_STRING]; char dStr[GPS_MAX_STRING];
struct tm timp; efidatetime_t dt;
p = strchr(p, ',') + 1; // read time p = strchr(p, ',') + 1; // read time
str_till_comma(p, dStr); str_till_comma(p, dStr);
if (strlen(dStr) > 5) { if (strlen(dStr) > 5) {
timp.tm_hour = str2int(dStr,2); dt.hour = str2int(dStr, 2);
timp.tm_min = str2int(dStr+2,2); dt.minute = str2int(dStr + 2, 2);
timp.tm_sec = str2int(dStr+4,2); dt.second = str2int(dStr + 4, 2);
} }
p = strchr(p, ',') + 1; // read field Valid status p = strchr(p, ',') + 1; // read field Valid status
@ -245,13 +235,14 @@ void nmea_parse_gprmc(char const * const nmea, loc_t *loc) {
p = strchr(p, ',') + 1; // read date p = strchr(p, ',') + 1; // read date
str_till_comma(p, dStr); str_till_comma(p, dStr);
if (strlen(dStr) > 5) { if (strlen(dStr) > 5) {
timp.tm_mday = str2int(dStr,2); dt.day = str2int(dStr, 2);
timp.tm_mon = str2int(dStr+2,2); dt.month = str2int(dStr + 2, 2);
timp.tm_year = str2int(dStr+4,2)+100; // we receive -200, but standard wait -1900 = add correction dt.year = 100 + // we receive -200, but standard wait -1900 = add correction
str2int(dStr + 4, 2);
} }
if (timp.tm_year > 0 ) { // check if date field is valid if (dt.year > 0 ) { // check if date field is valid
memcpy(&loc->GPStm, &timp, sizeof(timp)); memcpy(&loc->time, &dt, sizeof(dt));
} }
} }

View File

@ -6,6 +6,8 @@
#pragma once #pragma once
#include "rusefi_types.h"
#define GPS_MAX_STRING 256 #define GPS_MAX_STRING 256
typedef enum { typedef enum {
@ -28,7 +30,7 @@ struct GPSlocation {
float speed; float speed;
float altitude; float altitude;
float course; float course;
struct tm GPStm; efidatetime_t time;
nmea_message_type type; nmea_message_type type;
int quality; int quality;
int satellites; int satellites;
@ -42,3 +44,13 @@ int nmea_valid_checksum(const char *);
void nmea_parse_gpgga(char const * const, loc_t *); void nmea_parse_gpgga(char const * const, loc_t *);
void nmea_parse_gprmc(char const * const, loc_t *); void nmea_parse_gprmc(char const * const, loc_t *);
void gps_location(loc_t *, char const * const); void gps_location(loc_t *, char const * const);
static int str2int(const char * a, const int len) {
int i = 0, k = 0;
while (i < len) {
k = (k << 3) + (k << 1) + (*a) - '0';
a++;
i++;
}
return k;
}

View File

@ -11,14 +11,12 @@
* Kot_dnz 2014 * Kot_dnz 2014
*/ */
#if EFI_UART_GPS
#include "pch.h" #include "pch.h"
#include <string.h> #include <string.h>
// todo: MISRA does not like time.h
#include <time.h>
#if EFI_UART_GPS
#include "rusefi_types.h"
#include "console_io.h" #include "console_io.h"
#include "eficonsole.h" #include "eficonsole.h"
#include "nmea.h" #include "nmea.h"
@ -30,13 +28,15 @@ static THD_WORKING_AREA(gpsThreadStack, UTILITY_THREAD_STACK_SIZE);
// this field holds our current state // this field holds our current state
static loc_t GPSdata; static loc_t GPSdata;
static efidatetime_t lastDateTime;
static int gpsMesagesCount = 0; static int gpsMessageCount = 0;
static int uartErrors = 0; static int uartErrors = 0;
// todo: some data structure for coordinates location // TODO: some data structure for coordinates location
// todo:
float getCurrentSpeed(void) { float getCurrentSpeed(void) {
// TODO: ???
return GPSdata.speed; return GPSdata.speed;
} }
@ -44,28 +44,27 @@ static void printGpsInfo() {
efiPrintf("GPS RX %s", hwPortname(engineConfiguration->gps_rx_pin)); efiPrintf("GPS RX %s", hwPortname(engineConfiguration->gps_rx_pin));
efiPrintf("GPS TX %s", hwPortname(engineConfiguration->gps_tx_pin)); efiPrintf("GPS TX %s", hwPortname(engineConfiguration->gps_tx_pin));
efiPrintf("m=%d,e=%d: vehicle speed = %.2f", gpsMesagesCount, uartErrors, getCurrentSpeed()); efiPrintf("m=%d,e=%d: vehicle speed = %.2f", gpsMessageCount, uartErrors, getCurrentSpeed());
float sec = getTimeNowMs() / 1000.0; float sec = getTimeNowMs() / 1000.0;
efiPrintf("communication speed: %.2f", gpsMesagesCount / sec); efiPrintf("communication speed: %.2f", gpsMessageCount / sec);
efiPrintf("GPS latitude = %.2f\r\n", GPSdata.latitude); efiPrintf("GPS latitude = %.2f\r\n", GPSdata.latitude);
efiPrintf("GPS longitude = %.2f\r\n", GPSdata.longitude); efiPrintf("GPS longitude = %.2f\r\n", GPSdata.longitude);
} }
static struct tm curTm; static void onGpsMessage(const char * const buffer) {
static void onGpsMessage(char *buffer) {
gps_location(&GPSdata, buffer); gps_location(&GPSdata, buffer);
date_get_tm(&curTm);
if (GPSdata.quality == 4 && GPSdata.GPStm.tm_year > 0 && GPSdata.GPStm.tm_sec != curTm.tm_sec) { if (GPSdata.quality == 4 && GPSdata.time.year > 0) {
// quality =4 (valis GxRMC), year > 0, and difference more then second getRtcDateTime(&lastDateTime);
date_set_tm(&GPSdata.GPStm); // set GPS time if (GPSdata.time.second != dateTime.second) {
//} // quality =4 (valid GxRMC), year > 0, and difference more than second
setRtcDateTime(GPSdata.time);
}
} }
gpsMesagesCount++;
gpsMessageCount++;
} }
// we do not want this on stack, right? // we do not want this on stack, right?
@ -116,4 +115,4 @@ void initGps(void) {
addConsoleAction("gpsinfo", &printGpsInfo); addConsoleAction("gpsinfo", &printGpsInfo);
} }
#endif /* EFI_UART_GPS */ #endif // EFI_UART_GPS

View File

@ -284,12 +284,12 @@ TEST(misc, testGpsParser) {
assertEqualsM("3 speed", 11.2, GPSdata.speed); assertEqualsM("3 speed", 11.2, GPSdata.speed);
// ASSERT_EQ( 0, GPSdata.altitude) << "3 altitude"; // GPRMC not overwrite altitude // ASSERT_EQ( 0, GPSdata.altitude) << "3 altitude"; // GPRMC not overwrite altitude
ASSERT_EQ( 0, GPSdata.course) << "3 course"; ASSERT_EQ( 0, GPSdata.course) << "3 course";
ASSERT_EQ( 2006, GPSdata.GPStm.tm_year + 1900) << "3 GPS yy"; ASSERT_EQ( 2006, GPSdata.time.year + 1900) << "3 GPS yy";
ASSERT_EQ( 12, GPSdata.GPStm.tm_mon) << "3 GPS mm"; ASSERT_EQ( 12, GPSdata.time.month) << "3 GPS mm";
ASSERT_EQ( 26, GPSdata.GPStm.tm_mday) << "3 GPS dd"; ASSERT_EQ( 26, GPSdata.time.day) << "3 GPS dd";
ASSERT_EQ( 11, GPSdata.GPStm.tm_hour) << "3 GPS hh"; ASSERT_EQ( 11, GPSdata.time.hour) << "3 GPS hh";
ASSERT_EQ( 16, GPSdata.GPStm.tm_min) << "3 GPS mm"; ASSERT_EQ( 16, GPSdata.time.minute) << "3 GPS mm";
ASSERT_EQ( 9, GPSdata.GPStm.tm_sec) << "3 GPS ss"; ASSERT_EQ( 9, GPSdata.time.second) << "3 GPS ss";
// check again first one // check again first one
// we need to pass a mutable string, not a constant because the parser would be modifying the string // we need to pass a mutable string, not a constant because the parser would be modifying the string