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 5da7619577
commit 8eaa901595
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 48 deletions

View File

@ -20,10 +20,10 @@
* see #testGpsParser
*/
#include "pch.h"
#include <time.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;
long val = 0;
@ -35,16 +35,6 @@ static long hex2int(const char *a, int len) {
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) {
float ddeg;
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) {
char const * p = (char *)nmea;
char dStr[GPS_MAX_STRING];
struct tm timp;
efidatetime_t dt;
p = strchr(p, ',') + 1; // read time
str_till_comma(p, dStr);
if (strlen(dStr) > 5) {
timp.tm_hour = str2int(dStr,2);
timp.tm_min = str2int(dStr+2,2);
timp.tm_sec = str2int(dStr+4,2);
dt.hour = str2int(dStr, 2);
dt.minute = str2int(dStr + 2, 2);
dt.second = str2int(dStr + 4, 2);
}
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
str_till_comma(p, dStr);
if (strlen(dStr) > 5) {
timp.tm_mday = str2int(dStr,2);
timp.tm_mon = str2int(dStr+2,2);
timp.tm_year = str2int(dStr+4,2)+100; // we receive -200, but standard wait -1900 = add correction
dt.day = str2int(dStr, 2);
dt.month = str2int(dStr + 2, 2);
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
memcpy(&loc->GPStm, &timp, sizeof(timp));
if (dt.year > 0 ) { // check if date field is valid
memcpy(&loc->time, &dt, sizeof(dt));
}
}

View File

@ -6,6 +6,8 @@
#pragma once
#include "rusefi_types.h"
#define GPS_MAX_STRING 256
typedef enum {
@ -28,7 +30,7 @@ struct GPSlocation {
float speed;
float altitude;
float course;
struct tm GPStm;
efidatetime_t time;
nmea_message_type type;
int quality;
int satellites;
@ -42,3 +44,13 @@ int nmea_valid_checksum(const char *);
void nmea_parse_gpgga(char const * const, loc_t *);
void nmea_parse_gprmc(char const * const, loc_t *);
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
*/
#if EFI_UART_GPS
#include "pch.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 "eficonsole.h"
#include "nmea.h"
@ -30,13 +28,15 @@ static THD_WORKING_AREA(gpsThreadStack, UTILITY_THREAD_STACK_SIZE);
// this field holds our current state
static loc_t GPSdata;
static efidatetime_t lastDateTime;
static int gpsMesagesCount = 0;
static int gpsMessageCount = 0;
static int uartErrors = 0;
// todo: some data structure for coordinates location
// todo:
// TODO: some data structure for coordinates location
float getCurrentSpeed(void) {
// TODO: ???
return GPSdata.speed;
}
@ -44,28 +44,27 @@ static void printGpsInfo() {
efiPrintf("GPS RX %s", hwPortname(engineConfiguration->gps_rx_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;
efiPrintf("communication speed: %.2f", gpsMesagesCount / sec);
efiPrintf("communication speed: %.2f", gpsMessageCount / sec);
efiPrintf("GPS latitude = %.2f\r\n", GPSdata.latitude);
efiPrintf("GPS longitude = %.2f\r\n", GPSdata.longitude);
}
static struct tm curTm;
static void onGpsMessage(char *buffer) {
static void onGpsMessage(const char * const 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) {
// quality =4 (valis GxRMC), year > 0, and difference more then second
date_set_tm(&GPSdata.GPStm); // set GPS time
//}
if (GPSdata.quality == 4 && GPSdata.time.year > 0) {
getRtcDateTime(&lastDateTime);
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?
@ -116,4 +115,4 @@ void initGps(void) {
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);
// ASSERT_EQ( 0, GPSdata.altitude) << "3 altitude"; // GPRMC not overwrite altitude
ASSERT_EQ( 0, GPSdata.course) << "3 course";
ASSERT_EQ( 2006, GPSdata.GPStm.tm_year + 1900) << "3 GPS yy";
ASSERT_EQ( 12, GPSdata.GPStm.tm_mon) << "3 GPS mm";
ASSERT_EQ( 26, GPSdata.GPStm.tm_mday) << "3 GPS dd";
ASSERT_EQ( 11, GPSdata.GPStm.tm_hour) << "3 GPS hh";
ASSERT_EQ( 16, GPSdata.GPStm.tm_min) << "3 GPS mm";
ASSERT_EQ( 9, GPSdata.GPStm.tm_sec) << "3 GPS ss";
ASSERT_EQ( 2006, GPSdata.time.year + 1900) << "3 GPS yy";
ASSERT_EQ( 12, GPSdata.time.month) << "3 GPS mm";
ASSERT_EQ( 26, GPSdata.time.day) << "3 GPS dd";
ASSERT_EQ( 11, GPSdata.time.hour) << "3 GPS hh";
ASSERT_EQ( 16, GPSdata.time.minute) << "3 GPS mm";
ASSERT_EQ( 9, GPSdata.time.second) << "3 GPS ss";
// check again first one
// we need to pass a mutable string, not a constant because the parser would be modifying the string