确定设备树中使用的虚拟中断号
在imx6ull的芯片用户手册中,的第三章中断中。有一些保留的寄存器可以用来触发GIC SPI中断。
如何触发中断
可以使用devmem2命令在直接写GIC的PENDING寄存器
这个是在GIC手册里写的,并不在imx6ull的手册里
GICD_ISPENDRn有多个寄存器,每个寄存器中每一位对应一个GIC中断,写入1就可以触发中断
我们在设备树中使用的中断号是122,那么加上32。 122+32 = 154就是GIC的中断号,每一个GIC有32位,可以表示32个中断。
那么154/32 = 4…26,所以用到第5个寄存器中的,第26位。
GIC在上面的基地址是0x200,那么第5个寄存器偏移地址为0x200+(4*4)+Distribution地址(0x00a01000) = 0x00a01210
对应devmem2的写入基地址,然后第26位置1。写入的值就是0x4000000
实验步骤记录
显示内核日志:
echo "7 4 1 7" > /proc/sys/kernel/printk
root@npi:~/100ask# insmod virtual_int_controller.ko
[ 67.405164] virtual_intc_init 138
[ 67.405669] virtual_intc_probe irq_to_parent = 74
[ 67.405880] virtual_intc_probe irq_base = 237
这里提示向上的中断是74号,这是chained_intc对应的虚拟中断号
这里由于使用了legacy的分配方式,4个子中断号会一起分配出来。一开始的中断号是237。
# 查看注册的中断号
root@npi:/sys/kernel/irq/78# cd /sys/kernel/irq/74
root@npi:/sys/kernel/irq/74# ls
actions chip_name hwirq name per_cpu_count type wakeup
root@npi:/sys/kernel/irq/74# cat chip_name
GIC-0
root@npi:/sys/kernel/irq/74# cat hwirq
154
root@npi:/sys/kernel/irq/74# cd ../237
root@npi:/sys/kernel/irq/237# ls
actions chip_name hwirq name per_cpu_count type wakeup
root@npi:/sys/kernel/irq/237# cat hwirq
0
root@npi:/sys/kernel/irq/237# cat chip_name
100ask_virtual_intc
root@npi:/sys/kernel/irq/237# cd ../238/
root@npi:/sys/kernel/irq/238# cat hwirq
1
root@npi:/sys/kernel/irq/238# cat chip_name
100ask_virtual_intc
root@npi:/sys/kernel/irq/238# cat ../239/hwirq
2
root@npi:/sys/kernel/irq/238# cat ../239/chip_name
100ask_virtual_intc
root@npi:/sys/kernel/irq/238# cat ../240/hwirq
3
root@npi:/sys/kernel/irq/238# cat ../240/chip_name
100ask_virtual_intc
# 装载gpio驱动程序
root@npi:~/100ask# insmod gpio_key_drv.ko
[ 521.062571] /home/chen/Documents/mygit/100ask_rk3288_module/16_interrupt/01_virtua
l_interrupt/gpio_key_drv.c gpio_key_init line 97
[ 521.085613] /home/chen/Documents/mygit/100ask_rk3288_module/16_interrupt/01_virtua
l_interrupt/gpio_key_drv.c gpio_key_probe line 53
[ 521.100161] virtual_intc_irq_unmask 55
[ 521.105632] devm_request_irq 237 for 100ask_virtual_key0, err = 0
[ 521.114816] virtual_intc_irq_unmask 55
[ 521.120082] devm_request_irq 238 for 100ask_virtual_key1, err = 0
[ 521.126262] virtual_intc_irq_unmask 55
[ 521.132005] devm_request_irq 239 for 100ask_virtual_key2, err = 0
[ 521.138387] virtual_intc_irq_unmask 55
[ 521.142207] devm_request_irq 240 for 100ask_virtual_key3, err = 0
# 这里申请的就是237~240,和上面的中断号对应
root@npi:~/100ask# cat /proc/interrupts
#.....注册了4个中断函数
237: 0 100ask_virtual_intc 0 Edge 100ask_virtual_key0
238: 0 100ask_virtual_intc 1 Edge 100ask_virtual_key1
239: 0 100ask_virtual_intc 2 Edge 100ask_virtual_key2
240: 0 100ask_virtual_intc 3 Edge 100ask_virtual_key3
#.....
可以使用devmem2来触发imx6ull的中断:
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 251.270794] virtual_intc_irq_ack 40
[ 251.275143] key 100ask_virtual_key0 0
Memory mapped at address 0x76f92000.
Value at address 0xA01210 (0x76f92210): 0x0
Written 0x4000000; readback 0x4000000
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 361.006812] virtual_intc_irq_ack 40
[ 361.011162] key 100ask_virtual_key1 0
Memory mapped at address 0x76f43000.
Value at address 0xA01210 (0x76f43210): 0x0
Written 0x4000000; readback 0x4000000
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 363.896727] virtual_intc_irq_ack 40
[ 363.901077] key 100ask_virtual_key0 1
Memory mapped at address 0x76f9f000.
Value at address 0xA01210 (0x76f9f210): 0x0
Written 0x4000000; readback 0x4000000
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 364.766890] virtual_intc_irq_ack 40
[ 364.770937] key 100ask_virtual_key1 1
Memory mapped at address 0x76f72000.
Value at address 0xA01210 (0x76f72210): 0x0
Written 0x4000000; readback 0x4000000
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 365.466905] virtual_intc_irq_ack 40
[ 365.471245] key 100ask_virtual_key0 2
Memory mapped at address 0x76f78000.
Value at address 0xA01210 (0x76f78210): 0x0
Written 0x4000000; readback 0x4000000
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 366.096701] virtual_intc_irq_ack 40
[ 366.101046] key 100ask_virtual_key1 2
Memory mapped at address 0x76f1b000.
Value at address 0xA01210 (0x76f1b210): 0x0
Written 0x4000000; readback 0x4000000
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 366.736501] virtual_intc_irq_ack 40
[ 366.740830] key 100ask_virtual_key2 0
Memory mapped at address 0x76f24000.
Value at address 0xA01210 (0x76f24210): 0x0
Written 0x4000000; readback 0x4000000
如果修改virtual_intc_controller.c的触发函数为电平触发
//irq_set_chip_and_handler(virq, &virtual_intc_irq_chip, handle_edge_irq);
irq_set_chip_and_handler(virq, &virtual_intc_irq_chip, handle_level_irq);
结果就有mask和unmask函数了
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 320.670037] virtual_intc_irq_mask_ack 50
[ 320.674982] key 100ask_virtual_key2 0
[ 320.678693] virtual_intc_irq_unmask 55
Memory mapped at address 0x76fd6000.
Value at address 0xA01210 (0x76fd6210): 0x0
Written 0x4000000; readback 0x4000000
root@npi:~/100ask# devmem2 0x00a01210 w 0x4000000
/dev/mem opened.[ 414.802182] virtual_intc_irq_mask_ack 50
[ 414.806964] key 100ask_virtual_key1 0
[ 414.810675] virtual_intc_irq_unmask 55
Memory mapped at address 0x76ff7000.
Value at address 0xA01210 (0x76ff7210): 0x0
Written 0x4000000; readback 0x4000000
版权声明:本文为ch122633原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。