Functions not registered after Device OS update

Hello,

After updating my 0.7.0 Electron Device OS by installing a firmware requiring a 1.4.4 Device OS. The cloud functions are not registered. After multiple flash status messages the Electron comes online, but does not register the functions. The functions are registered first in the setup method. Should I always use SYSTEM_MODE(SEMI_AUTOMATIC); as described here: https://docs.particle.io/reference/device-os/firmware/electron/#optimizing-cellular-data-use-with-cloud-connectivity-on-the-electron

Thanks!

I forgot to mention, after a power cycle the functions appear. No problem for debugging, but I want to deploy this firmware to the field and I do not have physical access to the devices.

@tompesman, can you share your code, at least the parts before and leading up to the function registrations?

That’s easy:

void setup()
{
  // setup Particle
  Particle.function("open", openLock);
  Particle.function("state", publishState);
  Particle.function("mute-enabled", muteEnabled);
  Particle.function("mute-disabled", muteDisabled);
  Particle.function("mute-state", muteState);
  Particle.function("locate", locate);

  Serial.begin(115200);
  setupBoard();
  sendHello();

  // locate device
  locator.withSubscribe(locationCallback).withLocateOnce();
}

@tompesman, can you share the code before setup() showing the included files, etc.?

That’s a bit harder, because it’s split up in separate files :wink:

I’ve reconstructed the parts executed before the setup().

#include <google-maps-device-locator.h>
#include "spark_wiring_i2c.h"
#include "spark_wiring_usbserial.h"
#include "spark_wiring_constants.h"

PRODUCT_ID(xx);
PRODUCT_VERSION(xx);

SerialLogHandler logHandler(LOG_LEVEL_NONE);

Board board;
GoogleMapsDeviceLocator locator;
unsigned int lockStatusData;

#define MAX_LOCKS 4
Lock locks[MAX_LOCKS] = {
    Lock(1, board),
    Lock(2, board),
    Lock(3, board),
    Lock(4, board),
};

unsigned long lastSync = millis();

The Lock initializer is just an assignment of a few int’s and an assignment of millis().

I find the most interesting thing that the problem is only there after a Device OS update.

Thanks :slight_smile:

Why do you need to be including these?

#include "Particle.h"
is typically sufficient at the start of the application.

Hi @armor,

Thank you for your reply!

It’s a leftover from this repo: https://github.com/ControlEverythingCom/NCD8Relay

I’ve removed the three lines, cleaned and recompiled, but this generates the same binary. I don’t think this makes any difference.

Cheers!

Particle.function(“open”, openLock);
Particle.function(“state”, publishState);
Particle.function(“mute-enabled”, muteEnabled);
Particle.function(“mute-disabled”, muteDisabled);
Particle.function(“mute-state”, muteState);
Particle.function(“locate”, locate);

I think what we are after seeing is the function handler forward declarations and definitions for each of above. For example;

int openLock(const char * command); //forward declaration for openLock function handler

and

int openLock(const char * command)
{
/* your command handler */
return 0;
}

Can you run particle serial inspect (in Listening Mode) to see whether the upgrade actually completed successfully?
Can you also re-flash your application (with a very minor alteration) and run particle serial inspect again to compare the app hash between the two logs?

Since I couldn’t see anything wrong with your code snippets I’m inclinde to think you are not successfully flashing your application.

More questions

  • What IDE are you using?
  • How are you flashing?
  • Have you marked that device as developer device?
  • Is it maybe firmware locked?
  • How does that code behave on a non-product device?
  • Can you flash a minimal test application (e.g. Blink an LED with your Particle.function() block) to that device to see if anything works?

Besides what @ScruffR asked for, you may have an object creation problem as the order of creation and initialization of classes is not necessarily sequential. The reference to board may not be correct when you define locks[]. This is why it is usually recommended that classes have a begin() method that is called in setup() to avoid this problem.

@armor, @ScruffR and @peekay123

Thank you all for replying!

@ScruffR I can verify the flash was successful because after a power cycle the new functions appear and are working as expected. Therefore I’ve tried @peekay123 fix. It looks like this is the problem. The functions do appear after a flash. But after a few tests it didn’t happened less, but it sometimes still boots up without registering the functions.

And another thing I’m noticing right now is my firmware v1 (my previous version, which ran in 0.7.0) is also missing the functions after a downgrade of the firmware (v5 -> v1), . I’m thinking something has changed in the Device OS bootup sequence.

I’ve added the SYSTEM_MODE(SEMI_AUTOMATIC); and the Particle.connect(); after the Particle.function calls and I can not break it anymore.

Some answers to @ScruffR’s questions:

  • IDE: VS code
  • Cloud flash from VS code and by installing firmwares in a product
  • Tried it with and without
  • I locked different firmwares to simulate upgrading (where it fails)
  • Have not tried it yet
  • Have not tried it yet

One thing I’ve noticed during the OTA-flashing of a firmware is that the green blinking phase is completely skipped. So I’m thinking that the Electron is sometimes so fast in connecting to the Particle cloud that it is already connected before the setup() function is called. Therefore skipping the Particle.function() calls? Is that even possible?