Browse Source

[components][driver]add isr statistics (#8955)

add isr statistics
zms123456 11 months ago
parent
commit
6101f1fd29

+ 13 - 0
components/drivers/include/drivers/pic.h

@@ -91,6 +91,16 @@ struct rt_pic_isr
     struct rt_irq_desc action;
     struct rt_irq_desc action;
 };
 };
 
 
+#ifdef RT_USING_PIC_STATISTICS
+struct rt_pic_irq_statistics
+{
+    rt_ubase_t current_irq_begin[RT_CPUS_NR];
+    rt_ubase_t max_irq_time_ns;
+    rt_ubase_t min_irq_time_ns;
+    rt_ubase_t sum_irq_time_ns;
+};
+#endif
+
 struct rt_pic_irq
 struct rt_pic_irq
 {
 {
     int irq;
     int irq;
@@ -120,6 +130,9 @@ struct rt_pic_irq
 
 
     struct rt_pic *pic;
     struct rt_pic *pic;
     struct rt_pic_irq *parent;
     struct rt_pic_irq *parent;
+#ifdef RT_USING_PIC_STATISTICS
+    struct rt_pic_irq_statistics stat;
+#endif
 };
 };
 
 
 void rt_pic_default_name(struct rt_pic *pic);
 void rt_pic_default_name(struct rt_pic *pic);

+ 6 - 0
components/drivers/pic/Kconfig

@@ -4,6 +4,12 @@ menuconfig RT_USING_PIC
     depends on RT_USING_DM
     depends on RT_USING_DM
     default n
     default n
 
 
+config RT_USING_PIC_STATISTICS
+    bool "Enable ISR execution time statistics"
+    depends on RT_USING_PIC
+    depends on RT_USING_INTERRUPT_INFO
+    default n
+
 config MAX_HANDLERS
 config MAX_HANDLERS
     int "IRQ max handlers"
     int "IRQ max handlers"
     depends on RT_USING_PIC
     depends on RT_USING_PIC

+ 34 - 1
components/drivers/pic/pic.c

@@ -16,6 +16,7 @@
 #include <rtdbg.h>
 #include <rtdbg.h>
 
 
 #include <drivers/pic.h>
 #include <drivers/pic.h>
+#include <ktime.h>
 
 
 struct irq_traps
 struct irq_traps
 {
 {
@@ -504,10 +505,19 @@ rt_err_t rt_pic_handle_isr(struct rt_pic_irq *pirq)
     rt_err_t err = -RT_EEMPTY;
     rt_err_t err = -RT_EEMPTY;
     rt_list_t *handler_nodes;
     rt_list_t *handler_nodes;
     struct rt_irq_desc *action;
     struct rt_irq_desc *action;
+#ifdef RT_USING_PIC_STATISTICS
+    struct timespec ts;
+    rt_ubase_t irq_time_ns;
+#endif
 
 
     RT_ASSERT(pirq != RT_NULL);
     RT_ASSERT(pirq != RT_NULL);
     RT_ASSERT(pirq->pic != RT_NULL);
     RT_ASSERT(pirq->pic != RT_NULL);
 
 
+#ifdef RT_USING_PIC_STATISTICS
+    rt_ktime_boottime_get_ns(&ts);
+    pirq->stat.current_irq_begin[rt_hw_cpu_id()] = ts.tv_sec * (1000UL * 1000 * 1000) + ts.tv_nsec;
+#endif
+
     /* Corrected irq affinity */
     /* Corrected irq affinity */
     rt_bitmap_set_bit(pirq->affinity, rt_hw_cpu_id());
     rt_bitmap_set_bit(pirq->affinity, rt_hw_cpu_id());
 
 
@@ -561,6 +571,20 @@ rt_err_t rt_pic_handle_isr(struct rt_pic_irq *pirq)
         err = RT_EOK;
         err = RT_EOK;
     }
     }
 
 
+#ifdef RT_USING_PIC_STATISTICS
+    rt_ktime_boottime_get_ns(&ts);
+    irq_time_ns = ts.tv_sec * (1000UL * 1000 * 1000) + ts.tv_nsec - pirq->stat.current_irq_begin[rt_hw_cpu_id()];
+    pirq->stat.sum_irq_time_ns += irq_time_ns;
+    if (irq_time_ns < pirq->stat.min_irq_time_ns || pirq->stat.min_irq_time_ns == 0)
+    {
+        pirq->stat.min_irq_time_ns = irq_time_ns;
+    }
+    if (irq_time_ns > pirq->stat.max_irq_time_ns)
+    {
+        pirq->stat.max_irq_time_ns = irq_time_ns;
+    }
+#endif
+
     return err;
     return err;
 }
 }
 
 
@@ -1022,7 +1046,6 @@ rt_err_t rt_pic_init(void)
 #if defined(RT_USING_CONSOLE) && defined(RT_USING_MSH)
 #if defined(RT_USING_CONSOLE) && defined(RT_USING_MSH)
 static int list_irq(int argc, char**argv)
 static int list_irq(int argc, char**argv)
 {
 {
-    rt_ubase_t level;
     rt_size_t irq_nr = 0;
     rt_size_t irq_nr = 0;
     rt_bool_t dump_all = RT_FALSE;
     rt_bool_t dump_all = RT_FALSE;
     const char *const irq_modes[] =
     const char *const irq_modes[] =
@@ -1074,6 +1097,10 @@ static int list_irq(int argc, char**argv)
     }
     }
 #endif
 #endif
 
 
+#ifdef RT_USING_PIC_STATISTICS
+    rt_kprintf(" max/ns      avg/ns      min/ns");
+#endif
+
     rt_kputs("\n");
     rt_kputs("\n");
 
 
     for (int i = 0; i < RT_ARRAY_SIZE(_pirq_hash); ++i)
     for (int i = 0; i < RT_ARRAY_SIZE(_pirq_hash); ++i)
@@ -1117,6 +1144,9 @@ static int list_irq(int argc, char**argv)
         {
         {
             rt_kprintf(" %-10d", pirq->isr.action.cpu_counter[cpuid]);
             rt_kprintf(" %-10d", pirq->isr.action.cpu_counter[cpuid]);
         }
         }
+    #endif
+    #ifdef RT_USING_PIC_STATISTICS
+        rt_kprintf(" %-10d  %-10d  %-10d", pirq->stat.max_irq_time_ns, pirq->stat.sum_irq_time_ns/pirq->isr.action.counter, pirq->stat.min_irq_time_ns);
     #endif
     #endif
         rt_kputs("\n");
         rt_kputs("\n");
 
 
@@ -1137,6 +1167,9 @@ static int list_irq(int argc, char**argv)
                 {
                 {
                     rt_kprintf(" %-10d", repeat_isr->action.cpu_counter[cpuid]);
                     rt_kprintf(" %-10d", repeat_isr->action.cpu_counter[cpuid]);
                 }
                 }
+            #endif
+            #ifdef RT_USING_PIC_STATISTICS
+                rt_kprintf(" ---         ---         ---");
             #endif
             #endif
                 rt_kputs("\n");
                 rt_kputs("\n");
             }
             }

+ 1 - 0
src/Kconfig

@@ -77,6 +77,7 @@ config RT_USING_SMP
 config RT_CPUS_NR
 config RT_CPUS_NR
     int "Number of CPUs"
     int "Number of CPUs"
     default 1
     default 1
+    range 1 1 if !RT_USING_SMP && !RT_USING_AMP
     help
     help
         Number of CPUs in the system
         Number of CPUs in the system