Ticker only works if declared globally

Hi!

I’m not sure if this is a bug or if things are supposed to work this way - if they are, the documentation should definitely be more clear.

Basically, when declaring a ticker object inside of main, it does not work. I made a simple program to demonstrate what I mean: in the code below, LED2 will flash while LED1 will not. The behavior is the same if I switch them - basically, the ticker declared in global scope works while the one declared locally doesn’t. Why is that the case?

The below code was run on a NUCLEO-H743ZI2, compiled with arm-none-eabi-g++ (15:9-2019-q4-0ubuntu1) 9.2.1 and MBed OS 6.1.0 stable.

Code:


#include <mbed.h>

// setup
DigitalOut led1(LED1);
DigitalOut led2(LED2);

void led1Callback() {
    led1 = !led1;
}

void led2Callback() {
    led2 = !led2;
}

// real test

Ticker tickerG;

int main() {

    Ticker tickerL;

    tickerL.attach(callback(&led2Callback), 1); // doesn't work
    tickerG.attach(callback(&led1Callback), 1); // works

}
1 Like

Try adding:
while(1) ThisThread::sleep_for(1s);
to the end of your main function.

When you reach then end of main, the function returns and tickerL is destructed in the process, hence it never gets a chance to trigger.
tickerG is global, so it’s never destructed, and hence still exists to keep on working.

It looks like a scoping problem to me. The code you posted works fine on one of my boards if you prevent main from exiting (hence keeping tickerL in scope, alongside tickerG).

What programs do on exiting main can be platform specific. Some micros will just reset, but I believe MBED enters an infinite loop, which allows interrupt based object (like Ticker) to keep working in the background.

Regards,
Tom

2 Likes

This makes a lot of sense, thank you!