FreeRTOS Timers - Dispose() - 0.4.7 vs 0.4.9

Quick report to inform that there might be a bug in the FreeRTOS timer dispose() method under firmware 0.4.9.

With 0.4.9, calling dispose on one timer stops other timers too, whereas when building the same code against 0.4.7 (but with 0.4.9 loaded on the Photon), it operates as expected, ie stopping the indicated timer only.

If you find something you suspect to be a bug (and have tested well enough ;-)), you might want to open an issue on GitHub
https://github.com/spark/firmware/issues

Best with your test code included in the description.

This will ensure that the Particle dev team will be notified and can get to the bottom of it quicker.

@ScruffR, got it, will cut some test code over the next few weeks.

Work around was simple - just called stop() and did not bother disposing.

1 Like

@ScruffR, here is the code that reproduces the fault. The comments at the top of the code says it all.

Not sure if I should post this to Pull requests · particle-iot/device-os · GitHub as I don't know if calling dispose() within the timer callback is recommended or good practice. Let me know.

When it is called in loop(), dispose() works as expected for both 0.4.7 and 0.4.9, ie it only stops the timer it is meant to, not all timers.

/*
Debug of FREERTOS Timer dispose() method
on v0.4.7 vs v0.4.9 firmware

Firmware v0.4.9 loaded, but COMPILED against v0.4.7
Firmware version 0.4.9
010010010010010
Calling timer0.dispose()
111111111111111111111111111111111111111111111111111111111111111111111
Firmware v0.4.9 loaded, and COMPILED against v0.4.9
Firmware version 0.4.9
010010010010010
Calling timer0.dispose()

*/

SYSTEM_THREAD(ENABLED);

Timer timer0(100, timer0Callback);
Timer timer1(200, timer1Callback);

int led = D7;

int count = 0;

void setup()
{
pinMode(led, OUTPUT);

Serial.begin(9600L);
Serial.printlnf("Firmware version %s", System.version().c_str());
timer0.start();
timer1.start();

}

void loop()
{
digitalWrite(led, HIGH);
delay(1000L);
digitalWrite(led, LOW);
delay(1000L);

}

void timer0Callback(void)
{
Serial.print("0");

if (++count == 10)
{
    Serial.printlnf("\r\nCalling timer0.dispose()");
    timer0.dispose();   // only expect timer0 to stop
}

}

void timer1Callback(void)
{
Serial.print("1");
}

I wouldn’t call “self-dispose” from “inside” an object, but this would be best answered by @mdma.

@UMD, I agree with @ScruffR. You should be calling timer0.stop() to stop the timer. You can dispose of it in loop() if you need to reclaim one of the 10 timer “slots”. :wink:

1 Like

@ScruffR, @peekay, some background.

Was only doing this originally because there was no optional "one_shot" flag in the instantiation of the timer prior to 0.4.9.

The thinking of using dispose() was - "Am finished with the timer, never going to use it again, so I might as well dispose of it." How do you know when the timer is finished? Answer - In the call back.

Thinking that the use case I mention isn't that far wrong? What happens if you had 10 one shot timers and once finished with them, wanted to go on to use other timers?

Doco says:

dispose()
Stop and remove a timer from the (max. 10) timer list, freeing a timer "slot" in the list.

Sounds like you are saying that this line should be added to the doco:

Not to be called in timer callback.

but this was not an issue with 0.4.7.

Anyhow, case closed from my perspective!

1 Like