Parcourir la source

[Add][kservice]Add thread usage support.

Rbb666 il y a 2 semaines
Parent
commit
bc4c036942
4 fichiers modifiés avec 74 ajouts et 7 suppressions
  1. 19 4
      components/finsh/cmd.c
  2. 3 0
      include/rtthread.h
  3. 5 3
      src/Kconfig
  4. 47 0
      src/kservice.c

+ 19 - 4
components/finsh/cmd.c

@@ -165,6 +165,7 @@ long list_thread(void)
     rt_list_t *next = (rt_list_t *)RT_NULL;
     const char *item_title = "thread";
     const size_t tcb_strlen = sizeof(void *) * 2 + 2;
+    const size_t usage_strlen = sizeof(void *) + 1;
     int maxlen;
 
     list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
@@ -173,18 +174,22 @@ long list_thread(void)
     maxlen = RT_NAME_MAX;
 
 #ifdef RT_USING_SMP
-    rt_kprintf("%-*.*s cpu bind pri  status      sp     stack size max used left tick   error  tcb addr\n", maxlen, maxlen, item_title);
+    rt_kprintf("%-*.*s cpu bind pri  status      sp     stack size max used left tick   error  tcb addr   usage\n", maxlen, maxlen, item_title);
     object_split(maxlen);
     rt_kprintf(" --- ---- ---  ------- ---------- ----------  ------  ---------- -------");
     rt_kprintf(" ");
     object_split(tcb_strlen);
+    rt_kprintf(" ");
+    object_split(usage_strlen);
     rt_kprintf("\n");
 #else
-    rt_kprintf("%-*.*s pri  status      sp     stack size max used left tick   error  tcb addr\n", maxlen, maxlen, item_title);
+    rt_kprintf("%-*.*s pri  status      sp     stack size max used left tick   error  tcb addr   usage\n", maxlen, maxlen, item_title);
     object_split(maxlen);
     rt_kprintf(" ---  ------- ---------- ----------  ------  ---------- -------");
     rt_kprintf(" ");
     object_split(tcb_strlen);
+    rt_kprintf(" ");
+    object_split(usage_strlen);
     rt_kprintf("\n");
 #endif /*RT_USING_SMP*/
 
@@ -243,17 +248,22 @@ long list_thread(void)
                     ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1;
                     while (*ptr == '#')ptr --;
 
-                    rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %s %p\n",
+                    rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %s %p",
                                ((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
                                thread->stack_size,
                                ((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
                                thread->remaining_tick,
                                rt_strerror(thread->error),
                                thread);
+#ifdef RT_USING_CPU_USAGE_TRACER
+                    rt_kprintf(" %3d%%\n", rt_thread_get_usage(thread));
+#else
+                    rt_kprintf("  N/A\n");
+#endif
 #else
                     ptr = (rt_uint8_t *)thread->stack_addr;
                     while (*ptr == '#') ptr ++;
-                    rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %s %p\n",
+                    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,6 +271,11 @@ long list_thread(void)
                                RT_SCHED_PRIV(thread).remaining_tick,
                                rt_strerror(thread->error),
                                thread);
+#ifdef RT_USING_CPU_USAGE_TRACER
+                    rt_kprintf(" %3d%%\n", rt_thread_get_usage(thread));
+#else
+                    rt_kprintf("  N/A\n");
+#endif
 #endif
                 }
             }

+ 3 - 0
include/rtthread.h

@@ -181,6 +181,9 @@ rt_err_t rt_thread_wakeup(rt_thread_t thread);
 void rt_thread_wakeup_set(struct rt_thread *thread, rt_wakeup_func_t func, void* user_data);
 #endif /* RT_USING_SMART */
 rt_err_t rt_thread_get_name(rt_thread_t thread, char *name, rt_uint8_t name_size);
+#ifdef RT_USING_CPU_USAGE_TRACER
+rt_uint8_t rt_thread_get_usage(rt_thread_t thread);
+#endif /* RT_USING_CPU_USAGE_TRACER */
 #ifdef RT_USING_SIGNALS
 void rt_thread_alloc_sig(rt_thread_t tid);
 void rt_thread_free_sig(rt_thread_t tid);

+ 5 - 3
src/Kconfig

@@ -192,10 +192,12 @@ endif
 config RT_USING_CPU_USAGE_TRACER
     select RT_USING_HOOK
     bool "Enable cpu usage tracing"
-    help
-        Enable cpu usage tracer for application like top.
-    default y if RT_USING_SMART
     default n
+    help
+        Enable thread CPU usage statistics and monitoring.
+        This feature tracks CPU usage for each thread and provides
+        percentage information through the list thread command.
+        It will automatically integrate with the scheduler to track thread execution time.
 
 menu "kservice options"
     config RT_USING_TINY_FFS

+ 47 - 0
src/kservice.c

@@ -535,6 +535,53 @@ rt_err_t rt_backtrace_thread(rt_thread_t thread)
     return rc;
 }
 
+#ifdef RT_USING_CPU_USAGE_TRACER
+/**
+ * @brief Get thread usage percentage relative to total system CPU time
+ *
+ * This function calculates the CPU usage percentage of a specific thread
+ * relative to the total CPU time consumed by all threads in the system.
+ *
+ * @param thread Pointer to the thread object. Must not be NULL.
+ *
+ * @return The CPU usage percentage as an integer value (0-100).
+ *         Returns 0 if total system time is 0 or if CPU usage tracing is not enabled.
+ *
+ * @note This function requires RT_USING_CPU_USAGE_TRACER to be enabled.
+ * @note The percentage is calculated as: (thread_time * 100) / total_system_time
+ * @note Due to integer arithmetic, the result is truncated and may not sum
+ *       to exactly 100% across all threads due to rounding.
+ * @note If thread is NULL, an assertion will be triggered in debug builds.
+ */
+rt_uint8_t rt_thread_get_usage(rt_thread_t thread)
+{
+    rt_ubase_t thread_time;
+    rt_ubase_t total_time = 0U;
+    int i;
+    rt_cpu_t pcpu;
+
+    RT_ASSERT(thread != RT_NULL);
+
+    thread_time = thread->user_time + thread->system_time;
+
+    /* Calculate total system time by summing all CPUs' time */
+    for (i = 0; i < RT_CPUS_NR; i++)
+    {
+        pcpu = rt_cpu_index(i);
+        total_time += pcpu->cpu_stat.user + pcpu->cpu_stat.system + pcpu->cpu_stat.idle;
+    }
+
+    if (total_time > 0U)
+    {
+        /* Calculate thread usage percentage: (thread_time * 100) / total_time */
+        rt_ubase_t usage = (thread_time * 100U) / total_time;
+        return (rt_uint8_t)(usage > 100U ? 100U : usage);
+    }
+
+    return 0U;
+}
+#endif /* RT_USING_CPU_USAGE_TRACER */
+
 #if defined(RT_USING_LIBC) && defined(RT_USING_FINSH)
 #include <stdlib.h> /* for string service */