diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c index f8ee6b7fc53..a700cbfd4ab 100644 --- a/components/finsh/cmd.c +++ b/components/finsh/cmd.c @@ -32,6 +32,7 @@ * 2022-07-02 Stanley Lwin add list command * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2024-02-09 Bernard fix the version command + * 2024-04-02 Dyyt587 add thread usage for list_thread */ #include @@ -179,12 +180,20 @@ long list_thread(void) rt_kprintf(" "); object_split(tcb_strlen); rt_kprintf("\n"); +#else +#ifdef RT_USING_CPU_USAGE + rt_kprintf("%-*.*s pri status sp stack size max used left tick error tcb addr usage\n", maxlen, maxlen, item_title); #else rt_kprintf("%-*.*s pri status sp stack size max used left tick error tcb addr\n", maxlen, maxlen, item_title); +#endif /* RT_USING_CPU_USAGE */ object_split(maxlen); rt_kprintf(" --- ------- ---------- ---------- ------ ---------- -------"); rt_kprintf(" "); object_split(tcb_strlen); +#ifdef RT_USING_CPU_USAGE + rt_kprintf(" "); + object_split(usage_strlen); +#endif /* RT_USING_CPU_USAGE */ rt_kprintf("\n"); #endif /*RT_USING_SMP*/ @@ -253,7 +262,8 @@ long list_thread(void) #else ptr = (rt_uint8_t *)thread->stack_addr; while (*ptr == '#') ptr ++; - rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n", +#ifdef RT_USING_CPU_USAGE + rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p", thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp), thread->stack_size, (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100 @@ -261,7 +271,26 @@ long list_thread(void) RT_SCHED_PRIV(thread).remaining_tick, rt_strerror(thread->error), thread); -#endif + rt_uint64_t tick = (thread->duration_tick*10000); + rt_uint64_t now_time = rt_thread_usage_get_now_time(); + +#ifdef PKG_USING_RT_VSNPRINTF_FULL + double _usage= (thread->duration_tick*100.f/rt_thread_usage_get_now_time()); + rt_kprintf(" %.3f%%\n",_usage); +#else + rt_kprintf("%s%02d%%\n"," ", (tick/now_time)/100); +#endif /* PKG_USING_RT_VSNPRINTF_FULL */ +#else + rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n", + thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp), + thread->stack_size, + (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100 + / thread->stack_size, + rt_strerror(thread->error), + RT_SCHED_PRIV(thread).remaining_tick, + thread); +#endif /* RT_USING_CPU_USAGE */ +#endif /* ARCH_CPU_STACK_GROWS_UPWARD */ } } } diff --git a/src/Kconfig b/src/Kconfig index 849ce5fa3b8..65970032625 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -99,6 +99,13 @@ choice bool "256" endchoice +config RT_USING_CPU_USAGE + bool "Enable the usage of thread" + default true + help + Enable the usage of thread, the system will calculate the CPU usage + of each thread.(enable perfcounter and rt_kprintf_full will bring a surprise) + config RT_THREAD_PRIORITY_MAX int default 8 if RT_THREAD_PRIORITY_8 diff --git a/src/scheduler_up.c b/src/scheduler_up.c index 44da38d8ffa..09cf5e55d98 100644 --- a/src/scheduler_up.c +++ b/src/scheduler_up.c @@ -30,6 +30,7 @@ * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to scheduler.c * 2023-03-27 rose_man Split into scheduler upc and scheduler_mp.c * 2023-10-17 ChuShicheng Modify the timing of clearing RT_THREAD_STAT_YIELD flag bits + * 2024-04-02 Dyyt587 add thread usage support */ #include @@ -51,6 +52,10 @@ static rt_int16_t rt_scheduler_lock_nest; struct rt_thread *rt_current_thread = RT_NULL; rt_uint8_t rt_current_priority; +#ifdef RT_USING_CPU_USAGE +static rt_uint64_t last_time_tick; +#endif /* RT_USING_CPU_USAGE */ + #if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR) static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to); static void (*rt_scheduler_switch_hook)(struct rt_thread *tid); @@ -187,6 +192,38 @@ void rt_system_scheduler_start(void) /* never come back */ } +#ifdef RT_USING_CPU_USAGE +rt_weak rt_uint64_t rt_thread_usage_get_now_time(void) +{ +#ifdef PKG_USING_PERF_COUNTER + /* use perf_counter packages */ + extern int64_t get_system_ticks(void); + return get_system_ticks(); +#else + return rt_tick_get(); +#endif +} + +/** + * @brief This funtion will get the interval time; + * + * @return rt_uint64_t + */ +static rt_uint64_t rt_thread_uasge_get_interval_time(void) +{ + return rt_thread_usage_get_now_time() - last_time_tick; +} + +/** + * @brief This funtion will Resets the measurement start time + * + */ +static void rt_reaet_time_thread_usage(void) +{ + last_time_tick = rt_thread_usage_get_now_time(); +} +#endif /* RT_USING_CPU_USAGE */ + /** * @addtogroup Thread * @cond @@ -203,7 +240,10 @@ void rt_schedule(void) rt_base_t level; struct rt_thread *to_thread; struct rt_thread *from_thread; - +#ifdef RT_USING_CPU_USAGE + volatile rt_uint64_t interval_time; + interval_time = rt_thread_uasge_get_interval_time(); +#endif /* RT_USING_CPU_USAGE */ /* disable interrupt */ level = rt_hw_interrupt_disable(); @@ -237,6 +277,9 @@ void rt_schedule(void) if (to_thread != rt_current_thread) { +#ifdef RT_USING_CPU_USAGE + rt_current_thread->duration_tick += interval_time; +#endif /* RT_USING_CPU_USAGE */ /* if the destination thread is not the same as current thread */ rt_current_priority = (rt_uint8_t)highest_ready_priority; from_thread = rt_current_thread; @@ -276,6 +319,9 @@ void rt_schedule(void) rt_hw_context_switch((rt_ubase_t)&from_thread->sp, (rt_ubase_t)&to_thread->sp); +#ifdef RT_USING_CPU_USAGE + rt_reaet_time_thread_usage(); +#endif /* enable interrupt */ rt_hw_interrupt_enable(level); @@ -306,6 +352,9 @@ void rt_schedule(void) rt_hw_context_switch_interrupt((rt_ubase_t)&from_thread->sp, (rt_ubase_t)&to_thread->sp, from_thread, to_thread); +#ifdef RT_USING_CPU_USAGE + rt_reaet_time_thread_usage(); +#endif /* RT_USING_CPU_USAGE */ } } else