From 75f2097143c59b31ea0f9a65f9bbb019cfa5af27 Mon Sep 17 00:00:00 2001 From: Osprey Date: Mon, 18 May 2020 22:25:40 +0800 Subject: [PATCH] thread cpu usage cal --- examples/kernel/thread_cpu.c | 100 +++++++++++++++++++++++++++++++++++ examples/kernel/thread_cpu.h | 64 ++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 examples/kernel/thread_cpu.c create mode 100644 examples/kernel/thread_cpu.h diff --git a/examples/kernel/thread_cpu.c b/examples/kernel/thread_cpu.c new file mode 100644 index 0000000000..963086e95c --- /dev/null +++ b/examples/kernel/thread_cpu.c @@ -0,0 +1,100 @@ +#include +#include +#include "stm32f1xx_hal.h" +#include "thread_cpu.h" + +__weak +uint32_t get_curr_time() +{ + return DWT->CYCCNT; // don't use the function rt_tick_get() +} + +// rt_scheduler_sethook(thread_stats_scheduler_hook); + +void thread_stats_scheduler_hook(struct rt_thread *from, struct rt_thread *to) +{ + static uint32_t schedule_last_time; + + uint32_t time; + + time = get_curr_time(); + + from->user_data += (time - schedule_last_time); + schedule_last_time = time; +} + + +// can call the function 1 s (max 60s when stm32f1xx because of dwt) +void thread_cal_usage(thread_run_info_def *run_info) +{ + static uint32_t total_time_last; + + uint32_t time, total_time; + struct rt_list_node *node; + struct rt_list_node *list; + struct rt_thread *thread; + + uint32_t i; + + time = get_curr_time(); + + rt_enter_critical(); + + total_time = time - total_time_last; + total_time_last = time; + + list = &(rt_object_get_information(RT_Object_Class_Thread)->object_list); + + for(i = 0, node = list->next; (node != list) && i < THREAD_NBR_MAX; node = node->next, i++) + { + thread = rt_list_entry(node, struct rt_thread, list); + run_info[i].name = thread->name; + run_info[i].time = thread->user_data; + thread->user_data = 0; + } + + rt_exit_critical(); + + total_time /= 100; + if(total_time > 0) + { + for(uint32_t j = i, i = 0; i < j; i++) + { + run_info[i].usage = run_info[i].time / total_time; + } + } +} + + +void thread_stats_print(void) +{ + thread_run_info_def run_info[THREAD_NBR_MAX] = {0}; + thread_run_info_def *p_info; + + thread_cal_usage(run_info); + + rt_kprintf("thread\t\t\ttime\t usage\n"); + for(uint32_t i = 0; i < THREAD_NBR_MAX; i++) + { + p_info = &run_info[i]; + if(p_info->name != NULL) + { + if(p_info->usage > 0) + { + rt_kprintf("%-16s\t%u\t%2u%%\n", p_info->name, + (uint32_t)p_info->time, + (uint32_t)p_info->usage); + } + else + { + rt_kprintf("%-16s\t%u\t<1%%\n", p_info->name, + (uint32_t)p_info->time, + (uint32_t)p_info->usage); + } + } + else + { + break; + } + } +} diff --git a/examples/kernel/thread_cpu.h b/examples/kernel/thread_cpu.h new file mode 100644 index 0000000000..db681a5be0 --- /dev/null +++ b/examples/kernel/thread_cpu.h @@ -0,0 +1,64 @@ +/* + * File : thread_cpu.h + * Change Logs: + * Date Author Notes + * 2020-05-18 EmbeddedOsprey the first version + + 欢迎关注公众号:鱼鹰谈单片机 + utf-8 + + example: + + void rt_hw_board_init(void) + { + HAL_Init(); + + rt_scheduler_sethook(thread_stats_scheduler_hook); // set the hook before system start + + SystemClock_Config(); + #ifdef RT_USING_HEAP + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); + #endif + #ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); + #endif + #ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); + #endif + } + + + // call the function 1 s + int main() + { + while(1) + { + thread_stats_print(); + rt_thread_delay(1000); + } + } + */ + + +#ifndef __THREAD_CPU_USAGE_H__ +#define __THREAD_CPU_USAGE_H__ + +#include +#include +#include + +#define THREAD_NBR_MAX 10 // max the thread number + +typedef struct +{ + char *name; // thead name + uint32_t time; // dwt time unit + uint8_t usage; // thead usage percent 100% +}thread_run_info_def; + + +void thread_stats_scheduler_hook(struct rt_thread *from, struct rt_thread *to); +void thread_cal_usage(thread_run_info_def *run_info); +void thread_stats_print(void); + +#endif -- Gitee