创客神器NanoPi
直播中

midaszhou

10年用户 27经验值
擅长:处理器/DSP RF/无线
私信 关注
[问答]

NanoPi-NEO 的GPIO外部中断例子

一直想找一个NanoPi-NEO  GPIO外部中断C例子,没有找到。 请大神!

回帖(11)

midaszhou

2017-7-21 10:19:05
试了一下PG11脚,用 gpio_to_irq(203) 可以取得中断号 91
GPIO 24PIN管脚定义.JPG
举报

midaszhou

2017-7-22 14:51:52
百度了一下,凑了一段代码出来,直接在nanopi-neo里面make出gpio_int.ko模块。

/*----------------------------  gpio_int.c -----------------------*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

static unsigned int gpio_num=203; //--linux num. for GP11
unsigned int int_num=0;//--interrupter number

static struct work_struct int_wq; //--work queue for INT handler low part

static void enable_int_wq(struct work_struct *data)
{
   printk(KERN_INFO"Entering work_queue and start msleep....n");
   msleep_interruptible(3000);
   printk(KERN_INFO"Re-enable irq now....n");
   enable_irq(int_num);
}

static irqreturn_t int_handler(int irq, void *dev_id)
{
   printk(KERN_INFO "------ gpio_to_irq(PG11) triggered! -----n");
   printk(KERN_INFO "Disable irq ...n");
   disable_irq_nosync(int_num); //--!!!Must NOT use disable_irq() anyway,it's cause deadloop and will crash the kernel

   //----- irq handler low part -------
   schedule_work(&int_wq);

   return IRQ_HANDLED;
}


static int register_gpio_irq(void)
{
   int int_result=0;

   int_result=request_irq(int_num,int_handler,IRQF_TRIGGER_RISING,"GPIO_INT_Midas",(void *)&gpio_num);
   if(int_result != 0)
   {
        printk(KERN_EMERG "--- GPIO request irq failed! ---n");
   }

   return int_result;
}

static int __init gpio_int_init(void)
{
   int ret=-1;

   printk(KERN_INFO"------ Start init gpio_int -----n");

   gpio_set_value(gpio_num,0);
   gpio_direction_input(gpio_num); //-set gpio direction
   int_num=gpio_to_irq(gpio_num);
   if(int_num>0)
          printk(KERN_INFO "------ gpio_to_irq(PG11):%d -----n",int_num);
   else
          return -1;

   ret=register_gpio_irq();

   if(ret!= 0)
   {
          printk(KERN_EMERG "----- register_gpio_irq() failed! ----n");
        return -1;
   }
      else
          //---init wor-queue for irq-handler low part
      INIT_WORK(&int_wq,enable_int_wq);

        return 0;
}

static void __exit gpio_int_exit(void)
{

  if(int_num > 0)
            free_irq(int_num,(void *)&gpio_num); //---!!! void *dev_id MUST be presented,even no IRQF_SHARED flag in request_irq()
  printk(KERN_EMERG "------ gpio interrupt test exit -----n");

}

module_init(gpio_int_init);
module_exit(gpio_int_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux");
MODULE_DESCRIPTION("gpio-int-test");

/*----------------------------  END -----------------------*/
举报

midaszhou

2017-7-22 15:03:13
接好线,加载gpio_test.ko模块后就可以工作了
GPIO-INT-TEST.JPG
举报

midaszhou

2017-7-22 15:17:19
但是有个问题,disable_irq_nosync()好像并不能关闭硬件中断,在关闭irq期间产生的中断标记位似乎都被记录下来了,当再次enable_irq()的时候,就会再次触发中断程序的执行....
举报
  • gg.JPG

更多回帖

发帖
×
20
完善资料,
赚取积分