The osDelay() and osWait() functions are used for creating delays and waiting in embedded systems programmed with Keil RTX. Both functions are useful for implementing timing requirements, synchronization, timeouts, polling loops, and blocking operations. However, there are some key differences between the two that developers should understand.
osDelay()
The osDelay() function is used to create a delay or pause in task execution. It is declared as follows:
osStatus osDelay (uint32_t millisec);
osDelay() takes a single parameter which is the delay time in milliseconds. When called, it will pause execution of the current thread for the specified time before resuming. The delay time is a minimum, and delays may be longer depending on the scheduler.
During the delay, the thread is moved to a delayed state and added to the scheduler’s delay list. The kernel will not run the thread again until the delay time has elapsed. This allows other threads and tasks to execute while waiting.
Key properties of osDelay():
- Pauses execution of calling thread for a specified time
- Delays are a minimum, actual time may be longer
- Thread goes into delayed state, allowing other threads to run
- Resumes thread execution once delay time has elapsed
- Can be called multiple times to create longer delays
osDelay() is useful when a task needs to wait or pause without consuming CPU cycles. It allows avoiding busy wait loops. Delays can also synchronize events and create timed actions.
osWait()
The osWait() function is used to suspend a thread and wait for an event flag to be set. It is declared as follows:
os_InRegs osEvent osWait (uint32_t millisec);
osWait() takes a timeout value in milliseconds. It will suspend the calling thread until the specified event flag is set or the timeout occurs.
The event flags are set by calling osSignal(), osSet Signals(), or osThreadFlagsSet() from another context. This allows synchronization between threads and signaling that an event has occurred.
Key properties of osWait():
- Suspends thread execution until an event flag is set
- Can specify a timeout value for the wait
- Returns event flags when wait is satisfied or on timeout
- Commonly used for thread synchronization, signaling, event detection
- Does not consume CPU cycles while waiting
osWait() is useful for synchronizing operations across multiple threads, waiting for external events, implementing producer/consumer patterns, and other concurrent operations.
Key Differences
While both osDelay() and osWait() are used for waiting, there are some key differences:
- Purpose – osDelay() creates a pause, while osWait() waits for an event flag.
- Behavior – osDelay() always delays for the specified time. osWait() waits indefinitely until an event flag is set.
- Events – osDelay() does not use events. osWait() requires waiting for event flags.
- Timeout – osDelay() delay time is fixed. osWait() allows specifying a timeout.
- Return – osDelay() has no return value. osWait() returns event flags.
- Use Cases – osDelay() is for pauses and timing. osWait() is for synchronization and events.
In summary, osDelay() creates timed pauses, while osWait() suspends a thread until an event flag is set for synchronization.
Examples
Here are some example uses of osDelay() and osWait() in Keil RTX:
osDelay()
// Blink LED every 500 ms
while (1) {
LED_On();
osDelay(500);
LED_Off();
osDelay(500);
}
osDelay() is used to create a blinking LED with a fixed on/off timing.
// Timeout for serial data
startTime = osKernelSysTick();
while (!Serial_DataReady()) {
if (osKernelSysTick() > startTime + 500) {
// Timeout elapsed
return TIMEOUT;
}
osDelay(50); // Retry every 50 ms
}
osDelay() implements a timeout by delaying in a loop, allowing other threads to run.
osWait()
// Thread 1
osSignalSet( Thread2, SIGNAL_READY);
// Thread 2
osWait(SIGNAL_READY);
// Do action when signaled
osWait() allows Thread 2 to wait until Thread 1 sends a signal event.
// Producer thread
while(1) {
osWait(SPACE_AVAIL); // Wait for space
put_item(item);
osSignal(CONSUMER, ITEM_AVAIL); // Signal consumer
}
// Consumer thread
while(1) {
osWait(ITEM_AVAIL); // Wait for item
get_item(item);
osSignal(PRODUCER, SPACE_AVAIL); // Signal space
}
osWait() synchronizes a producer and consumer using event flags.
Conclusion
In summary, osDelay() is used for creating timed pauses in a thread, while osWait() suspends a thread until an event flag is set for synchronization purposes. osDelay() accepts a delay time in milliseconds, while osWait() takes an optional timeout and waits for events. Both functions are useful constructs for embedded systems using Keil RTX.