12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /*
- * Copyright (c) 2018 Nordic Semiconductor ASA
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <sys/printk.h>
- #include <kernel_internal.h>
- #include <ksched.h>
- #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; i<IRQ_TABLE_SIZE; i++) {
- ite = &_sw_isr_table[i];
- if (ite->isr != 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 */
|