2.0.1 reset with libs PublishQueueAsyncRK and MB85RC256V-FRAM-RK

As a showstopper for a new product, the minimal code example below freezes 30 secs after going online.

It does this on both B523 product HW , B SOM evaluation board (B523), and an Argon (change watchdog pin to unused pin). All running OS2.0.1 and connected to an FRAM (Adafruit for the dev boards).

Building with the Web IDE with MB85RC256V-FRAM-RK (0.0.5), PublishQueueAsyncRK (0.2.0) and for OS 2.0.1 it resets. Building for OS1.5.2 and uploading to OS2.0.1 devices all is well.

I have tried retained memory instead, on the product HW and it does the same: Reset when built for 1.5.2 and ok when built for 2.0.1, and in both cases uploaded to 2.0.1 devices.

In a trace the last thing that happens is PublishQueueAsyncRK is storing the data.

Hoping someone can spot a bug or knows of a work-around for 2.0.1?

#include <MB85RC256V-FRAM-RK.h>
#include <PublishQueueAsyncRK.h>

SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED);

SerialLogHandler logHandler;

MB85RC512 fram(Wire, 0);

//    retained uint8_t publishQueueRetainedBuffer[2048]; // Out of 3068 bytes total
//    PublishQueueAsync publishQueue(publishQueueRetainedBuffer, sizeof(publishQueueRetainedBuffer));
PublishQueueAsyncFRAM publishQueue(fram, 8192, 16383); 
//PublishQueueAsyncFRAM publishQueue(fram, 0, 8192);

static char buf[620]; // Particle.publish data (up to 255 characters (prior to 0.8.0), 622 characters (since 0.8.0))
static unsigned long lastUploadTime = 0;

const pin_t WATCHDOG_PIN = D22; 

void setup() {

    pinMode(WATCHDOG_PIN, OUTPUT);

    fram.begin();
    
	publishQueue.setup();			
	publishQueue.setPausePublishing(true);
	
	Particle.process();
    Particle.connect();
}

 
void loop() { 
    
    if (Particle.connected() && Time.isValid()){}
    else lastUploadTime = millis();
    
    if (((millis() - lastUploadTime) >= 30*1000)) UpdateServer();

    digitalWrite(WATCHDOG_PIN, !digitalRead(WATCHDOG_PIN));
}



int UpdateServer(void){
    Log.trace("UpdateServer()");

    snprintf(buf, sizeof(buf), "{\"T\":\"2021-02-02T12:51:03Z\",\"R\":-72,\"I\":60,\"D\":\"{}\"}");
    publishQueue.publish("HLP1up", buf, 60, PRIVATE, WITH_ACK);
}


I tested this using those libraries, in Workbench, using the B404 evaluation board and a MB85RC64 FRAM.

While I did not get a freeze, I got an SOS+1 hard fault 30 seconds after the cloud connection was established.

int UpdateServer(void){
    Log.trace("UpdateServer()");

    snprintf(buf, sizeof(buf), "{\"T\":\"2021-02-02T12:51:03Z\",\"R\":-72,\"I\":60,\"D\":\"{}\"}");
    publishQueue.publish("HLP1up", buf, 60, PRIVATE, WITH_ACK);

    return 0;  // <-- this was missing
}

The reason for the SOS is that the gcc 9.2.1 compiler is really picky about missing return values for functions. Adding a return statement makes the SOS go away. Since gcc 9.2.1 is only used in 2.0.0rc and later, this is why the problem only shows up when targeting that version.

Also, there’s a bug in this block of code:

if (Particle.connected() && Time.isValid()) {
    // do nothing
}
else {
    lastUploadTime = millis();
}

Once you’ve connected to the cloud and the time is valid, lastUploadTime is never updated and UpdateServer will be called on every loop, causing the FRAM to fill up.

2 Likes

Thank you, works. Oh boy, I can imagine that is going to trip up a lot of updates.

1 Like

Fixed the title to “reset”.

Poor coding practices will eventually bite one in the butt - hence never adopt them in the first place :wink:

That is especially true with the new compiler version :wink:

It was actually an oversight - the function output was supposed to be void, as there is no use for it.

It is also true that the last platform I worked with, I got an error when building code with such an obvious discrepancy (once you notice it) :slightly_smiling_face:

1 Like