linux irq
linux irq
request_threaded_irq()参数含义
int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long irqflags, const char *devname, void *dev_id)
irq参数表示request的这个irq的irq number,此irq number为hw irq number,此number会反映在/proc/interrupts结果里,比如我一个ttyS0的irq number是32,则/proc/interrupts里会显示这个irq的number为32,同时这个irq number将等于irq_data里的hwirq成员;
devname,比如devname参数是"ttyS0",在/proc/interrupts里显示的devname将是ttyS0:
32: 430 0 0 0 GICv2 32 Level ttyS0
查看某一个irq发生的次数
1. /proc/interrupts
结果的第一列就是irq number
2. /proc/irq/$irq_num/spurious
在/proc/irq目录下各个注册的irq都会有一个目录,目录的名字就是其irq number,这个irq num和/proc/interrupts里的irq num是相等的
console:/proc/irq/98 # cat spurious count 275 unhandled 0 last_unhandled 0 ms
从spurious文件得知98号irq发生的次数是275
中断发生时会先关掉此中断以防止此中断嵌套
中断发生时先关掉此irq;然后进行中断处理;处理完后再打开此中断
中断发生时先关掉此irq callstack:
stacktrace for swapper/0-0: [ffffff800810f50c] chip_irq_mask+0x4c/0x44c [ffffff8008115bd0] arm_mask_irq+0x6c/0xcc [ffffff800892d53c] gic_eoimode1_mask_irq+0x68/0xd4 [ffffff8008211774] handle_fasteoi_irq+0x150/0x458 [ffffff80082078e4] __handle_domain_irq+0x138/0x1e0 [ffffff8008083ec8] gic_handle_irq+0x50/0xbc [ffffff8008085ee8] el1_irq+0xe8/0x190 [ffffff80081b540c] try_to_wake_up+0x6cc/0x9a0 [ffffff800823df5c] process_timeout+0x28/0x34 [ffffff8008241760] call_timer_fn+0x134/0x29c
关中断就是将此irq的mask bit set(mask)
处理完后再打开此中断callstack:
stacktrace for swapper/0-0: [ffffff800810f958] chip_irq_unmask+0x4c/0x44c [ffffff8008115c9c] arm_unmask_irq+0x6c/0xcc [ffffff800892e8e8] gic_unmask_irq+0x68/0xa0 [ffffff800820fe3c] irq_enable+0xa4/0xf8 [ffffff800820fbb8] irq_startup+0x98/0x278 [ffffff800820d45c] enable_irq+0x84/0x17c
chip_irq_unmask()是SOC自己的实现,enable irq就是将这个irq的mask bit clear(unmask)
中断处理“下半部”机制
https://blog.csdn.net/myarrow/article/details/9287169
中断「interrupt」(IPI interrupt)
https://chasinglulu.github.io/2019/07/07/%E4%B8%AD%E6%96%AD%E3%80%8Cinterrupt%E3%80%8D/