Arm Mbed OS support forum

Difference between ThisThread::sleep and wait

If I want to spin wait so that my zigbee can initialize without the OS switching to other thread, which one should I use? Thank you.

Hello Deng,

To wait in one thread by spinning the MCU, for example by calling the wait_us function, is not recommended for time periods of millisecond and longer. Read below the reason why.

By default, there are four threads running after boot:

  • the ISR/scheduler thread,
  • the idle thread,
  • the timer thread and
  • the main application thread.

RTOS, including Mbed OS, needs a mechanism for counting the time and scheduling tasks. A timer that generates periodic interrupts, called system tick timer, usually does this. Under Mbed OS, we call this mechanism the RTOS ticker. The RTOS ticker runs in the timer thread. Keeping the MCU to spin in one thread without enabling the other threads (including the timer thread) to run, by calling the wait_us function, can disrupt the RTOS ticker and consequently all the other RTOS functions depending on it.

One alternative is to use the ThisThread::sleep_for function in combination with EventFlags.
In the thread initializing the zigbeee call the ThisThread::sleep_forfunction. After the specified time elapsed set the EventFlags defined to keep the other threads waiting.

#include "mbed.h"

#define ZIGBEE_FLAG1    (1UL << 0)  // keeps task1 waiting until the zigbee is initialized
#define ZIGBEE_FLAG2    (1UL << 1)  // keeps task2 waiting until the zigbee is initialized

EventFlags      event_flags;
Thread          threadInitZigBee;
Thread          thread1;
Thread          thread2;

void taskInitZigBee()
{
    initZigBee();
    ThisThread::sleep_for(500ms);  // wait for ZigBee to become initialized
    event_flags.set(ZIGBEE_FLAG1); // signal task1 that ZigBee is initialized
    event_flags.set(ZIGBEE_FLAG2); // signal task2 that ZigBee is initialized
    while(1) {
        ...
    }
}

void task1()
{
    event_flags.wait_all(ZIGBEE_FLAG1);  // wait for ZIGBEE_FLAG1 to become set
    while(1) {
        ...
    }
}

void task2()
{
    event_flags.wait_all(ZIGBEE_FLAG2);  // wait for ZIGBEE_FLAG2 to become set
    while(1) {
        ...
    }
}

int main()
{
    threadInitZigBee.start(callback(taskInitZigBee));
    thread1.start(callback(task1));
    thread2.start(callback(task2));

    ...

    while(1) {
        ...
    }
}
1 Like