diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index 5b95413b10..74e1715d20 100644 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -16,6 +16,30 @@ config RT_USING_HWTIMER bool "Using hardware timer device drivers" default n +config RT_USING_CPUTIME + bool "Enable CPU time for high resolution clock counter" + default n + help + When enable this option, the BSP should provide a rt_clock_cputime_ops + for CPU time by: + clock_cpu_setops(const struct rt_clock_cputime_ops *ops); + + Then developer can use high resolution clock counter with: + + ts = clock_cpu_gettime(); + /* The unit of clock_cpu_gettime() can be returned by */ + unit = clock_cpu_getres(); /* number for nanosecond */ + +if RT_USING_CPUTIME + config RT_USING_CPUTIME_CORTEXM + bool "Use DWT for CPU time" + default y + depends on ARCH_ARM_CORTEX_M3 || ARCH_ARM_CORTEX_M4 || ARCH_ARM_CORTEX_M7 + help + Some Cortex-M3/4/7 MCU has Data Watchpoint and Trace Register, use + the cycle counter in DWT for CPU time. +endif + config RT_USING_I2C bool "Using I2C device drivers" default n diff --git a/components/drivers/cputime/SConscript b/components/drivers/cputime/SConscript new file mode 100644 index 0000000000..57c0b44fa8 --- /dev/null +++ b/components/drivers/cputime/SConscript @@ -0,0 +1,14 @@ +from building import * + +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include'] +src = Split(''' +cputime.c +''') + +if GetDepend('RT_USING_CPUTIME_CORTEXM'): + src += ['cputime_cortexm.c'] + +group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_CPUTIME'], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/drivers/cputime/cputime.c b/components/drivers/cputime/cputime.c new file mode 100644 index 0000000000..a607aeefa1 --- /dev/null +++ b/components/drivers/cputime/cputime.c @@ -0,0 +1,70 @@ +/* + * File : cputime.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-12-23 Bernard first version + */ + +#include +#include + +static const struct rt_clock_cputime_ops *_cputime_ops = RT_NULL; + +/** + * The clock_cpu_getres() function shall return the resolution of CPU time, the + * number of nanosecond per tick. + */ +uint32_t clock_cpu_getres(void) +{ + if (_cputime_ops) + return _cputime_ops->cputime_getres(); + + rt_set_errno(-ENOSYS); + return 0; +} + +/** + * The clock_cpu_gettime() function shall return the current value of cpu time tick. + */ +uint32_t clock_cpu_gettime(void) +{ + if (_cputime_ops) + return _cputime_ops->cputime_gettime(); + + rt_set_errno(-ENOSYS); + return 0; +} + +/** + * The clock_cpu_seops() function shall set the ops of cpu time. + * + * @return always return 0. + */ +int clock_cpu_setops(const struct rt_clock_cputime_ops *ops) +{ + _cputime_ops = ops; + if (ops) + { + RT_ASSERT(ops->cputime_getres != RT_NULL); + RT_ASSERT(ops->cputime_gettime != RT_NULL); + } + + return 0; +} diff --git a/components/drivers/cputime/cputime_cortexm.c b/components/drivers/cputime/cputime_cortexm.c new file mode 100644 index 0000000000..7db27b4b98 --- /dev/null +++ b/components/drivers/cputime/cputime_cortexm.c @@ -0,0 +1,66 @@ +/* + * File : cputime_cortexm.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-12-23 Bernard first version + */ + +#include +#include +#include + +#include + +/* Use Cycle counter of Data Watchpoint and Trace Register for CPU time */ + +static uint32_t cortexm_cputime_getres(void) +{ + return (1000 * 1000 * 1000)/SystemCoreClock; +} + +static uint32_t cortexm_cputime_gettime(void) +{ + return DWT->CYCCNT; +} + +const static struct rt_clock_cputime_ops _cortexm_ops = +{ + cortexm_cputime_getres, + cortexm_cputime_gettime +}; + +int cortexm_cputime_init(void) +{ + /* check support bit */ + if ((DWT->CTRL & (1UL << DWT_CTRL_NOCYCCNT_Pos)) == 0) + { + /* whether cycle counter not enabled */ + if ((DWT->CTRL & (1UL << DWT_CTRL_CYCCNTENA_Pos)) == 0) + { + /* enable cycle counter */ + DWT->CTRL |= (1UL << DWT_CTRL_CYCCNTENA_Pos); + } + + clock_cpu_setops(&_cortexm_ops); + } + + return 0; +} +INIT_BOARD_EXPORT(cortexm_cputime_init); diff --git a/components/drivers/include/drivers/cputime.h b/components/drivers/include/drivers/cputime.h new file mode 100644 index 0000000000..54037146bb --- /dev/null +++ b/components/drivers/include/drivers/cputime.h @@ -0,0 +1,39 @@ +/* + * File : cputime.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-12-23 Bernard first version + */ + +#ifndef CPUTIME_H__ +#define CPUTIME_H__ + +struct rt_clock_cputime_ops +{ + uint32_t (*cputime_getres) (void); + uint32_t (*cputime_gettime)(void); +}; + +uint32_t clock_cpu_getres(void); +uint32_t clock_cpu_gettime(void); + +int clock_cpu_setops(const struct rt_clock_cputime_ops *ops); + +#endif diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h index 0f021da66e..f7aadd8305 100644 --- a/components/drivers/include/rtdevice.h +++ b/components/drivers/include/rtdevice.h @@ -108,6 +108,10 @@ extern "C" { #include "drivers/audio.h" #endif +#ifdef RT_USING_CPUTIME +#include "drivers/cputime.h" +#endif + #ifdef __cplusplus } #endif