/* * Copyright (c) 2018 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #ifdef CONFIG_TRACING_IRQ_PROFILER #define RUNNING_CYCLES(end, start) ((uint32_t)((long)(end) - (long)(start))) #ifdef CONFIG_TRACING_IRQ_PROFILER_IRQLOADING #define RUNNING_TIMES(end, start) ((uint32_t)((long)(end) - (long)(start))) extern void idle(void *unused1, void *unused2, void *unused3); static u32_t cpuload_isr_total_cycles; static u32_t cpuload_isr_in_idle_cycles; static u32_t irq_pre_total_us[IRQ_TABLE_SIZE]; #endif void isr_wrapper_with_profiler(u32_t irqnum) { u32_t ts_irq_enter, irq_cycles; u32_t stop_cycle; #ifdef CONFIG_TRACING_IRQ_PROFILER_IRQLOADING static u32_t pre_time, curr_time; u32_t i, print_flag = 0; #endif struct _isr_table_entry *ite; irqnum >>= 3; ts_irq_enter = k_cycle_get_32(); ite = &_sw_isr_table[irqnum]; if(ite->isr){ ite->isr(ite->arg); } ite->irq_cnt++; stop_cycle = k_cycle_get_32(); irq_cycles = RUNNING_CYCLES(stop_cycle, ts_irq_enter); ite->irq_total_us += k_cyc_to_ns_floor64(irq_cycles) / 1000; if (irq_cycles > ite->max_irq_cycles) ite->max_irq_cycles = irq_cycles; #ifdef CONFIG_TRACING_IRQ_PROFILER_MAX_LATENCY if(irq_cycles >= CONFIG_TRACING_IRQ_PROFILE_MAX_LATENCY_CYCLES){ printk("irq@%d run %dus not meet latency\n", irqnum, (u32_t)(k_cyc_to_ns_floor64(irq_cycles) / 1000)); } #endif #ifdef CONFIG_TRACING_IRQ_PROFILER_IRQLOADING cpuload_isr_total_cycles += RUNNING_CYCLES(stop_cycle, ts_irq_enter); if (_current->entry.pEntry == idle) { cpuload_isr_in_idle_cycles += RUNNING_CYCLES(stop_cycle, ts_irq_enter); } curr_time = k_uptime_get_32(); if ((curr_time - pre_time) > 1000) { pre_time = curr_time; for (i=0; iisr != z_irq_spurious) { if ((RUNNING_TIMES(ite->irq_total_us, irq_pre_total_us[i]) > 60000)) { printk("current irq@%d overtime run %dus\n", i, RUNNING_TIMES(ite->irq_total_us, irq_pre_total_us[i])); print_flag = 1; } irq_pre_total_us[i] = ite->irq_total_us; } } /* > (300ms) (9677000/1000)*31 */ /* SYS_CLOCK_HW_CYCLES_TO_NS_AVG(1000, 1000) = 31us */ if ((cpuload_isr_total_cycles > 9677000) || print_flag) { printk("(%u)total isr %d us, in idle %d us\n", curr_time, SYS_CLOCK_HW_CYCLES_TO_NS_AVG(cpuload_isr_total_cycles, 1000), SYS_CLOCK_HW_CYCLES_TO_NS_AVG(cpuload_isr_in_idle_cycles, 1000)); } cpuload_isr_total_cycles = 0; cpuload_isr_in_idle_cycles = 0; } #endif } #endif /* CONFIG_TRACING_CPU_STATS_LOG */