diff --git a/components/drivers/include/drivers/pic.h b/components/drivers/include/drivers/pic.h index 8429007d16..5ab1434047 100755 --- a/components/drivers/include/drivers/pic.h +++ b/components/drivers/include/drivers/pic.h @@ -91,6 +91,16 @@ struct rt_pic_isr 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 { int irq; @@ -120,6 +130,9 @@ struct rt_pic_irq struct rt_pic *pic; 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); diff --git a/components/drivers/pic/Kconfig b/components/drivers/pic/Kconfig index 1f80b854b7..16c14105a0 100755 --- a/components/drivers/pic/Kconfig +++ b/components/drivers/pic/Kconfig @@ -4,6 +4,12 @@ menuconfig RT_USING_PIC depends on RT_USING_DM 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 int "IRQ max handlers" depends on RT_USING_PIC diff --git a/components/drivers/pic/pic.c b/components/drivers/pic/pic.c index 06081ac099..cdf8a8ff62 100644 --- a/components/drivers/pic/pic.c +++ b/components/drivers/pic/pic.c @@ -16,6 +16,7 @@ #include #include +#include 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_list_t *handler_nodes; 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->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 */ 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; } +#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; } @@ -1022,7 +1046,6 @@ rt_err_t rt_pic_init(void) #if defined(RT_USING_CONSOLE) && defined(RT_USING_MSH) static int list_irq(int argc, char**argv) { - rt_ubase_t level; rt_size_t irq_nr = 0; rt_bool_t dump_all = RT_FALSE; const char *const irq_modes[] = @@ -1074,6 +1097,10 @@ static int list_irq(int argc, char**argv) } #endif +#ifdef RT_USING_PIC_STATISTICS + rt_kprintf(" max/ns avg/ns min/ns"); +#endif + rt_kputs("\n"); 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]); } + #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 rt_kputs("\n"); @@ -1137,6 +1167,9 @@ static int list_irq(int argc, char**argv) { rt_kprintf(" %-10d", repeat_isr->action.cpu_counter[cpuid]); } + #endif + #ifdef RT_USING_PIC_STATISTICS + rt_kprintf(" --- --- ---"); #endif rt_kputs("\n"); } diff --git a/src/Kconfig b/src/Kconfig index 91eefbf5c6..1d4c0489d7 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -77,6 +77,7 @@ config RT_USING_SMP config RT_CPUS_NR int "Number of CPUs" default 1 + range 1 1 if !RT_USING_SMP && !RT_USING_AMP help Number of CPUs in the system