Linux kernel 中断之proc接口之interrupts

来源:互联网 发布:soulgame游戏制作软件 编辑:程序博客网 时间:2024/06/05 11:35
用于对中断观察的主要有两个文件,一个是proc/irq,另一个是proc/interrupts。
需要配置CONFIG_GENERIC_IRQ_SHOW
在proc目录下实现interrupts文件,用于获取中断发生次数统计:
fs/proc/interrupts.c

static const struct seq_operations int_seq_ops = { .start = int_seq_start, .next  = int_seq_next, .stop  = int_seq_stop, .show  = show_interrupts};

static int interrupts_open(struct inode *inode, struct file *filp){ return seq_open(filp, &int_seq_ops);}

static const struct file_operations proc_interrupts_operations = { .open  = interrupts_open, .read  = seq_read, .llseek  = seq_lseek, .release = seq_release,};

static int __init proc_interrupts_init(void)proc_create("interrupts", 0, NULL, &proc_interrupts_operations); return 0;}fs_initcall(proc_interrupts_init);

#ifdef CONFIG_GENERIC_IRQ_SHOW

int __weak arch_show_interrupts(struct seq_file *p, int prec){ return 0;}

int show_interrupts(struct seq_file *p, void *v){ static int prec;

 unsigned long flags, any_count = 0; int i = *(loff_t *) v, j; struct irqaction *action; struct irq_desc *desc;

 if (i > ACTUAL_NR_IRQS)  return 0;

 if (i == ACTUAL_NR_IRQS)  return arch_show_interrupts(p, prec);

 /* print header and calculate the width of the first column */ if (i == 0) {  for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)   j *= 10;

  seq_printf(p, "%*s", prec + 8, "");  for_each_online_cpu(j)   seq_printf(p, "CPU%-8d", j);  seq_putc(p, '\n'); }

 irq_lock_sparse(); desc = irq_to_desc(i); if (!desc)  goto outsparse;

 raw_spin_lock_irqsave(&desc->lock, flags); for_each_online_cpu(j)  any_count |= kstat_irqs_cpu(i, j); action = desc->action; if ((!action || irq_desc_is_chained(desc)) && !any_count)  goto out;

 seq_printf(p, "%*d: ", prec, i); for_each_online_cpu(j)  seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));

 if (desc->irq_data.chip) {  if (desc->irq_data.chip->irq_print_chip)   desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);  else if (desc->irq_data.chip->name)   seq_printf(p, " %8s", desc->irq_data.chip->name);  else   seq_printf(p, " %8s", "-"); } else {  seq_printf(p, " %8s", "None"); } if (desc->irq_data.domain)  seq_printf(p, " %*d", prec, (int) desc->irq_data.hwirq);#ifdef CONFIG_GENERIC_IRQ_SHOW_LEVEL seq_printf(p, " %-8s", irqd_is_level_type(&desc->irq_data) ? "Level" : "Edge");#endif if (desc->name)  seq_printf(p, "-%-8s", desc->name);

 if (action) {  seq_printf(p, "  %s", action->name);  while ((action = action->next) != NULL)   seq_printf(p, ", %s", action->name); }

 seq_putc(p, '\n');out: raw_spin_unlock_irqrestore(&desc->lock, flags);outsparse: irq_unlock_sparse(); return 0;}#endif

/proc # cat interruptscat interrupts           CPU0       CPU1   29:       0          0          GIC  arch_timer 30:    1923       1077          GIC  arch_timer 34:       0          0          GIC  fa608000.ap_dmas 38:       0          0          GIC  MIPI irq 43:       0          0          GIC  fa100000.gpu 44:       0          0          GIC  fa100000.gpu 45:       1          0          GIC  fa100000.gpu 49:     279          0          GIC  dwc3 51:    2856          0          GIC  malidp-de 52:       0          0          GIC  malidp-se 53:     392          0          GIC  isp_irq 

 
 
 

 

0 0
原创粉丝点击