Beaglebone Black(Linux BBBW 4.14.71-ti-r80)上的“向量XX处的意外IRQ陷阱”

时间:2019-04-11 09:02:58

标签: beagleboneblack interrupt-handling

我对beaglebone black的中断处理有问题。我编写了自己的内核模块和用户空间驱动程序的组合,以访问gpios(另请参见https://github.com/Terstegge/gpio-bbb)。使用较旧的内核,一切工作正常。使用最新的debian映像(内核4.14.71-ti-r80),内核日志中出现错误:

&&

我的工作如下:在模块代码中,我致电[ 461.028013] gpio_bbb: Device /dev/gpio_bbb registered [ 507.507335] gpio_bbb: Requesting GPIO #30 [ 507.507370] Mode: f [ 507.507383] gpio_bbb: Requesting GPIO #49 [ 507.507395] Mode: 37 [ 507.507405] gpio_bbb: Requesting GPIO #15 [ 507.507414] Mode: 37 [ 507.507656] gpio_bbb: Using IRQ #77 for GPIO #49 [ 507.507821] gpio_bbb: Using IRQ #78 for GPIO #15 [ 571.511409] irq 77, desc: db1ad800, depth: 0, count: 0, unhandled: 0 [ 571.511429] ->handle_irq(): c01ab7b0, [ 571.511458] handle_bad_irq+0x0/0x2c0 [ 571.511463] ->irq_data.chip(): dc122910, [ 571.511476] 0xdc122910 [ 571.511481] ->action(): dc454600 [ 571.511487] ->action->handler(): bf4c904c, [ 571.511514] gpio_irq_handler+0x0/0x34 [gpio_bbb] [ 571.511524] IRQ_NOPROBE set [ 571.511532] unexpected IRQ trap at vector 4d 以获取irq号,然后致电gpio_to_irq()。这两个调用似乎都有效,因为它们没有报告错误代码(请参见上面的日志文件):

request_irq()

启动测试程序时,我可以看到我的模块(gpio_bbb)已为/ proc / interrupts中的中断注册:

  /* request the irq and install handler */
  if (!irq_enabled[gpio_num]) {
    irq = gpio_to_irq(gpio_num);
    /* request irq and install handler */
    ret = request_irq (irq, gpio_irq_handler, IRQF_SHARED, "gpio_bbb", &gpio_data);
    if (ret != 0) {
      printk(KERN_ERR MOD_STR"Failed to request IRQ %i (error %i)\n", irq, ret);
      return ret;
    }
    printk(KERN_INFO MOD_STR"Using IRQ #%i for GPIO #%i\n", irq, gpio_num);
    irq_enabled[gpio_num] = irq;
  }

在触发一些中断(gpio输入值更改)和(甚至)使用空中断处理程序触发时,它什么都不做:

           CPU0       
...
 62:          0  tps65217   2 Edge      tps65217_pwr_but
 63:       5822  44e07000.gpio  29 Edge      wl18xx
 77:          0  4804c000.gpio  17 Edge      gpio_bbb
 78:          0  44e07000.gpio  15 Edge      gpio_bbb
IPI0:          0  CPU wakeup interrupts
IPI1:          0  Timer broadcast interrupts

我在内核日志中收到以上错误消息,并且未处理我的中断:(我注意到中断号已更改(以前,gpio的irq编号为#gpio + 128)。我也知道显然正在运行的新libgpiod中(我看到了/dev/gpiochip[0..3]设备)我的问题是否与这些更改有关? 我仍然有些困惑,因为我调用的所有方法似乎都可以正常工作,而且我的中断仍被处理为“意外”。我在做什么错??

1 个答案:

答案 0 :(得分:0)

我已经更深入地研究了这个问题。简单的解决方案是在调用irq_set_irq_type(irq, IRQ_TYPE_NONE)之后添加request_any_context_irq()(现在应使用此方法代替request_irq()):

ret = request_any_context_irq (irq, _gpio_irq_handler, IRQF_SHARED, "gpio_bbb", &gpio_data);
if (ret < 0) {
  printk(KERN_ERR MOD_STR"Failed to request IRQ %i (error %i)\n", irq, ret);
  return ret;
}
// Set IRQ type
irq_set_irq_type(irq, IRQ_TYPE_NONE);

这些变化似乎是必要的,因为linux中有新的通用irq系统:https://www.kernel.org/doc/html/v4.12/core-api/genericirq.html。我尚未完全理解IRQ类型为何以及如何影响内部调用的方法,但是gpio模块仍按预期运行。