Memory leak in Argon doing WiFi.off() / WiFi.on() and Boron doing Cellular.off() / Cellular.on()

I'm trying to test a firmware which should use as little power as possible, and have experimented with shutting off Wifi during Sleep, since the Wifi module draws a huge amount of current while the particle is sleeping.

using this code

/*
 * Project TestApp
 * Description: Firmware for TestApp to catch bug
 * Author: Kristofer Liew, AppCentric
 * Date: 190506
 */

#include "application.h"
#include "TestApp.h"

// Define Threading
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(MANUAL);

SerialLogHandler serialLog;

/**
* Declaring the variables.
*/
#define CALLBACK_PERIOD 2 // minutes

unsigned int nextTime = 0; // Next time to contact the server
unsigned int lastTime = 0; // last time processed
constexpr char *APPNAME = "TestApp";

float voltage = 0.0;
float soC = 0.0;
uint16_t Input1 = D2;
uint16_t Input2 = D3;

//
// Used instead of delay() in order to not block processing
//
inline void softDelay(uint32_t t)
{
  for (uint32_t ms = millis(); millis() - ms < t; Particle.process())
    ;
}

// setup() runs once, when the device is first turned on.
void setup()
{
  softDelay(5000);
  Serial.begin();
  // Put initialization like pinMode and begin functions here.
  Log.info("Setup Started");
  Particle.connect();
  if (waitFor(Particle.connected, 30000))
  {
    Log.info("Cloud connected");
  }
  else
  {
    Log.error("Failed Cloud connect");
  }
  pinMode(Input1, INPUT_PULLUP);
  pinMode(Input2, INPUT_PULLUP);
  Log.info("Setup Reporting to cloud");

  Particle.publish(APPNAME, "Device started", PRIVATE);
  Log.info("Setup Finished");
}

// loop() runs over and over again, as quickly as it can execute.
void loop()
{
  // The core of your code will likely live here.
  if ((nextTime > millis()))
  {
    return;
  }
  Log.info("In Loop, Status");
  WiFi.on();
  softDelay(2000);

  GetBatteryStatus();
  SetNextPeriod();
  bool success = PublishAlive();
  if (!success)
  {
    Log.error("Failed to publish status");
  }
  softDelay(1000);
  WiFi.off();
  softDelay(2000);
  System.sleep({Input1, Input2}, CHANGE, (CALLBACK_PERIOD * 3));
}

//
// Set next wakeup period
//
void SetNextPeriod()
{
  lastTime = millis();
  nextTime = lastTime + (CALLBACK_PERIOD * 5000);
}

bool PublishAlive()
{
  // if (CommunicationsOn())
  bool success = false;
  Log.info("Publish to Particle");
  if (!waitFor(Particle.connected, 30000))
  {
    Log.info("Cloud not connected");
    return success;
  }
  Log.info("Publishing ..");
  success = Particle.publish(APPNAME, "Hi", PRIVATE);
  Log.info("Publish to particle done");
  //  CommunicationsOff();
  return success;
}

void GetBatteryStatus()
{
#if PLATFORM_ID == 12 // Argon
  voltage = analogRead(BATT) * 0.0011224;
#elif PLATFORM_ID == 13 // Boron
  voltage = fuel.getVCell();
  soC = fuel.getSoC();
#endif
}

The loop leaks about 5 kb of ram on each iteration and will stop communicating after a few turnarounds. Removing WiFi.off()/WiFi.on() from the main loop keeps the firmware running.

Logging returns

0003289511 [gsm0710muxer] INFO: Starting GSM07.10 muxer
0003289511 [hal] ERROR: Failed to perform early initialization

I am running firmware version 1.1.0-rc.2 and has also tested with 1.2.0-beta.1

I haven’t read it myself since I don’t use WiFi modules, but if you search for WiFi.on or something similar you’ll see a recent thread that talks about this memory leak. Sorry I don’t remember which thread it’s in. I think it might be in a thread just called “memory management”.

I have now checked the behavior on Boron and its alost identical to the one on the Argon. After a few iterations i get

0002683252 [hal] ERROR: Failed to perform early initialization
0002695802 [hal] ERROR: Failed to power off modem
0002704428 [hal] ERROR: Failed to perform early initialization

so the problem is not related to WiFi only but with Cellular models as well.

What is in the #include “TestApp.h”? I have a similar problem and would like to see if I can reproduce.

Many thanks for your post & observations!

_Todd

TestApp.h contains the declarations

void setup();
bool PublishAlive();
void loop();
void SetNextPeriod();
void GetBatteryStatus();
1 Like

We have now found that by adding a long delay (15 seconds) after shutting off the WiFi (Cellular) the memory leek disappears. We are currently running 1.3.0-rc1

This issue should be resolved in 1.3.1-rc.1: https://github.com/particle-iot/device-os/pull/1862.

1 Like