mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-30 14:55:21 +00:00
By default, kernel event logger is using the system timer. But on some platforms where the timer driver maintains the system timer cycle accumulator in software, such as ones using the LOAPIC timer, the system timer behavior leads to timestamp errors. For example, the timer interrupt is logged with a wrong timestamp since the HW timer value has been reset (periodic mode) but accumulated value not updated yet (done later in the ISR). This patch is adding the possibility to register a timer callback function that will be used by the kernel event logger. For example, on Quark SE, this allows using RTC or AON counter which accuracy is sufficient and behavior more straight forward compared to system timer. Change-Id: I754c7557350ef29fc10701e62a35a5425e035f11 Signed-off-by: Fabrice Olivero <fabrice.olivero@intel.com>
83 lines
2.1 KiB
C
83 lines
2.1 KiB
C
/* k_task_monitor.c - microkernel task monitoring subsystem */
|
|
|
|
/*
|
|
* Copyright (c) 1997-2010, 2013-2015 Wind River Systems, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <micro_private.h>
|
|
#include <misc/kernel_event_logger.h>
|
|
|
|
#ifdef CONFIG_KERNEL_EVENT_LOGGER_DYNAMIC
|
|
int _k_monitor_mask;
|
|
#else
|
|
const int _k_monitor_mask = CONFIG_TASK_MONITOR_MASK;
|
|
#endif
|
|
|
|
k_task_monitor_hook_t _k_task_switch_callback;
|
|
|
|
void task_monitor_hook_set(k_task_monitor_hook_t func)
|
|
{
|
|
_k_task_switch_callback = func;
|
|
}
|
|
|
|
void _k_task_monitor(struct k_task *X, uint32_t D)
|
|
{
|
|
uint32_t data[3];
|
|
#ifdef CONFIG_TASK_DEBUG
|
|
if (!_k_debug_halt)
|
|
#endif
|
|
{
|
|
data[0] = _sys_k_get_time();
|
|
data[1] = X->id;
|
|
data[2] = D;
|
|
sys_k_event_logger_put(
|
|
KERNEL_EVENT_LOGGER_TASK_MON_TASK_STATE_CHANGE_EVENT_ID,
|
|
data, ARRAY_SIZE(data));
|
|
}
|
|
if ((_k_task_switch_callback != NULL) && (D == 0)) {
|
|
(_k_task_switch_callback)(X->id, sys_cycle_get_32());
|
|
}
|
|
}
|
|
|
|
void _k_task_monitor_args(struct k_args *A)
|
|
{
|
|
#ifdef CONFIG_TASK_DEBUG
|
|
if (!_k_debug_halt)
|
|
#endif
|
|
{
|
|
int cmd_type;
|
|
cmd_type = (int)A & KERNEL_CMD_TYPE_MASK;
|
|
|
|
if (cmd_type == KERNEL_CMD_EVENT_TYPE) {
|
|
uint32_t data[2];
|
|
|
|
data[0] = _sys_k_get_time();
|
|
data[1] = MO_EVENT | (uint32_t)A;
|
|
sys_k_event_logger_put(
|
|
KERNEL_EVENT_LOGGER_TASK_MON_KEVENT_EVENT_ID,
|
|
data, ARRAY_SIZE(data));
|
|
} else {
|
|
uint32_t data[3];
|
|
|
|
data[0] = _sys_k_get_time();
|
|
data[1] = _k_current_task->id;
|
|
data[2] = (uint32_t)A->Comm;
|
|
sys_k_event_logger_put(
|
|
KERNEL_EVENT_LOGGER_TASK_MON_CMD_PACKET_EVENT_ID,
|
|
data, ARRAY_SIZE(data));
|
|
}
|
|
}
|
|
}
|