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_for
function. 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) {
...
}
}