system_timer.h: Change "now" uptime API to be simpler for drivers

The current z_clock_uptime() call (recently renamed from
_get_elapsed_program_time) requires the driver to track a full 64 bit
uptime value in ticks, which is entirely separate from the one the
kernel is already keeping.

Don't do that.  Just ask the drivers to track uptime since the last
call to z_clock_announce(), since that is going to map better to
built-in hardware capability.

Obviously existing drivers already have this feature, so they're
actually getting slightly larger in order to implement the new API in
terms of the old one.  But future drivers will thank us.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2018-09-27 14:08:46 -07:00 committed by Anas Nashif
commit 96013b0375
4 changed files with 40 additions and 8 deletions

View file

@ -1,10 +1,11 @@
#ifndef ZEPHYR_LEGACY_SET_TIME_H__
#define ZEPHYR_LEGACY_SET_TIME_H__
/* Stub implementation of z_clock_set_timeout() in terms of the
* original APIs. Used by older timer drivers. Should be replaced.
/* Stub implementation of z_clock_set_timeout() and z_clock_elapsed()
* in terms of the original APIs. Used by older timer drivers.
* Should be replaced.
*
* Yes, this "header" includes a function definition and must be
* Yes, this "header" includes function definitions and must be
* included only once in a single compilation.
*/
@ -20,7 +21,9 @@ extern u32_t _get_remaining_program_time(void);
extern u32_t _get_elapsed_program_time(void);
#endif
extern void z_clock_set_timeout(s32_t ticks, bool idle)
extern u64_t z_clock_uptime(void);
void z_clock_set_timeout(s32_t ticks, bool idle)
{
#ifdef CONFIG_TICKLESS_KERNEL
if (idle) {
@ -31,4 +34,24 @@ extern void z_clock_set_timeout(s32_t ticks, bool idle)
#endif
}
/* The old driver "now" API would return a full uptime value. The new
* one only requires the driver to track ticks since the last announce
* call. Implement the new call in terms of the old one on legacy
* drivers by keeping (yet another) uptime value locally.
*/
static u32_t driver_uptime;
u32_t z_clock_elapsed(void)
{
return (u32_t)(z_clock_uptime() - driver_uptime);
}
static void wrapped_announce(s32_t ticks)
{
driver_uptime += ticks;
z_clock_announce(ticks);
}
#define z_clock_announce(t) wrapped_announce(t)
#endif /* ZEPHYR_LEGACY_SET_TIME_H__ */

View file

@ -72,3 +72,8 @@ u32_t _timer_cycle_get_32(void)
{
return accumulated_cycle_count + timer->val;
}
u32_t z_clock_elapsed(void)
{
return 0;
}

View file

@ -102,12 +102,14 @@ extern void z_clock_idle_exit(void);
extern void z_clock_announce(s32_t ticks);
/**
* @brief System uptime in ticks
* @brief Ticks elapsed since last z_clock_announce() call
*
* Queries the clock driver for the current time elapsed since system
* bootup in ticks.
* Queries the clock driver for the current time elapsed since the
* last call to z_clock_announce() was made. The kernel will call
* this with appropriate locking, the driver needs only provide an
* instantaneous answer.
*/
extern u64_t z_clock_uptime(void);
extern u32_t z_clock_elapsed(void);
#ifdef __cplusplus
}

View file

@ -31,6 +31,8 @@ int z_clock_hw_cycles_per_sec;
#endif
#endif
extern u64_t z_clock_uptime(void);
/* Note that this value is 64 bits, and thus non-atomic on almost all
* Zephyr archtictures. And of course it's routinely updated inside
* timer interrupts. Access to it must be locked.