kernel/timeout: fix k_timer_remaining_get() when tickless
In some circumstances (e.g., a tickless kernel), k_timer_remaining_get() would not account for time passed that didn't involve clock interrupts. This adds a simple fix for that, and adds a test case. In addition, the return value of k_timer_remaining_get() is clamped at 0 in the case of overdue timers and the API description is adjusted to reflect this. Fixes: #13353 Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
parent
10040f603d
commit
0ad4022e51
4 changed files with 34 additions and 4 deletions
|
@ -1561,7 +1561,8 @@ __syscall u32_t k_timer_remaining_get(struct k_timer *timer);
|
||||||
|
|
||||||
static inline u32_t _impl_k_timer_remaining_get(struct k_timer *timer)
|
static inline u32_t _impl_k_timer_remaining_get(struct k_timer *timer)
|
||||||
{
|
{
|
||||||
return (u32_t)__ticks_to_ms(z_timeout_remaining(&timer->timeout));
|
const s32_t ticks = z_timeout_remaining(&timer->timeout);
|
||||||
|
return (ticks > 0) ? (u32_t)__ticks_to_ms(ticks) : 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -134,7 +134,7 @@ s32_t z_timeout_remaining(struct _timeout *timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ticks;
|
return ticks - elapsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t _get_next_timeout_expiry(void)
|
s32_t _get_next_timeout_expiry(void)
|
||||||
|
|
|
@ -484,6 +484,33 @@ void test_timer_user_data(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test accuracy of k_timer_remaining_get()
|
||||||
|
*
|
||||||
|
* Validate countdown of time to expiration
|
||||||
|
*
|
||||||
|
* Starts a timer, busy-waits for half the DURATION, then checks the
|
||||||
|
* remaining time to expiration and stops the timer. The remaining time
|
||||||
|
* should reflect the passage of at least the busy-wait interval.
|
||||||
|
*
|
||||||
|
* @ingroup kernel_timer_tests
|
||||||
|
*
|
||||||
|
* @see k_timer_init(), k_timer_start(), k_timer_stop(),
|
||||||
|
* k_timer_remaining_get()
|
||||||
|
*/
|
||||||
|
|
||||||
|
void test_timer_remaining_get(void)
|
||||||
|
{
|
||||||
|
u32_t remaining;
|
||||||
|
|
||||||
|
init_timer_data();
|
||||||
|
k_timer_init(&timer, NULL, NULL);
|
||||||
|
k_timer_start(&timer, DURATION, 0);
|
||||||
|
busy_wait_ms(DURATION / 2);
|
||||||
|
remaining = k_timer_remaining_get(&timer);
|
||||||
|
k_timer_stop(&timer);
|
||||||
|
zassert_true(remaining <= (DURATION / 2), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void test_main(void)
|
void test_main(void)
|
||||||
{
|
{
|
||||||
|
@ -496,6 +523,7 @@ void test_main(void)
|
||||||
ztest_unit_test(test_timer_status_get_anytime),
|
ztest_unit_test(test_timer_status_get_anytime),
|
||||||
ztest_unit_test(test_timer_status_sync),
|
ztest_unit_test(test_timer_status_sync),
|
||||||
ztest_unit_test(test_timer_k_define),
|
ztest_unit_test(test_timer_k_define),
|
||||||
ztest_unit_test(test_timer_user_data));
|
ztest_unit_test(test_timer_user_data),
|
||||||
|
ztest_unit_test(test_timer_remaining_get));
|
||||||
ztest_run_test_suite(timer_api);
|
ztest_run_test_suite(timer_api);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
common:
|
||||||
|
arch_exclude: x86_64
|
||||||
tests:
|
tests:
|
||||||
kernel.timer:
|
kernel.timer:
|
||||||
tags: kernel
|
tags: kernel
|
||||||
kernel.timer.tickless:
|
kernel.timer.tickless:
|
||||||
build_only: true
|
|
||||||
extra_args: CONF_FILE="prj_tickless.conf"
|
extra_args: CONF_FILE="prj_tickless.conf"
|
||||||
arch_exclude: riscv32 nios2 posix
|
arch_exclude: riscv32 nios2 posix
|
||||||
tags: kernel
|
tags: kernel
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue