sparkfun / SparkFun_u-blox_GNSS_Arduino_Library

An Arduino library which allows you to communicate seamlessly with the full range of u-blox GNSS modules
Other
225 stars 99 forks source link

GNSS Stack Overflow error on v2.2.9 #138

Closed ricozinn closed 2 years ago

ricozinn commented 2 years ago

Subject of the issue

If I run the GNSS library version 2.2.9 I get a stack overflow with the code below that I never get using version 2.0.15.

Here's the MbedOS error: 11:22:24.344 -> 11:22:24.344 -> 11:22:24.344 -> ++ MbedOS Error Info ++ 11:22:24.344 -> Error Status: 0x80020125 Code: 293 Module: 2 11:22:24.344 -> Error Message: CMSIS-RTOS error: Stack overflow 11:22:24.344 -> Location: 0x2E1E3 11:22:24.344 -> Error Value: 0x1 11:22:24.344 -> Current Thread: main Id: 0x10004F40 Entry: 0x2E07D StackSize: 0x1000 StackMem: 0x10006BB0 SP: 0x1005FEEC 11:22:24.344 -> For more info, visit: https://mbed.com/s/error?error=0x80020125&tgt=SFE_ARTEMIS_ATP 11:22:24.344 -> -- MbedOS Error Info --

Your workbench

HARDWARE/LIBRARY SETUP... use the artemis red board hardware and the following libraries. I only connect the GNSS module using the qwiic wire and nothing else. The code and setup is as minimal as I could get it and still cause the stack overflow to occur quickly.

//https://github.com/sparkfun/Arduino_Apollo3/releases/tag/v2.2.1//https://github.com/sparkfun/Arduino_Apollo3/releases/tag/v2.2.1 use v2.2.1 of the Apollo3 board

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/releases use version 2.2.9 of the GNSS library

https://github.com/arduino-libraries/ArduinoBLE/releases use version 1.2.2 of the ArduinoBLE library

Steps to reproduce

To test, run the sketch, and use a mobile app like "Light Blue" (free in the app store), connect to the peripheral, and turn on notifications of the custom "testChar" BLE characteristic (the one with the long UUID)

Expected behavior

You should see the stack overflow somewhere in the first 5 to 300 seconds. If using the same code I go back to version 2.0.15 of the GNSS library you will never see it even after running for hours.

/*
 * HARDWARE/LIBRARY SETUP...
 * use the artemis red board hardware and the following libraries.  I only connect the GNSS module using the qwiic wire and nothing else.  The code and setup is as minimal as I could get it and still cause the stack overflow to occur quickly. 
 * 
 * //https://github.com/sparkfun/Arduino_Apollo3/releases/tag/v2.2.1//https://github.com/sparkfun/Arduino_Apollo3/releases/tag/v2.2.1
 * use v2.2.1 of the Apollo3 board
 * 
 * https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/releases
 * use version 2.2.9 of the GNSS library
 * 
 * https://github.com/arduino-libraries/ArduinoBLE/releases
 * use version 1.2.2 of the ArduinoBLE library
 * 
 * TO TEST...
 * To test, run the sketch, and use a mobile app like "Light Blue" (free in the app store), connect to the peripheral, 
 * and turn on notifications of the custom "testChar" BLE characteristic (the one with the long UUID)
 * 
 * You should see the stack overflow somewhere in the first 5 to 200 seconds.  If using the same code I go back to version 2.0.15 
 * of the GNSS library you will never see it even after running for hours.
 * 
 */

#include <ArduinoBLE.h>

const byte PIN_QWIIC_POWER = 18;
const byte PIN_QWIIC_SCL = 8;
const byte PIN_QWIIC_SDA = 9;

#include <Wire.h> //Needed for I2C to GPS
TwoWire qwiic(PIN_QWIIC_SDA, PIN_QWIIC_SCL); //Will use pads 8/9

#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
SFE_UBLOX_GNSS myGNSS;

rtos::Thread thread;  // https://os.mbed.com/docs/mbed-os/v6.2/apis/thread.html
uint32_t counter = 0;
BLEService                  testService("f5b64b90-14ed-0000-82a8-0242ac130093");
BLECharacteristic             testChar ("f5b64b90-14ed-11ec-0000-0242ac130000", BLENotify, 255);
BLEService batteryService("180F");
BLEUnsignedCharCharacteristic batteryLevelChar("2A19", BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

// Callback: printPVTdata will be called when new NAV PVT data arrives
// See u-blox_structs.h for the full definition of UBX_NAV_PVT_data_t
//         _____  You can use any name you like for the callback. Use the same name when you call setAutoPVTcallback
//        /                  _____  This _must_ be UBX_NAV_PVT_data_t
//        |                 /               _____ You can use any name you like for the struct
//        |                 |              /
//        |                 |              |
void printPVTdata(UBX_NAV_PVT_data_t *ubxDataStruct)
{
    Serial.println();

    uint8_t valid = ubxDataStruct->valid.all;
    Serial.print(F("TEST 2... Time: ")); // Print the time
    uint8_t hms = ubxDataStruct->hour; // Print the hours
    if (hms < 10) Serial.print(F("0")); // Print a leading zero if required
    Serial.print(hms);
    Serial.print(F(":"));
    hms = ubxDataStruct->min; // Print the minutes
    if (hms < 10) Serial.print(F("0")); // Print a leading zero if required
    Serial.print(hms);
    Serial.print(F(":"));
    hms = ubxDataStruct->sec; // Print the seconds
    if (hms < 10) Serial.print(F("0")); // Print a leading zero if required
    Serial.print(hms);
    Serial.print(F("."));
    unsigned long millisecs = ubxDataStruct->iTOW % 1000; // Print the milliseconds
    if (millisecs < 100) Serial.print(F("0")); // Print the trailing zeros correctly
    if (millisecs < 10) Serial.print(F("0"));
    Serial.print(millisecs);

    long latitude = ubxDataStruct->lat; // Print the latitude
    Serial.print(F(" Lat: "));
    Serial.print(latitude);

    long longitude = ubxDataStruct->lon; // Print the longitude
    Serial.print(F(" Long: "));
    Serial.print(longitude);
    Serial.print(F(" (degrees * 10^-7)"));

    long altitude = ubxDataStruct->hMSL; // Print the height above mean sea level
    Serial.print(F(" Height above MSL: "));
    Serial.print(altitude);
    Serial.println(F(" (mm)"));

    if(BLE.connected() && testChar.subscribed()){
      testChar.writeValue("reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreally long",239, false );
    }
}

void setup()
{
  pinMode(PIN_QWIIC_POWER, OUTPUT);
  pin_config(PinName(PIN_QWIIC_POWER), g_AM_HAL_GPIO_OUTPUT); // Make sure the pin does actually get re-configured
  digitalWrite(PIN_QWIIC_POWER, HIGH);

  delay(10);
  qwiic.begin();
  qwiic.setClock(AM_HAL_IOM_400KHZ);

  delay(1000);
  am_hal_gpio_pincfg_t sclPinCfg = g_AM_BSP_GPIO_IOM1_SCL;
  am_hal_gpio_pincfg_t sdaPinCfg = g_AM_BSP_GPIO_IOM1_SDA;
  sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; // No pull-ups
  sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE;
  pin_config(PinName(PIN_QWIIC_SCL), sclPinCfg);
  pin_config(PinName(PIN_QWIIC_SDA), sdaPinCfg);

  //myGNSS.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial

  Serial.begin(500000);
  while (!Serial); //Wait for user to open terminal
  Serial.println("SparkFun u-blox Example 2");

  if (myGNSS.begin(qwiic, 0x42) == false) //Connect to the u-blox module using Wire port
  {
    Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
    while (1);
  }

  myGNSS.setUART1Output(0);
  myGNSS.setUART2Output(0);
  myGNSS.setUSBOutput(0);
  myGNSS.setSPIOutput(0);
  //myGNSS.enableDebugging();
  myGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
  myGNSS.setAutoPVT(true);//, false);//nodeSetting->useAutoPVT); // Use autoPVT as required
  myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save (only) the communications port settings to flash and BBR
  myGNSS.setNavigationFrequency(2); //Produce two solutions per second
  myGNSS.setAutoPVTcallbackPtr(&printPVTdata); // Enable automatic NAV PVT messages with callback to printPVTdata

  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }
  BLE.setLocalName("LP Test");
  BLE.setDeviceName("LP Test");
  BLE.setConnectionInterval(6, 12); // 7.5 ms minimum, 4 s maximum... increments of 1.25ms (6=7.5ms and 12=15ms)

  batteryService.addCharacteristic(batteryLevelChar);
  BLE.addService(batteryService); // Add the battery service  
  testService.addCharacteristic(testChar);
  BLE.addService(testService);
  BLE.setAdvertisedService(testService);
  BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
  BLE.advertise();

  thread.start(thread_fn);          // assign thread_fn to the object thread and begin execution
}

void blePeripheralDisconnectHandler(BLEDevice device) {
  Serial.print("Disconnected event, device: ");
  Serial.println(device.address());
  BLE.advertise();
}

void thread_fn( void ){             // create a function to run as a thread

  while(1){
    rtos::ThisThread::sleep_for(10);    // equivalent to calling "delay()"
    counter++;
  }

}

void loop()
{
  myGNSS.checkUblox(); // Check for the arrival of new data and process it.
  myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed.

  if(BLE.connected() && batteryLevelChar.subscribed() && counter % 100 == 0){
    batteryLevelChar.writeValue(100);
  }

}
PaulZC commented 2 years ago

Hi Richard (@ricozinn ),

Thanks for reporting. I will look at this as soon as I can. (It’s Easter weekend here - two public holidays.)

Quick question: what happens if you comment the testChar.writeValue in the callback?

It seems evident that the stack usage has increased from 2.0.15, but I wonder if you’re just trying to do too much inside the callback? You may need to restructure your code so the writeValue is done from the main loop instead?

Best wishes, Paul

ricozinn commented 2 years ago

Thanks @PaulZC, I'm trying your suggestion now to move the testChar.writeValue in to the main loop and will let that run for a few hours and if it works then rework my app and see how it goes for even longer tests.

To answer your other question, commenting out the testChar.writeValue would make it at least difficult to see the crash - or maybe impossible. I think you are probably on the right track with your suggestion.

I'm close to an hour now in to this test and still going good!

PaulZC commented 2 years ago

Thanks Richard,

I'll give you some pointers on how to access the callback data from the main loop. Hopefully tomorrow. It can be done. You don't need to copy the data out of the callback to pass it back to the main loop.

ricozinn commented 2 years ago

Was just working on how I'd do that... so I'll wait instead. Thanks!

PaulZC commented 2 years ago

Hi Richard,

I've added a new example showing how to use the callback data from the main loop. This was something that @nseidle wanted to know how to do too. So I'm killing two birds with one stone!

The new example is in the release_candidate branch. I'll merge it into the main branch in the next release.

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/release_candidate/examples/Callbacks/CallbackExample9_UseCallbackDataInLoop/CallbackExample9_UseCallbackDataInLoop.ino

If this allows you to cure your overflow error, can you please close this issue? Happy to discuss further as required.

Enjoy! Paul

ricozinn commented 2 years ago

Thanks Paul! I'll give this a shot

On Fri, Apr 15, 2022 at 3:10 AM Paul @.***> wrote:

Hi Richard,

I've added a new example showing how to use the callback data from the main loop. This was something that @nseidle https://github.com/nseidle wanted to know how to do too. So I'm killing two birds with one stone!

The new example is in the release_candidate branch. I'll merge it into the main branch in the next release.

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/release_candidate/examples/Callbacks/CallbackExample9_UseCallbackDataInLoop/CallbackExample9_UseCallbackDataInLoop.ino

If this allows you to cure your overflow error, can you please close this issue? Happy to discuss further as required.

Enjoy! Paul

— Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/issues/138#issuecomment-1100015480, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANI7NOIHVQ3LU327D5PHD3VFE57VANCNFSM5TOR52SA . You are receiving this because you were mentioned.Message ID: <sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/issues/138/1100015480@ github.com>

ricozinn commented 2 years ago

Hey Paul, I've been putting this to its paces and seems to be performing well. I still am tracking down a MbedOS fault error that happens around one every 15 tests. I think it has to do though with calling BLE.begin() - so if that's the case then this is off topic of this thread. I didn't see it though when I switched to the new GNSS library. I wonder what the relationship could be here... Is there a way to use this fault info? I've done some googling but can't find anything arduino related. Thanks again.

13:02:48.586 -> ++ MbedOS Fault Handler ++ 13:02:48.586 -> 13:02:48.586 -> FaultType: HardFault 13:02:48.586 -> 13:02:48.586 -> Context: 13:02:48.586 -> R0: 0 13:02:48.586 -> R1: 2D011 13:02:48.586 -> R2: 100080F7 13:02:48.586 -> R3: 0 13:02:48.586 -> R4: 10009EC8 13:02:48.586 -> R5: 2D011 13:02:48.586 -> R6: 9 13:02:48.586 -> R7: 10009F28 13:02:48.586 -> R8: 3E8 13:02:48.586 -> R9: 10009F34 13:02:48.586 -> R10: 0 13:02:48.586 -> R11: 0 13:02:48.586 -> R12: 0 13:02:48.586 -> SP : 100100C0 13:02:48.586 -> LR : 3C60D 13:02:48.586 -> PC : 0 13:02:48.586 -> xPSR : 40000000 13:02:48.586 -> PSP : 100100A0 13:02:48.586 -> MSP : 1005FF70 13:02:48.586 -> CPUID: 410FC241 13:02:48.586 -> HFSR : 40000000 13:02:48.586 -> MMFSR: 0 13:02:48.586 -> BFSR : 0 13:02:48.586 -> UFSR : 2 13:02:48.586 -> DFSR : 0 13:02:48.586 -> AFSR : 0 13:02:48.586 -> Mode : Thread 13:02:48.586 -> Priv : Privileged 13:02:48.586 -> Stack: PSP 13:02:48.586 -> 13:02:48.586 -> -- MbedOS Fault Handler -- 13:02:48.586 -> 13:02:48.586 -> 13:02:48.586 -> 13:02:48.586 -> ++ MbedOS Error Info ++ 13:02:48.586 -> Error Status: 0x80FF013D Code: 317 Module: 255 13:02:48.586 -> Error Message: Fault exception 13:02:48.586 -> Location: 0x0 13:02:48.586 -> Error Value: 0x10009F38 13:02:48.586 -> Current Thread: application_unnamed_thread Id: 0x100101B8 Entry: 0x40289 StackSize: 0x1000 StackMem: 0x1000F138 SP: 0x100100C0 13:02:48.586 -> For more info, visit: https://mbed.com/s/error?error=0x80FF013D&tgt=SFE_ARTEMIS_ATP 13:02:48.586 -> -- MbedOS Error Info --

On Fri, Apr 15, 2022 at 6:25 AM Richard Zinn @.***> wrote:

Thanks Paul! I'll give this a shot

On Fri, Apr 15, 2022 at 3:10 AM Paul @.***> wrote:

Hi Richard,

I've added a new example showing how to use the callback data from the main loop. This was something that @nseidle https://github.com/nseidle wanted to know how to do too. So I'm killing two birds with one stone!

The new example is in the release_candidate branch. I'll merge it into the main branch in the next release.

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/release_candidate/examples/Callbacks/CallbackExample9_UseCallbackDataInLoop/CallbackExample9_UseCallbackDataInLoop.ino

If this allows you to cure your overflow error, can you please close this issue? Happy to discuss further as required.

Enjoy! Paul

— Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/issues/138#issuecomment-1100015480, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANI7NOIHVQ3LU327D5PHD3VFE57VANCNFSM5TOR52SA . You are receiving this because you were mentioned.Message ID: <sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/issues/138/1100015480@ github.com>

ricozinn commented 2 years ago

Quick update... Looks like this same problem is documented here along with a fix: https://github.com/arduino-libraries/ArduinoBLE/issues/192

Hopefully they bring that fix in to an official release soon.

On Wed, Apr 20, 2022 at 1:06 PM Richard Zinn @.***> wrote:

Hey Paul, I've been putting this to its paces and seems to be performing well. I still am tracking down a MbedOS fault error that happens around one every 15 tests. I think it has to do though with calling BLE.begin() - so if that's the case then this is off topic of this thread. I didn't see it though when I switched to the new GNSS library. I wonder what the relationship could be here... Is there a way to use this fault info? I've done some googling but can't find anything arduino related. Thanks again.

13:02:48.586 -> ++ MbedOS Fault Handler ++ 13:02:48.586 -> 13:02:48.586 -> FaultType: HardFault 13:02:48.586 -> 13:02:48.586 -> Context: 13:02:48.586 -> R0: 0 13:02:48.586 -> R1: 2D011 13:02:48.586 -> R2: 100080F7 13:02:48.586 -> R3: 0 13:02:48.586 -> R4: 10009EC8 13:02:48.586 -> R5: 2D011 13:02:48.586 -> R6: 9 13:02:48.586 -> R7: 10009F28 13:02:48.586 -> R8: 3E8 13:02:48.586 -> R9: 10009F34 13:02:48.586 -> R10: 0 13:02:48.586 -> R11: 0 13:02:48.586 -> R12: 0 13:02:48.586 -> SP : 100100C0 13:02:48.586 -> LR : 3C60D 13:02:48.586 -> PC : 0 13:02:48.586 -> xPSR : 40000000 13:02:48.586 -> PSP : 100100A0 13:02:48.586 -> MSP : 1005FF70 13:02:48.586 -> CPUID: 410FC241 13:02:48.586 -> HFSR : 40000000 13:02:48.586 -> MMFSR: 0 13:02:48.586 -> BFSR : 0 13:02:48.586 -> UFSR : 2 13:02:48.586 -> DFSR : 0 13:02:48.586 -> AFSR : 0 13:02:48.586 -> Mode : Thread 13:02:48.586 -> Priv : Privileged 13:02:48.586 -> Stack: PSP 13:02:48.586 -> 13:02:48.586 -> -- MbedOS Fault Handler -- 13:02:48.586 -> 13:02:48.586 -> 13:02:48.586 -> 13:02:48.586 -> ++ MbedOS Error Info ++ 13:02:48.586 -> Error Status: 0x80FF013D Code: 317 Module: 255 13:02:48.586 -> Error Message: Fault exception 13:02:48.586 -> Location: 0x0 13:02:48.586 -> Error Value: 0x10009F38 13:02:48.586 -> Current Thread: application_unnamed_thread Id: 0x100101B8 Entry: 0x40289 StackSize: 0x1000 StackMem: 0x1000F138 SP: 0x100100C0 13:02:48.586 -> For more info, visit: https://mbed.com/s/error?error=0x80FF013D&tgt=SFE_ARTEMIS_ATP 13:02:48.586 -> -- MbedOS Error Info --

On Fri, Apr 15, 2022 at 6:25 AM Richard Zinn @.***> wrote:

Thanks Paul! I'll give this a shot

On Fri, Apr 15, 2022 at 3:10 AM Paul @.***> wrote:

Hi Richard,

I've added a new example showing how to use the callback data from the main loop. This was something that @nseidle https://github.com/nseidle wanted to know how to do too. So I'm killing two birds with one stone!

The new example is in the release_candidate branch. I'll merge it into the main branch in the next release.

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/release_candidate/examples/Callbacks/CallbackExample9_UseCallbackDataInLoop/CallbackExample9_UseCallbackDataInLoop.ino

If this allows you to cure your overflow error, can you please close this issue? Happy to discuss further as required.

Enjoy! Paul

— Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/issues/138#issuecomment-1100015480, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANI7NOIHVQ3LU327D5PHD3VFE57VANCNFSM5TOR52SA . You are receiving this because you were mentioned.Message ID: <sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/issues/138/1100015480@ github.com>

PaulZC commented 2 years ago

Hi Richard,

If you're 'happy', can you please close this issue? Unless we can give you any more help?

Best wishes, Paul

ricozinn commented 2 years ago

Thanks Paul, I can get the sketch here to cause the crash within 30 seconds but it has nothing to do with the GNSS library apparently. I wish the ArduinoBLE team had a Paul ;) https://github.com/arduino-libraries/ArduinoBLE/issues/192

I'll close this thanks.