mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-30 15:15:21 +00:00
Use a common function to get the thread name. There was no necessity in keeping sys_trace_thread_info() inline, Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
188 lines
3.5 KiB
C
188 lines
3.5 KiB
C
/*
|
|
* Copyright (c) 2018 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include <zephyr.h>
|
|
#include <kernel_structs.h>
|
|
#include <init.h>
|
|
#include <ksched.h>
|
|
|
|
#include <SEGGER_SYSVIEW.h>
|
|
#include <Global.h>
|
|
#include "SEGGER_SYSVIEW_Zephyr.h"
|
|
|
|
#if CONFIG_THREAD_MAX_NAME_LEN
|
|
#define THREAD_NAME_LEN CONFIG_THREAD_MAX_NAME_LEN
|
|
#else
|
|
#define THREAD_NAME_LEN 20
|
|
#endif
|
|
|
|
static uint32_t interrupt;
|
|
|
|
uint32_t sysview_get_timestamp(void)
|
|
{
|
|
return k_cycle_get_32();
|
|
}
|
|
|
|
uint32_t sysview_get_interrupt(void)
|
|
{
|
|
return interrupt;
|
|
}
|
|
|
|
void sys_trace_thread_switched_in(void)
|
|
{
|
|
struct k_thread *thread;
|
|
|
|
thread = k_current_get();
|
|
|
|
if (z_is_idle_thread_object(thread)) {
|
|
SEGGER_SYSVIEW_OnIdle();
|
|
} else {
|
|
SEGGER_SYSVIEW_OnTaskStartExec((uint32_t)(uintptr_t)thread);
|
|
}
|
|
}
|
|
|
|
void sys_trace_thread_switched_out(void)
|
|
{
|
|
SEGGER_SYSVIEW_OnTaskStopExec();
|
|
}
|
|
|
|
void sys_trace_isr_enter(void)
|
|
{
|
|
SEGGER_SYSVIEW_RecordEnterISR();
|
|
}
|
|
|
|
void sys_trace_isr_exit(void)
|
|
{
|
|
SEGGER_SYSVIEW_RecordExitISR();
|
|
}
|
|
|
|
void sys_trace_isr_exit_to_scheduler(void)
|
|
{
|
|
SEGGER_SYSVIEW_RecordExitISRToScheduler();
|
|
}
|
|
|
|
void sys_trace_idle(void)
|
|
{
|
|
SEGGER_SYSVIEW_OnIdle();
|
|
}
|
|
|
|
|
|
void sys_trace_semaphore_init(struct k_sem *sem)
|
|
{
|
|
SEGGER_SYSVIEW_RecordU32(
|
|
SYS_TRACE_ID_SEMA_INIT, (uint32_t)(uintptr_t)sem);
|
|
}
|
|
|
|
void sys_trace_semaphore_take(struct k_sem *sem)
|
|
{
|
|
SEGGER_SYSVIEW_RecordU32(
|
|
SYS_TRACE_ID_SEMA_TAKE, (uint32_t)(uintptr_t)sem);
|
|
}
|
|
|
|
void sys_trace_semaphore_give(struct k_sem *sem)
|
|
{
|
|
SEGGER_SYSVIEW_RecordU32(
|
|
SYS_TRACE_ID_SEMA_GIVE, (uint32_t)(uintptr_t)sem);
|
|
}
|
|
|
|
void sys_trace_mutex_init(struct k_mutex *mutex)
|
|
{
|
|
SEGGER_SYSVIEW_RecordU32(
|
|
SYS_TRACE_ID_MUTEX_INIT, (uint32_t)(uintptr_t)mutex);
|
|
}
|
|
|
|
void sys_trace_mutex_lock(struct k_mutex *mutex)
|
|
{
|
|
SEGGER_SYSVIEW_RecordU32(
|
|
SYS_TRACE_ID_MUTEX_LOCK, (uint32_t)(uintptr_t)mutex);
|
|
}
|
|
|
|
void sys_trace_mutex_unlock(struct k_mutex *mutex)
|
|
{
|
|
SEGGER_SYSVIEW_RecordU32(
|
|
SYS_TRACE_ID_MUTEX_UNLOCK, (uint32_t)(uintptr_t)mutex);
|
|
}
|
|
|
|
static void set_thread_name(char *name, struct k_thread *thread)
|
|
{
|
|
const char *tname = k_thread_name_get(thread);
|
|
|
|
if (tname != NULL && tname[0] != '\0') {
|
|
memcpy(name, tname, THREAD_NAME_LEN);
|
|
name[THREAD_NAME_LEN - 1] = '\0';
|
|
} else {
|
|
snprintk(name, THREAD_NAME_LEN, "T%pE%p",
|
|
thread, &thread->entry);
|
|
}
|
|
}
|
|
|
|
void sys_trace_thread_info(struct k_thread *thread)
|
|
{
|
|
char name[THREAD_NAME_LEN];
|
|
|
|
set_thread_name(name, thread);
|
|
|
|
SEGGER_SYSVIEW_TASKINFO Info;
|
|
|
|
Info.TaskID = (uint32_t)(uintptr_t)thread;
|
|
Info.sName = name;
|
|
Info.Prio = thread->base.prio;
|
|
Info.StackBase = thread->stack_info.size;
|
|
Info.StackSize = thread->stack_info.start;
|
|
SEGGER_SYSVIEW_SendTaskInfo(&Info);
|
|
}
|
|
|
|
|
|
|
|
static void send_task_list_cb(void)
|
|
{
|
|
struct k_thread *thread;
|
|
|
|
for (thread = _kernel.threads; thread; thread = thread->next_thread) {
|
|
char name[THREAD_NAME_LEN];
|
|
|
|
if (z_is_idle_thread_object(thread)) {
|
|
continue;
|
|
}
|
|
|
|
set_thread_name(name, thread);
|
|
|
|
SEGGER_SYSVIEW_SendTaskInfo(&(SEGGER_SYSVIEW_TASKINFO) {
|
|
.TaskID = (uint32_t)(uintptr_t)thread,
|
|
.sName = name,
|
|
.StackSize = thread->stack_info.size,
|
|
.StackBase = thread->stack_info.start,
|
|
.Prio = thread->base.prio,
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
static U64 get_time_cb(void)
|
|
{
|
|
return (U64)k_cycle_get_32();
|
|
}
|
|
|
|
|
|
const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
|
|
get_time_cb,
|
|
send_task_list_cb,
|
|
};
|
|
|
|
|
|
static int sysview_init(const struct device *arg)
|
|
{
|
|
ARG_UNUSED(arg);
|
|
|
|
SEGGER_SYSVIEW_Conf();
|
|
if (IS_ENABLED(CONFIG_SEGGER_SYSTEMVIEW_BOOT_ENABLE)) {
|
|
SEGGER_SYSVIEW_Start();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
SYS_INIT(sysview_init, POST_KERNEL, 0);
|