From 1ae1099ef072fd5fa5d1fde1e73c8c1df8d8d2f4 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 29 Jul 2013 13:36:19 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6038 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM4-STM32F303-DISCOVERY/chconf.h | 9 +- os/kernel/include/ch.h | 2 +- os/kernel/include/chrt.h | 171 ------------------------ os/kernel/include/chstats.h | 105 +++++++++++++++ os/kernel/include/chtm.h | 171 ++++++++++++++++++++++++ os/kernel/kernel.mk | 2 +- os/kernel/src/chrt.c | 208 ------------------------------ os/kernel/src/chstats.c | 65 ++++++++++ os/kernel/src/chtm.c | 197 ++++++++++++++++++++++++++++ 9 files changed, 545 insertions(+), 385 deletions(-) delete mode 100644 os/kernel/include/chrt.h create mode 100644 os/kernel/include/chstats.h create mode 100644 os/kernel/include/chtm.h delete mode 100644 os/kernel/src/chrt.c create mode 100644 os/kernel/src/chstats.c create mode 100644 os/kernel/src/chtm.c diff --git a/demos/ARMCM4-STM32F303-DISCOVERY/chconf.h b/demos/ARMCM4-STM32F303-DISCOVERY/chconf.h index 928186af8..727f9de89 100644 --- a/demos/ARMCM4-STM32F303-DISCOVERY/chconf.h +++ b/demos/ARMCM4-STM32F303-DISCOVERY/chconf.h @@ -128,13 +128,14 @@ /*===========================================================================*/ /** - * @brief Realtime counter APIs. - * @details If enabled then the RT APIs are included in the kernel. + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. * * @note The default is @p TRUE. */ -#if !defined(CH_CFG_USE_RT) || defined(__DOXYGEN__) -#define CH_CFG_USE_RT TRUE +#if !defined(CH_CFG_USE_TM) || defined(__DOXYGEN__) +#define CH_CFG_USE_TM TRUE #endif /** diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h index efade76bf..e30ddd515 100644 --- a/os/kernel/include/ch.h +++ b/os/kernel/include/ch.h @@ -108,7 +108,7 @@ typedef struct thread thread_t; #include "chconf.h" #include "chtypes.h" #include "chdebug.h" -#include "chrt.h" +#include "chtm.h" #include "chstats.h" #include "chcore.h" #include "chsys.h" diff --git a/os/kernel/include/chrt.h b/os/kernel/include/chrt.h deleted file mode 100644 index caf27747e..000000000 --- a/os/kernel/include/chrt.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012,2013 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file chrt.h - * @brief Real Time Counter and Measurement module macros and structures. - * - * @addtogroup realtime_counter - * @{ - */ - -#ifndef _CHRT_H_ -#define _CHRT_H_ - -#if CH_CFG_USE_RT || defined(__DOXYGEN__) - -#define port_rt_get_counter_value() 0 - -/*===========================================================================*/ -/* Module constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of a Time Measurement object. - * @note The maximum measurable time period depends on the implementation - * of the realtime counter and its clock frequency. - * @note The measurement is not 100% cycle-accurate, it can be in excess - * of few cycles depending on the compiler and target architecture. - * @note Interrupts can affect measurement if the measurement is performed - * with interrupts enabled. - */ -typedef struct { - rtcnt_t best; /**< @brief Best measurement. */ - rtcnt_t worst; /**< @brief Worst measurement. */ - rtcnt_t cumulative; /**< @brief Cumulative measurement. */ - rtcnt_t last; /**< @brief Last measurement. */ -} time_measurement_t; - -/*===========================================================================*/ -/* Module macros. */ -/*===========================================================================*/ - -/** - * @name Time conversion utilities for the realtime counter - * @{ - */ -/** - * @brief Seconds to realtime counter. - * @details Converts from seconds to realtime counter cycles. - * @note The result is rounded upward to the next tick boundary. - * - * @param[in] sec number of seconds - * @return The number of cycles. - * - * @api - */ -#define S2RTV(freq, sec) ((freq) * (sec)) - -/** - * @brief Milliseconds to realtime counter. - * @details Converts from milliseconds to realtime counter cycles. - * @note The result is rounded upward to the next tick boundary. - * - * @param[in] msec number of milliseconds - * @return The number of cycles. - * - * @api - */ -#define MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec)) - -/** - * @brief Microseconds to realtime counter. - * @details Converts from microseconds to realtime counter cycles. - * @note The result is rounded upward to the next tick boundary. - * - * @param[in] usec number of microseconds - * @return The number of cycles. - * - * @api - */ -#define US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec)) - -/** - * @brief Realtime counter cycles to seconds. - * @details Converts from realtime counter cycles number to seconds. - * - * @param[in] n number of cycles - * @return The number of seconds. - * - * @api - */ -#define RTC2S(freq, n) (rtcnt_t)((n) / (freq)) - -/** - * @brief Realtime counter cycles to milliseconds. - * @details Converts from realtime counter cycles number to milliseconds. - * - * @param[in] n number of cycles - * @return The number of milliseconds. - * - * @api - */ -#define RTC2MS(freq, n) ((n) / ((freq) / 1000UL)) - -/** - * @brief Realtime counter cycles to microseconds. - * @details Converts from realtime counter cycles number to microseconds. - * - * @param[in] n number of cycles - * @return The number of microseconds. - * - * @api - */ -#define RTC2US(freq, n) ((n) / ((freq) / 1000000UL)) -/** @} */ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void _rt_init(void); - bool chRTIsCounterWithin(rtcnt_t start, rtcnt_t end); - void chRTPolledDelay(rtcnt_t cycles); - void chRTTimeMeasurementObjectInit(time_measurement_t *tmp); - NOINLINE void chRTTimeMeasurementStartX(time_measurement_t *tmp); - NOINLINE void chRTTimeMeasurementStopX(time_measurement_t *tmp); -#ifdef __cplusplus -} -#endif - -/*===========================================================================*/ -/* Module inline functions. */ -/*===========================================================================*/ - -#endif /* CH_CFG_USE_RT */ - -#endif /* _CHRT_H_ */ - -/** @} */ diff --git a/os/kernel/include/chstats.h b/os/kernel/include/chstats.h new file mode 100644 index 000000000..a94a84814 --- /dev/null +++ b/os/kernel/include/chstats.h @@ -0,0 +1,105 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chstats.h + * @brief Statistics module macros and structures. + * + * @addtogroup statistics + * @{ + */ + +#ifndef _CHSTATS_H_ +#define _CHSTATS_H_ + +#if CH_DBG_STATISTICS || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a kernel statistics structure. + */ +typedef struct { + ucnt_t nirq; /**< @brief IRQ number. + @note Fast Interrupts are not + accounted for. */ + ucnt_t nctxswc; /**< @brief Context switch number. */ + time_measurement_t critical; /**< @brief Critical zones measurement. */ + time_measurement_t isr; /**< @brief ISR measurement. */ +} kernel_stats_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Increases the IRQ counter. + */ +#define _stats_increase_irq() kernel_stats.nirq++ + +/** + * @brief Increases the context switch counter. + */ +#define _stats_increase_ctxswc() kernel_stats.nctxswc++ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern kernel_stats_t kernel_stats; +#endif + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#else /* !CH_DBG_STATISTICS */ + +/* Stub functions for when the statistics module is disabled. */ +#define _stats_increase_irq() +#define _stats_increase_ctxswc() + +#endif /* !CH_DBG_STATISTICS */ + +#endif /* _CHSTATS_H_ */ + +/** @} */ diff --git a/os/kernel/include/chtm.h b/os/kernel/include/chtm.h new file mode 100644 index 000000000..a7500a26b --- /dev/null +++ b/os/kernel/include/chtm.h @@ -0,0 +1,171 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chtm.h + * @brief Time Measurement module macros and structures. + * + * @addtogroup time_measurement + * @{ + */ + +#ifndef _CHTM_H_ +#define _CHTM_H_ + +#if CH_CFG_USE_TM || defined(__DOXYGEN__) + +#define port_rt_get_counter_value() 0 + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a Time Measurement object. + * @note The maximum measurable time period depends on the implementation + * of the realtime counter and its clock frequency. + * @note The measurement is not 100% cycle-accurate, it can be in excess + * of few cycles depending on the compiler and target architecture. + * @note Interrupts can affect measurement if the measurement is performed + * with interrupts enabled. + */ +typedef struct { + rtcnt_t best; /**< @brief Best measurement. */ + rtcnt_t worst; /**< @brief Worst measurement. */ + rtcnt_t cumulative; /**< @brief Cumulative measurement. */ + rtcnt_t last; /**< @brief Last measurement. */ +} time_measurement_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @name Time conversion utilities for the realtime counter + * @{ + */ +/** + * @brief Seconds to realtime counter. + * @details Converts from seconds to realtime counter cycles. + * @note The result is rounded upward to the next tick boundary. + * + * @param[in] sec number of seconds + * @return The number of cycles. + * + * @api + */ +#define S2RTV(freq, sec) ((freq) * (sec)) + +/** + * @brief Milliseconds to realtime counter. + * @details Converts from milliseconds to realtime counter cycles. + * @note The result is rounded upward to the next tick boundary. + * + * @param[in] msec number of milliseconds + * @return The number of cycles. + * + * @api + */ +#define MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec)) + +/** + * @brief Microseconds to realtime counter. + * @details Converts from microseconds to realtime counter cycles. + * @note The result is rounded upward to the next tick boundary. + * + * @param[in] usec number of microseconds + * @return The number of cycles. + * + * @api + */ +#define US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec)) + +/** + * @brief Realtime counter cycles to seconds. + * @details Converts from realtime counter cycles number to seconds. + * + * @param[in] n number of cycles + * @return The number of seconds. + * + * @api + */ +#define RTC2S(freq, n) (rtcnt_t)((n) / (freq)) + +/** + * @brief Realtime counter cycles to milliseconds. + * @details Converts from realtime counter cycles number to milliseconds. + * + * @param[in] n number of cycles + * @return The number of milliseconds. + * + * @api + */ +#define RTC2MS(freq, n) ((n) / ((freq) / 1000UL)) + +/** + * @brief Realtime counter cycles to microseconds. + * @details Converts from realtime counter cycles number to microseconds. + * + * @param[in] n number of cycles + * @return The number of microseconds. + * + * @api + */ +#define RTC2US(freq, n) ((n) / ((freq) / 1000000UL)) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void _rt_init(void); + bool chRTIsCounterWithin(rtcnt_t start, rtcnt_t end); + void chRTPolledDelay(rtcnt_t cycles); + void chRTTimeMeasurementObjectInit(time_measurement_t *tmp); + NOINLINE void chRTTimeMeasurementStartX(time_measurement_t *tmp); + NOINLINE void chRTTimeMeasurementStopX(time_measurement_t *tmp); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CH_CFG_USE_TM */ + +#endif /* _CHTM_H_ */ + +/** @} */ diff --git a/os/kernel/kernel.mk b/os/kernel/kernel.mk index 6b2dafd55..b82339f5e 100644 --- a/os/kernel/kernel.mk +++ b/os/kernel/kernel.mk @@ -4,7 +4,7 @@ KERNSRC = ${CHIBIOS}/os/kernel/src/chsys.c \ ${CHIBIOS}/os/kernel/src/chdebug.c \ ${CHIBIOS}/os/kernel/src/chlists.c \ ${CHIBIOS}/os/kernel/src/chvt.c \ - ${CHIBIOS}/os/kernel/src/chrt.c \ + ${CHIBIOS}/os/kernel/src/chtm.c \ ${CHIBIOS}/os/kernel/src/chstats.c \ ${CHIBIOS}/os/kernel/src/chschd.c \ ${CHIBIOS}/os/kernel/src/chthreads.c \ diff --git a/os/kernel/src/chrt.c b/os/kernel/src/chrt.c deleted file mode 100644 index 0a477de39..000000000 --- a/os/kernel/src/chrt.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012,2013 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file chvt.c - * @brief Real Time Counter and Measurement module code. - * - * @addtogroup realtime_counter - * @details Realtime Counter APIs and services. - * - *

Operation mode

- * The realtime counter is a fast HW counter that counts upward at - * regular intervals. This counted can be used for small and accurate - * delays, time stamp and time measurement. - * - *

Notes

- * On those architectures where such a counter is not implemented - * the system time counter is used instead. Of course the system - * time counter usually has a much lower resolution than a real - * HW counter. - * @{ - */ - -#include "ch.h" - -#if CH_CFG_USE_RT || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Module local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local variables. */ -/*===========================================================================*/ - -/** - * @brief Subsystem calibration value. - */ -static rtcnt_t measurement_offset; - -/*===========================================================================*/ -/* Module local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module exported functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the realtime counter unit. - * - * @init - */ -void _rt_init(void) { - time_measurement_t tm; - - /* Time Measurement subsystem calibration, it does a null measurement - and calculates the call overhead which is subtracted to real - measurements.*/ - measurement_offset = 0; - chRTTimeMeasurementObjectInit(&tm); - chRTTimeMeasurementStartX(&tm); - chRTTimeMeasurementStopX(&tm); - measurement_offset = tm.last; -} - -/** - * @brief Realtime window test. - * @details This function verifies if the current realtime counter value - * lies within the specified range or not. The test takes care - * of the realtime counter wrapping to zero on overflow. - * @note When start==end then the function returns always true because the - * whole time range is specified. - * @note This function can be called from any context. - * - * @par Example 1 - * Example of a guarded loop using the realtime counter. The loop implements - * a timeout after one second. - * @code - * rtcnt_t start = chRTGetCounterValue(); - * rtcnt_t timeout = start + S2RTC(RTCCLK, 1); - * while (my_condition) { - * if (!chRTIsCounterWithin(start, timeout) - * return TIMEOUT; - * // Do something. - * } - * // Continue. - * @endcode - * - * @par Example 2 - * Example of a loop that lasts exactly 50 microseconds. - * @code - * rtcnt_t start = chRTGetCounterValue(); - * rtcnt_t timeout = start + US2RTC(RTCCLK, 50); - * while (chRTIsCounterWithin(start, timeout)) { - * // Do something. - * } - * // Continue. - * @endcode - * - * @param[in] start the start of the time window (inclusive) - * @param[in] end the end of the time window (non inclusive) - * @retval true current time within the specified time window. - * @retval false current time not within the specified time window. - * - * @special - */ -bool chRTIsCounterWithin(rtcnt_t start, rtcnt_t end) { - rtcnt_t now = chSysGetRealtimeCounterX(); - - return end > start ? (now >= start) && (now < end) : - (now >= start) || (now < end); -} - -/** - * @brief Polled delay. - * @note The real delay is always few cycles in excess of the specified - * value. - * @note This function can be called from any context. - * - * @param[in] cycles number of cycles - * - * @special - */ -void chRTPolledDelay(rtcnt_t cycles) { - rtcnt_t start = chSysGetRealtimeCounterX(); - rtcnt_t end = start + cycles; - while (chRTIsCounterWithin(start, end)) - ; -} - -/** - * @brief Initializes a @p TimeMeasurement object. - * - * @param[out] tmp pointer to a @p TimeMeasurement structure - * - * @init - */ -void chRTTimeMeasurementObjectInit(time_measurement_t *tmp) { - - tmp->best = (rtcnt_t)-1; - tmp->worst = (rtcnt_t)0; - tmp->cumulative = (rtcnt_t)0; - tmp->last = (rtcnt_t)0; -} - -/** - * @brief Starts a measurement. - * @pre The @p time_measurement_t structure must be initialized. - * @note This function can be invoked from any context. - * - * @param[in,out] tmp pointer to a @p TimeMeasurement structure - * - * @special - */ -NOINLINE void chRTTimeMeasurementStartX(time_measurement_t *tmp) { - - tmp->last = chSysGetRealtimeCounterX(); -} - -/** - * @brief Stops a measurement. - * @pre The @p time_measurement_t structure must be initialized. - * @note This function can be invoked from any context. - * - * @param[in,out] tmp pointer to a @p time_measurement_t structure - * - * @special - */ -NOINLINE void chRTTimeMeasurementStopX(time_measurement_t *tmp) { - - rtcnt_t now = chSysGetRealtimeCounterX(); - tmp->last = now - tmp->last - measurement_offset; - tmp->cumulative += tmp->last; - if (tmp->last > tmp->worst) - tmp->worst = tmp->last; - else if (tmp->last < tmp->best) - tmp->best = tmp->last; -} - -#endif /* CH_CFG_USE_RT */ - -/** @} */ diff --git a/os/kernel/src/chstats.c b/os/kernel/src/chstats.c new file mode 100644 index 000000000..1decf8f16 --- /dev/null +++ b/os/kernel/src/chstats.c @@ -0,0 +1,65 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chstats.c + * @brief Real Time Counter and Measurement module code. + * + * @addtogroup realtime_counter + * @details Statistics services. + * @{ + */ + +#include "ch.h" + +#if CH_DBG_STATISTICS || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/** + * @brief Global kernel statistics. + */ +kernel_stats_t kernel_stats; + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +#endif /* CH_DBG_STATISTICS */ + +/** @} */ diff --git a/os/kernel/src/chtm.c b/os/kernel/src/chtm.c new file mode 100644 index 000000000..a42223da3 --- /dev/null +++ b/os/kernel/src/chtm.c @@ -0,0 +1,197 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chtm.c + * @brief Time Measurement module code. + * + * @addtogroup time_measurement + * @details Time Measurement APIs and services. + * @{ + */ + +#include "ch.h" + +#if CH_CFG_USE_TM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/** + * @brief Subsystem calibration value. + */ +static rtcnt_t measurement_offset; + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the realtime counter unit. + * + * @init + */ +void _rt_init(void) { + time_measurement_t tm; + + /* Time Measurement subsystem calibration, it does a null measurement + and calculates the call overhead which is subtracted to real + measurements.*/ + measurement_offset = 0; + chRTTimeMeasurementObjectInit(&tm); + chRTTimeMeasurementStartX(&tm); + chRTTimeMeasurementStopX(&tm); + measurement_offset = tm.last; +} + +/** + * @brief Realtime window test. + * @details This function verifies if the current realtime counter value + * lies within the specified range or not. The test takes care + * of the realtime counter wrapping to zero on overflow. + * @note When start==end then the function returns always true because the + * whole time range is specified. + * @note This function can be called from any context. + * + * @par Example 1 + * Example of a guarded loop using the realtime counter. The loop implements + * a timeout after one second. + * @code + * rtcnt_t start = chSysGetRealtimeCounterX(); + * rtcnt_t timeout = start + S2RTC(RTCCLK, 1); + * while (my_condition) { + * if (!chTMIsCounterWithin(start, timeout) + * return TIMEOUT; + * // Do something. + * } + * // Continue. + * @endcode + * + * @par Example 2 + * Example of a loop that lasts exactly 50 microseconds. + * @code + * rtcnt_t start = chSysGetRealtimeCounterX(); + * rtcnt_t timeout = start + US2RTC(RTCCLK, 50); + * while (chTMIsCounterWithin(start, timeout)) { + * // Do something. + * } + * // Continue. + * @endcode + * + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval true current time within the specified time window. + * @retval false current time not within the specified time window. + * + * @special + */ +bool chTMIsCounterWithin(rtcnt_t start, rtcnt_t end) { + rtcnt_t now = chSysGetRealtimeCounterX(); + + return end > start ? (now >= start) && (now < end) : + (now >= start) || (now < end); +} + +/** + * @brief Polled delay. + * @note The real delay is always few cycles in excess of the specified + * value. + * @note This function can be called from any context. + * + * @param[in] cycles number of cycles + * + * @special + */ +void chTMPolledDelay(rtcnt_t cycles) { + rtcnt_t start = chSysGetRealtimeCounterX(); + rtcnt_t end = start + cycles; + while (chRTIsCounterWithin(start, end)) + ; +} + +/** + * @brief Initializes a @p TimeMeasurement object. + * + * @param[out] tmp pointer to a @p TimeMeasurement structure + * + * @init + */ +void chTMObjectInit(time_measurement_t *tmp) { + + tmp->best = (rtcnt_t)-1; + tmp->worst = (rtcnt_t)0; + tmp->cumulative = (rtcnt_t)0; + tmp->last = (rtcnt_t)0; +} + +/** + * @brief Starts a measurement. + * @pre The @p time_measurement_t structure must be initialized. + * @note This function can be invoked from any context. + * + * @param[in,out] tmp pointer to a @p TimeMeasurement structure + * + * @special + */ +NOINLINE void chTMStartX(time_measurement_t *tmp) { + + tmp->last = chSysGetRealtimeCounterX(); +} + +/** + * @brief Stops a measurement. + * @pre The @p time_measurement_t structure must be initialized. + * @note This function can be invoked from any context. + * + * @param[in,out] tmp pointer to a @p time_measurement_t structure + * + * @special + */ +NOINLINE void chTMStopX(time_measurement_t *tmp) { + + rtcnt_t now = chSysGetRealtimeCounterX(); + tmp->last = now - tmp->last - measurement_offset; + tmp->cumulative += tmp->last; + if (tmp->last > tmp->worst) + tmp->worst = tmp->last; + else if (tmp->last < tmp->best) + tmp->best = tmp->last; +} + +#endif /* CH_CFG_USE_TM */ + +/** @} */ -- cgit v1.2.3