Skip to content

Commit e4430d0

Browse files
committed
Add Thread::wait_until
API is somewhat loose to cope with potential shift in the underlying RTOS APIs.
1 parent 23ec84e commit e4430d0

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

rtos/Thread.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,35 @@ osStatus Thread::wait(uint32_t millisec) {
353353
return osDelay(millisec);
354354
}
355355

356+
osStatus Thread::wait_until(uint64_t millisec) {
357+
// CMSIS-RTOS 2.1.0 and 2.1.1 differ in the time type, which we determine
358+
// by looking at the return type of osKernelGetTickCount. We assume
359+
// our header at least matches the implementation, so we don't try looking
360+
// at the run-time version report. (There's no compile-time version report)
361+
if (sizeof osKernelGetTickCount() == sizeof(uint64_t)) {
362+
// CMSIS-RTOS 2.1.0 has a 64-bit API. The corresponding RTX 5.2.0 can't
363+
// delay more than 0xfffffffe ticks, but there's no limit stated for
364+
// the generic API.
365+
return osDelayUntil(millisec);
366+
} else {
367+
// 64-bit time doesn't wrap (for half a billion years, at last)
368+
uint64_t now = Kernel::get_ms_count();
369+
// Report being late on entry
370+
if (now >= millisec) {
371+
return osErrorParameter;
372+
}
373+
// We're about to make a 32-bit delay call, so have at least this limit
374+
if (millisec - now > 0xFFFFFFFF) {
375+
return osErrorParameter;
376+
}
377+
// And this may have its own internal limit - we'll find out.
378+
// We hope/assume there's no problem with passing
379+
// osWaitForever = 0xFFFFFFFF - that value is only specified to have
380+
// special meaning for osSomethingWait calls.
381+
return osDelay(millisec - now);
382+
}
383+
}
384+
356385
osStatus Thread::yield() {
357386
return osThreadYield();
358387
}

rtos/Thread.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,14 +360,33 @@ class Thread : private mbed::NonCopyable<Thread> {
360360
*/
361361
static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
362362

363-
/** Wait for a specified time period in millisec:
363+
/** Wait for a specified time period in milliseconds
364+
Being tick-based, the delay will be up to the specified time - eg for
365+
a value of 1 the system waits until the next millisecond tick occurs,
366+
leading to a delay of 0-1 milliseconds.
364367
@param millisec time delay value
365368
@return status code that indicates the execution status of the function.
366369
367370
@note You cannot call this function from ISR context.
368371
*/
369372
static osStatus wait(uint32_t millisec);
370373

374+
/** Wait until a specified time in millisec
375+
The specified time is according to Kernel::get_ms_count().
376+
@param millisec absolute time in millisec
377+
@return status code that indicates the execution status of the function.
378+
@note not callable from interrupt
379+
@note if millisec is equal to or lower than the current tick count, this
380+
returns immediately, either with an error or "osOK".
381+
@note the underlying RTOS may have a limit to the maximum wait time
382+
due to internal 32-bit computations, but this is guaranteed to work if the
383+
delay is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
384+
it may return with an immediate error, or wait for the maximum delay.
385+
386+
@note You cannot call this function from ISR context.
387+
*/
388+
static osStatus wait_until(uint64_t millisec);
389+
371390
/** Pass control to next thread that is in state READY.
372391
@return status code that indicates the execution status of the function.
373392

0 commit comments

Comments
 (0)