samples/task_profiler: add RTC/counter support as timestamp
On Quark SE, using system timer as event timestamp creates inconsistencies since the timer is handled by software in timer_int_handler and tickless_idle_exit. So timestamp does not reflect timing of certain events like timer IRQ. This patch introduces the usage of RTC or AON counter as kernel event logger timestamp Change-Id: I070254446dd98dd448e119892c34abf12efca719 Signed-off-by: Fabrice Olivero <fabrice.olivero@intel.com>
This commit is contained in:
parent
128dcbbe13
commit
8a1c4e642b
5 changed files with 99 additions and 0 deletions
|
@ -72,6 +72,9 @@ prof.log = profiler output file generated from Zephyr target (binary)
|
|||
1) Enable KERNEL_EVENT_LOGGER
|
||||
-----------------------------
|
||||
|
||||
1.1) Kernel event logger configuration
|
||||
--------------------------------------
|
||||
|
||||
Edit project configuration file (e.g. $APP_BASE/prj.conf) and add the following
|
||||
flags:
|
||||
|
||||
|
@ -108,6 +111,29 @@ If wanting to understand microkernel object usage and task bit handling,
|
|||
recommended value is 6
|
||||
Otherwise, task monitor can be disabled (to decrease logger ring buffer usage)
|
||||
|
||||
1.2) Kernel event logger timestamp
|
||||
----------------------------------
|
||||
|
||||
By default, the kernel event logger is using the system timer for timestamping
|
||||
events. As system timer may not work properly depending on platform, this timer
|
||||
can be set at runtime using following flag:
|
||||
|
||||
$APP_BASE/prj.conf:
|
||||
CONFIG_KERNEL_EVENT_LOGGER_CUSTOM_TIMESTAMP=y
|
||||
|
||||
In that case, the profiler will set the RTC as timestamp so RTC must be enabled
|
||||
$APP_BASE/prj.conf:
|
||||
CONFIG_RTC=y
|
||||
|
||||
In case the RTC cannot be used, profiler can support counters as well by
|
||||
building application with the following way:
|
||||
|
||||
$APP_BASE/prj.conf:
|
||||
CONFIG_COUNTER=y
|
||||
|
||||
Build command:
|
||||
make BOARD=... PROFILER_USE_COUNTER=y
|
||||
|
||||
2) Enable UART flush [OPTIONAL]
|
||||
-------------------------------
|
||||
|
||||
|
@ -240,6 +266,16 @@ make BOARD=... PROFILER_NO_SHELL_REGISTER=1
|
|||
4) Build and flash project
|
||||
--------------------------
|
||||
|
||||
Flags that can be used by the profiler
|
||||
PROFILER_NO_SHELL_REGISTER: when profiler dynamic control is set, the profiler
|
||||
won't set its own console handler. In that case the
|
||||
profiler commands must be added to the application
|
||||
console handler
|
||||
|
||||
PROFILER_USECOUNTER: in case custom timestamp is set for the kernel event
|
||||
logger, the profiler will use RTC. This flag allows to
|
||||
use a counter instead
|
||||
|
||||
5) Get prepared for collecting profiler data
|
||||
--------------------------------------------
|
||||
|
||||
|
|
|
@ -3,5 +3,8 @@ ccflags-y += -I${ZEPHYR_BASE}/include/drivers/
|
|||
ifeq (${PROFILER_NO_SHELL_REGISTER},1)
|
||||
ccflags-y += -DPROFILER_NO_SHELL_REGISTER
|
||||
endif
|
||||
ifeq (${PROFILER_USE_COUNTER},1)
|
||||
ccflags-y += -DPROFILER_USE_COUNTER
|
||||
endif
|
||||
|
||||
obj-y = profiler.o
|
||||
|
|
|
@ -167,16 +167,72 @@ struct shell_cmd commands[] = {
|
|||
PROF_CMD,
|
||||
{ NULL, NULL}
|
||||
};
|
||||
#endif /* PROFILER_SHELL */
|
||||
|
||||
#undef TIMESTAMP_MODE_RTC
|
||||
#undef TIMESTAMP_MODE_COUNTER
|
||||
#if defined(CONFIG_KERNEL_EVENT_LOGGER_CUSTOM_TIMESTAMP)
|
||||
#if defined(CONFIG_RTC) && !defined(PROFILER_USE_COUNTER)
|
||||
#define TIMESTAMP_MODE_RTC
|
||||
#elif defined(CONFIG_COUNTER)
|
||||
#define TIMESTAMP_MODE_COUNTER
|
||||
#else
|
||||
#error KERNEL_EVENT_LOGGER_CUSTOM_TIMESTAMP set but RTC/COUNTER not enabled
|
||||
#endif
|
||||
|
||||
#if defined(TIMESTAMP_MODE_RTC)
|
||||
#include <rtc.h>
|
||||
struct device *rtc_dev;
|
||||
#elif defined(TIMESTAMP_MODE_COUNTER)
|
||||
#include <counter.h>
|
||||
struct device *counter_dev;
|
||||
#endif
|
||||
|
||||
#if defined(TIMESTAMP_MODE_RTC)
|
||||
uint32_t prof_read_timer(void)
|
||||
{
|
||||
return rtc_read(rtc_dev);
|
||||
}
|
||||
#elif defined(TIMESTAMP_MODE_COUNTER)
|
||||
uint32_t prof_read_timer(void)
|
||||
{
|
||||
return counter_read(counter_dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_KERNEL_EVENT_LOGGER_CUSTOM_TIMESTAMP */
|
||||
|
||||
void prof_init(void)
|
||||
{
|
||||
#if defined(TIMESTAMP_MODE_RTC)
|
||||
struct rtc_config config;
|
||||
|
||||
rtc_dev = device_get_binding("RTC_0");
|
||||
config.init_val = 0;
|
||||
config.alarm_enable = 0;
|
||||
rtc_enable(rtc_dev);
|
||||
rtc_set_config(rtc_dev, &config);
|
||||
|
||||
sys_k_event_logger_set_timer(prof_read_timer);
|
||||
#elif defined(TIMESTAMP_MODE_COUNTER)
|
||||
counter_dev = device_get_binding("AON_COUNTER");
|
||||
counter_start(counter_dev);
|
||||
|
||||
sys_k_event_logger_set_timer(prof_read_timer);
|
||||
#endif
|
||||
|
||||
#ifdef PROFILER_SHELL
|
||||
#ifndef PROFILER_NO_SHELL_REGISTER
|
||||
shell_init("shell> ", commands);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(TIMESTAMP_MODE_RTC) || defined(TIMESTAMP_MODE_COUNTER)
|
||||
prof_pltfm_info.hw_ticks_per_sec = 32768;
|
||||
#else
|
||||
prof_pltfm_info.hw_ticks_per_sec = (sys_clock_ticks_per_sec * sys_clock_hw_cycles_per_tick);
|
||||
#endif
|
||||
|
||||
uart_console_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME);
|
||||
|
||||
prof_initialized = 1;
|
||||
|
|
|
@ -17,3 +17,5 @@ CONFIG_TICKLESS_IDLE=y
|
|||
CONFIG_KERNEL_EVENT_LOGGER_SLEEP=y
|
||||
CONFIG_UART_QMSI_1_BAUDRATE=2000000
|
||||
CONFIG_ARC_INIT=n
|
||||
CONFIG_KERNEL_EVENT_LOGGER_CUSTOM_TIMESTAMP=y
|
||||
CONFIG_RTC=y
|
||||
|
|
|
@ -15,3 +15,5 @@ CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT=y
|
|||
#CONFIG_KERNEL_EVENT_LOGGER_SLEEP=y
|
||||
CONFIG_UART_QMSI_1_BAUDRATE=2000000
|
||||
CONFIG_ARC_INIT=n
|
||||
CONFIG_KERNEL_EVENT_LOGGER_CUSTOM_TIMESTAMP=y
|
||||
CONFIG_RTC=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue