Browse Source

sensors: fix millis() rollover stall in GPS time-sync + minor cleanups

next_check and next_gps_update stored a future millis() value in a signed
long and compared with a naive '>'. After the ~24.8-day millis() sign flip
the deadline sits above the wrapped millis(), so the block never runs again
and GPS->RTC time-sync (and the location cache refresh) stall permanently
until reboot. Switch to unsigned deadlines with the wrap-safe signed-
difference compare '(long)(millis() - deadline) > 0', matching the idiom in
Dispatcher::millisHasNowPassed.

Also: reorder the MicroNMEALocationProvider ctor init-list to declaration
order (silences -Wreorder) and drop the always-true 'if (_claims > 0)' guard
in claim() (claim() always runs after _claims++, so it is >= 1).
pull/2937/head
Jody Bentley 1 week ago
parent
commit
63731d3fbf
  1. 4
      src/helpers/sensors/EnvironmentSensorManager.cpp
  2. 10
      src/helpers/sensors/MicroNMEALocationProvider.h

4
src/helpers/sensors/EnvironmentSensorManager.cpp

@ -889,11 +889,11 @@ void EnvironmentSensorManager::stop_gps() {
void EnvironmentSensorManager::loop() { void EnvironmentSensorManager::loop() {
#if ENV_INCLUDE_GPS #if ENV_INCLUDE_GPS
static long next_gps_update = 0; static unsigned long next_gps_update = 0;
if (gps_active) { if (gps_active) {
_location->loop(); _location->loop();
} }
if (millis() > next_gps_update) { if ((long)(millis() - next_gps_update) > 0) {
if(gps_active){ if(gps_active){
#ifdef RAK_WISBLOCK_GPS #ifdef RAK_WISBLOCK_GPS

10
src/helpers/sensors/MicroNMEALocationProvider.h

@ -42,14 +42,14 @@ class MicroNMEALocationProvider : public LocationProvider {
int8_t _claims = 0; int8_t _claims = 0;
int _pin_reset; int _pin_reset;
int _pin_en; int _pin_en;
long next_check = 0; unsigned long next_check = 0;
long time_valid = 0; long time_valid = 0;
unsigned long _last_time_sync = 0; unsigned long _last_time_sync = 0;
static const unsigned long TIME_SYNC_INTERVAL = 1800000; // Re-sync every 30 minutes static const unsigned long TIME_SYNC_INTERVAL = 1800000; // Re-sync every 30 minutes
public : public :
MicroNMEALocationProvider(Stream& ser, mesh::RTCClock* clock = NULL, int pin_reset = GPS_RESET, int pin_en = GPS_EN,RefCountedDigitalPin* peripher_power=NULL) : MicroNMEALocationProvider(Stream& ser, mesh::RTCClock* clock = NULL, int pin_reset = GPS_RESET, int pin_en = GPS_EN,RefCountedDigitalPin* peripher_power=NULL) :
_gps_serial(&ser), nmea(_nmeaBuffer, sizeof(_nmeaBuffer)), _pin_reset(pin_reset), _pin_en(pin_en), _clock(clock), _peripher_power(peripher_power) { nmea(_nmeaBuffer, sizeof(_nmeaBuffer)), _clock(clock), _gps_serial(&ser), _peripher_power(peripher_power), _pin_reset(pin_reset), _pin_en(pin_en) {
if (_pin_reset != -1) { if (_pin_reset != -1) {
pinMode(_pin_reset, OUTPUT); pinMode(_pin_reset, OUTPUT);
digitalWrite(_pin_reset, GPS_RESET_FORCE); digitalWrite(_pin_reset, GPS_RESET_FORCE);
@ -62,9 +62,7 @@ public :
void claim() { void claim() {
_claims++; _claims++;
if (_claims > 0) { if (_peripher_power) _peripher_power->claim();
if (_peripher_power) _peripher_power->claim();
}
} }
void release() { void release() {
@ -143,7 +141,7 @@ public :
if (!isValid()) time_valid = 0; if (!isValid()) time_valid = 0;
if (millis() > next_check) { if ((long)(millis() - next_check) > 0) {
next_check = millis() + 1000; next_check = millis() + 1000;
// Re-enable time sync periodically when GPS has valid fix // Re-enable time sync periodically when GPS has valid fix
if (!_time_sync_needed && _clock != NULL && (millis() - _last_time_sync) > TIME_SYNC_INTERVAL) { if (!_time_sync_needed && _clock != NULL && (millis() - _last_time_sync) > TIME_SYNC_INTERVAL) {

Loading…
Cancel
Save