Как обнаружить прерывание на линии GPIO во встроенном Linux?

#c #linux #interrupt #gpio #pandaboard

#c #linux #прерывание #gpio #pandaboard

Вопрос:

Прерывание генерируется каждые 10 мс на GPIO_39 в pandaboard OMAP4. Я зарегистрировал обработчик для этого в коде драйвера Linux, но обработчик не вызывается, поскольку прерывание не обнаруживается.

Я убедился на аппаратном уровне (путем проверки вывода gpio), что прерывание действительно генерируется. Дело только в том, что программное обеспечение не может его обнаружить.

В моем коде драйвера есть следующее.

 #define GPIO_NO     39

  iowrite16(0x3, gpio_39_address   2); /* Configured the pin 22 to be used as gpio. */

  ret = gpio_request(GPIO_NO, "Claiming GPIO");
  if(ret < 0)
  {
    printk(KERN_ALERT "%s: Claiming GPIO_%d failedn", __func__, GPIO_NO);
    return -1;
  }
  else
  {
    printk(KERN_INFO "%s: Claiming GPIO_%d successfuln", __func__, GPIO_NO);
  }

  ret = gpio_direction_input(GPIO_NO);  
  if(ret < 0)
  {
    printk(KERN_INFO "%s: Setting GPIO direction to input failedn", __func__);
    return -1;
  }
  else
  {
    printk(KERN_INFO "%s: Direction of GPIO_%d set to inputn", __func__, GPIO_NO);
  }

  GPIO_IRQ = gpio_to_irq(GPIO_NO);

  if(GPIO_IRQ < 0)
  {
    printk(KERN_INFO "%s: Mapping GPIO_%d to IRQ failedn", __func__, GPIO_NO);
    return -1;
  }
  else
  {
    printk(KERN_INFO "%s: Mapping GPIO_%d to IRQ_%d successfuln", __func__, GPIO_NO, GPIO_IRQ);
  }

  if((request_irq(GPIO_IRQ, ten_ms_int, IRQF_TRIGGER_FALLING, DEVICE_NAME, NULL)))
  {
    printk(KERN_ALERT "%s: requeseting GPIO_IRQ %d failedn", __func__, GPIO_IRQ);
    return -1;
  }
  else
  {
    printk(KERN_INFO "%s: requesting GPIO_IRQ %d successfuln", __func__, GPIO_IRQ);
  }

irqreturn_t ten_ms_int(int irq, void *dev_id)
{
  T_UINT32 l;
  /* Enable spi channel */
  l = ioread32(spi_base   SPI_CHCONF0);
  l |= SPI_CHCONF0_FORCE;
  iowrite32(l, (spi_base    SPI_CHCONF0));

  l = ioread32(spi_base   SPI_CHCTRL0);
  l |= SPI_CHCTRL_EN;
  iowrite32(l, (spi_base   SPI_CHCTRL0));

  /* Enable dma channel 0 */
  l = ioread32(sdma_base   SDMA_CCR(CHANNEL0));
  l |= SDMA_CCR_ENABLE;
  iowrite32(l, sdma_base   SDMA_CCR(CHANNEL0));

  /* Enable dma channel 1 */
  l = ioread32(sdma_base   SDMA_CCR(CHANNEL1));
  l |= SDMA_CCR_ENABLE;
  iowrite32(l, sdma_base   SDMA_CCR(CHANNEL1));
  //printk(KERN_INFO "%s: 10ms interrupt detected %dn", __func__, irq); /* I know that I've to remove this printk statement */
  return IRQ_HANDLED;
}
  

GPIO_39 принадлежит банку GPIO2, и соответствующий номер прерывания равен 32. Но возвращаемое значение gpio_to_irq() равно 199. Это еще одна причина для беспокойства.

Пожалуйста, дайте мне знать, если что-то не так в коде или я что-то пропустил.

Комментарии:

1. Ваш код в основном выглядит нормально. Я думаю, что ваш первый iowrite, вероятно, в лучшем случае не нужен, что он должен делать? Проверили ли вы свои настройки мультиплексирования контактов и убедились, что можете считывать сигнал прерывания как значение (например, с помощью пользовательского интерфейса).

2. Первый iowrite — это часть мультиплексирования выводов.

3. Если вы используете пользовательский интерфейс, можете ли вы правильно определить уровень внешнего сигнала?

Ответ №1:

Явно укажите вывод GPIO для обнаружения падающего края.

На уровне модуля gpio необходимо включить FALLING_DETECT gpio.