diff --git a/doc/kernel/timing_functions/index.rst b/doc/kernel/timing_functions/index.rst index 5f21204c4e6..711ce319fcc 100644 --- a/doc/kernel/timing_functions/index.rst +++ b/doc/kernel/timing_functions/index.rst @@ -78,3 +78,6 @@ API documentation ***************** .. doxygengroup:: timing_api +.. doxygengroup:: timing_api_arch +.. doxygengroup:: timing_api_soc +.. doxygengroup:: timing_api_board diff --git a/include/zephyr/sys/arch_interface.h b/include/zephyr/sys/arch_interface.h index dc1d8f2e5a8..d044f578fae 100644 --- a/include/zephyr/sys/arch_interface.h +++ b/include/zephyr/sys/arch_interface.h @@ -1057,7 +1057,13 @@ int arch_gdb_remove_breakpoint(struct gdb_ctx *ctx, uint8_t type, #include /** - * @ingroup arch-timing + * @brief Arch specific Timing Measurement APIs + * @defgroup timing_api_arch Arch specific Timing Measurement APIs + * @ingroup timing_api + * + * Implements the necessary bits to support timing measurement + * using architecture specific timing measurement mechanism. + * * @{ */ @@ -1101,17 +1107,25 @@ void arch_timing_stop(void); /** * @brief Return timing counter. * + * @parblock + * * @note Any call to arch_timing_counter_get() must be done between * calls to arch_timing_start() and arch_timing_stop(), and on the * same CPU core. * - * @note Not all platforms have a timing counter with 64 bit precision. It - * is possible to see this value "go backwards" due to internal + * @endparblock + * + * @parblock + * + * @note Not all architectures have a timing counter with 64 bit precision. + * It is possible to see this value "go backwards" due to internal * rollover. Timing code must be prepared to address the rollover * (with platform-dependent code, e.g. by casting to a uint32_t before * subtraction) or by using arch_timing_cycles_get() which is required * to understand the distinction. * + * @endparblock + * * @return Timing counter. * * @see timing_counter_get() @@ -1121,7 +1135,7 @@ timing_t arch_timing_counter_get(void); /** * @brief Get number of cycles between @p start and @p end. * - * For some architectures or SoCs, the raw numbers from counter need + * @note For some architectures, the raw numbers from counter need * to be scaled to obtain actual number of cycles, or may roll over * internally. This function computes a positive-definite interval * between two returned cycle values. diff --git a/include/zephyr/timing/timing.h b/include/zephyr/timing/timing.h index bf9ee9033e9..a0c4a644abb 100644 --- a/include/zephyr/timing/timing.h +++ b/include/zephyr/timing/timing.h @@ -14,33 +14,253 @@ extern "C" { #endif +/** + * @brief Timing Measurement APIs + * @defgroup timing_api Timing Measurement APIs + * @ingroup os_services + * + * The timing measurement APIs can be used to obtain execution + * time of a section of code to aid in analysis and optimization. + * + * Please note that the timing functions may use a different timer + * than the default kernel timer, where the timer being used is + * specified by architecture, SoC or board configuration. + */ + +/** + * @brief SoC specific Timing Measurement APIs + * @defgroup timing_api_soc SoC specific Timing Measurement APIs + * @ingroup timing_api + * + * Implements the necessary bits to support timing measurement + * using SoC specific timing measurement mechanism. + * + * @{ + */ + +/** + * @brief Initialize the timing subsystem on SoC. + * + * Perform the necessary steps to initialize the timing subsystem. + * + * @see timing_init() + */ void soc_timing_init(void); + +/** + * @brief Signal the start of the timing information gathering. + * + * Signal to the timing subsystem that timing information + * will be gathered from this point forward. + * + * @see timing_start() + */ void soc_timing_start(void); + +/** + * @brief Signal the end of the timing information gathering. + * + * Signal to the timing subsystem that timing information + * is no longer being gathered from this point forward. + * + * @see timing_stop() + */ void soc_timing_stop(void); + +/** + * @brief Return timing counter. + * + * @note Not all SoCs have timing counters with 64 bit precision. It + * is possible to see this value "go backwards" due to internal + * rollover. Timing code must be prepared to address the rollover + * (with SoC dependent code, e.g. by casting to a uint32_t before + * subtraction) or by using soc_timing_cycles_get() which is required + * to understand the distinction. + * + * @return Timing counter. + * + * @see timing_counter_get() + */ timing_t soc_timing_counter_get(void); + +/** + * @brief Get number of cycles between @p start and @p end. + * + * @note The raw numbers from counter need to be scaled to + * obtain actual number of cycles, or may roll over internally. + * This function computes a positive-definite interval between two + * returned cycle values. + * + * @param start Pointer to counter at start of a measured execution. + * @param end Pointer to counter at stop of a measured execution. + * @return Number of cycles between start and end. + * + * @see timing_cycles_get() + */ uint64_t soc_timing_cycles_get(volatile timing_t *const start, volatile timing_t *const end); + +/** + * @brief Get frequency of counter used (in Hz). + * + * @return Frequency of counter used for timing in Hz. + * + * @see timing_freq_get() + */ uint64_t soc_timing_freq_get(void); + +/** + * @brief Convert number of @p cycles into nanoseconds. + * + * @param cycles Number of cycles + * @return Converted time value + * + * @see timing_cycles_to_ns() + */ uint64_t soc_timing_cycles_to_ns(uint64_t cycles); + +/** + * @brief Convert number of @p cycles into nanoseconds with averaging. + * + * @param cycles Number of cycles + * @param count Times of accumulated cycles to average over + * @return Converted time value + * + * @see timing_cycles_to_ns_avg() + */ uint64_t soc_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count); + +/** + * @brief Get frequency of counter used (in MHz). + * + * @return Frequency of counter used for timing in MHz. + * + * @see timing_freq_get_mhz() + */ uint32_t soc_timing_freq_get_mhz(void); +/** + * @} + */ + +/** + * @brief Board specific Timing Measurement APIs + * @defgroup timing_api_board Board specific Timing Measurement APIs + * @ingroup timing_api + * + * Implements the necessary bits to support timing measurement + * using board specific timing measurement mechanism. + * + * @{ + */ + +/** + * @brief Initialize the timing subsystem. + * + * Perform the necessary steps to initialize the timing subsystem. + * + * @see timing_init() + */ void board_timing_init(void); + +/** + * @brief Signal the start of the timing information gathering. + * + * Signal to the timing subsystem that timing information + * will be gathered from this point forward. + * + * @see timing_start() + */ void board_timing_start(void); + +/** + * @brief Signal the end of the timing information gathering. + * + * Signal to the timing subsystem that timing information + * is no longer being gathered from this point forward. + * + * @see timing_stop() + */ void board_timing_stop(void); + +/** + * @brief Return timing counter. + * + * @note Not all timing counters have 64 bit precision. It is + * possible to see this value "go backwards" due to internal + * rollover. Timing code must be prepared to address the rollover + * (with board dependent code, e.g. by casting to a uint32_t before + * subtraction) or by using board_timing_cycles_get() which is required + * to understand the distinction. + * + * @return Timing counter. + * + * @see timing_counter_get() + */ timing_t board_timing_counter_get(void); + +/** + * @brief Get number of cycles between @p start and @p end. + * + * @note The raw numbers from counter need to be scaled to + * obtain actual number of cycles, or may roll over internally. + * This function computes a positive-definite interval between two + * returned cycle values. + * + * @param start Pointer to counter at start of a measured execution. + * @param end Pointer to counter at stop of a measured execution. + * @return Number of cycles between start and end. + * + * @see timing_cycles_get() + */ uint64_t board_timing_cycles_get(volatile timing_t *const start, volatile timing_t *const end); + +/** + * @brief Get frequency of counter used (in Hz). + * + * @return Frequency of counter used for timing in Hz. + * + * @see timing_freq_get() + */ uint64_t board_timing_freq_get(void); + +/** + * @brief Convert number of @p cycles into nanoseconds. + * + * @param cycles Number of cycles + * @return Converted time value + * + * @see timing_cycles_to_ns() + */ uint64_t board_timing_cycles_to_ns(uint64_t cycles); + +/** + * @brief Convert number of @p cycles into nanoseconds with averaging. + * + * @param cycles Number of cycles + * @param count Times of accumulated cycles to average over + * @return Converted time value + * + * @see timing_cycles_to_ns_avg() + */ uint64_t board_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count); + +/** + * @brief Get frequency of counter used (in MHz). + * + * @return Frequency of counter used for timing in MHz. + * + * @see timing_freq_get_mhz() + */ uint32_t board_timing_freq_get_mhz(void); +/** + * @} + */ /** - * @brief Timing Measurement APIs - * @defgroup timing_api Timing APIs - * @ingroup os_services + * @addtogroup timing_api * @{ */