| /* |
| * Copyright (c) 2015 Wind River Systems, Inc. |
| * Copyright (c) 2019 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @file |
| * @brief Timer driver API |
| * |
| * Declare API implemented by system timer driver and used by kernel components. |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_ |
| #define ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_ |
| |
| #include <stdbool.h> |
| #include <zephyr/types.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * @brief System Clock APIs |
| * @defgroup clock_apis System Clock APIs |
| * @{ |
| */ |
| |
| /** |
| * @brief Set system clock timeout |
| * |
| * Informs the system clock driver that the next needed call to |
| * sys_clock_announce() will not be until the specified number of ticks |
| * from the the current time have elapsed. Note that spurious calls |
| * to sys_clock_announce() are allowed (i.e. it's legal to announce |
| * every tick and implement this function as a noop), the requirement |
| * is that one tick announcement should occur within one tick BEFORE |
| * the specified expiration (that is, passing ticks==1 means "announce |
| * the next tick", this convention was chosen to match legacy usage). |
| * Similarly a ticks value of zero (or even negative) is legal and |
| * treated identically: it simply indicates the kernel would like the |
| * next tick announcement as soon as possible. |
| * |
| * Note that ticks can also be passed the special value K_TICKS_FOREVER, |
| * indicating that no future timer interrupts are expected or required |
| * and that the system is permitted to enter an indefinite sleep even |
| * if this could cause rollover of the internal counter (i.e. the |
| * system uptime counter is allowed to be wrong |
| * |
| * Note also that it is conventional for the kernel to pass INT_MAX |
| * for ticks if it wants to preserve the uptime tick count but doesn't |
| * have a specific event to await. The intent here is that the driver |
| * will schedule any needed timeout as far into the future as |
| * possible. For the specific case of INT_MAX, the next call to |
| * sys_clock_announce() may occur at any point in the future, not just |
| * at INT_MAX ticks. But the correspondence between the announced |
| * ticks and real-world time must be correct. |
| * |
| * A final note about SMP: note that the call to sys_clock_set_timeout() |
| * is made on any CPU, and reflects the next timeout desired globally. |
| * The resulting calls(s) to sys_clock_announce() must be properly |
| * serialized by the driver such that a given tick is announced |
| * exactly once across the system. The kernel does not (cannot, |
| * really) attempt to serialize things by "assigning" timeouts to |
| * specific CPUs. |
| * |
| * @param ticks Timeout in tick units |
| * @param idle Hint to the driver that the system is about to enter |
| * the idle state immediately after setting the timeout |
| */ |
| extern void sys_clock_set_timeout(int32_t ticks, bool idle); |
| |
| /** |
| * @brief Timer idle exit notification |
| * |
| * This notifies the timer driver that the system is exiting the idle |
| * and allows it to do whatever bookkeeping is needed to restore timer |
| * operation and compute elapsed ticks. |
| * |
| * @note Legacy timer drivers also use this opportunity to call back |
| * into sys_clock_announce() to notify the kernel of expired ticks. |
| * This is allowed for compatibility, but not recommended. The kernel |
| * will figure that out on its own. |
| */ |
| extern void sys_clock_idle_exit(void); |
| |
| /** |
| * @brief Announce time progress to the kernel |
| * |
| * Informs the kernel that the specified number of ticks have elapsed |
| * since the last call to sys_clock_announce() (or system startup for |
| * the first call). The timer driver is expected to delivery these |
| * announcements as close as practical (subject to hardware and |
| * latency limitations) to tick boundaries. |
| * |
| * @param ticks Elapsed time, in ticks |
| */ |
| extern void sys_clock_announce(int32_t ticks); |
| |
| /** |
| * @brief Ticks elapsed since last sys_clock_announce() call |
| * |
| * Queries the clock driver for the current time elapsed since the |
| * last call to sys_clock_announce() was made. The kernel will call |
| * this with appropriate locking, the driver needs only provide an |
| * instantaneous answer. |
| */ |
| extern uint32_t sys_clock_elapsed(void); |
| |
| /** |
| * @brief Disable system timer. |
| * |
| * @note Not all system timer drivers has the capability of being disabled. |
| * The config @kconfig{CONFIG_SYSTEM_TIMER_HAS_DISABLE_SUPPORT} can be used to |
| * check if the system timer has the capability of being disabled. |
| */ |
| extern void sys_clock_disable(void); |
| |
| /** |
| * @brief Hardware cycle counter |
| * |
| * Timer drivers are generally responsible for the system cycle |
| * counter as well as the tick announcements. This function is |
| * generally called out of the architecture layer (@see |
| * arch_k_cycle_get_32()) to implement the cycle counter, though the |
| * user-facing API is owned by the architecture, not the driver. The |
| * rate must match CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. |
| * |
| * @note |
| * If the counter clock is large enough for this to wrap its full range |
| * within a few seconds (i.e. CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC is greater |
| * than 50Mhz) then it is recommended to also implement |
| * sys_clock_cycle_get_64(). |
| * |
| * @return The current cycle time. This should count up monotonically |
| * through the full 32 bit space, wrapping at 0xffffffff. Hardware |
| * with fewer bits of precision in the timer is expected to synthesize |
| * a 32 bit count. |
| */ |
| uint32_t sys_clock_cycle_get_32(void); |
| |
| /** |
| * @brief 64 bit hardware cycle counter |
| * |
| * As for sys_clock_cycle_get_32(), but with a 64 bit return value. |
| * Not all hardware has 64 bit counters. This function need be |
| * implemented only if CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER is set. |
| * |
| * @note |
| * If the counter clock is large enough for sys_clock_cycle_get_32() to wrap |
| * its full range within a few seconds (i.e. CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC |
| * is greater than 50Mhz) then it is recommended to implement this API. |
| * |
| * @return The current cycle time. This should count up monotonically |
| * through the full 64 bit space, wrapping at 2^64-1. Hardware with |
| * fewer bits of precision in the timer is generally not expected to |
| * implement this API. |
| */ |
| uint64_t sys_clock_cycle_get_64(void); |
| |
| /** |
| * @} |
| */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_ */ |