linux GPIO 中断 Demo

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

记录一下GPIO 中断demo,需要用的时候直接赋值修改即可。如果中断后判断高低电平,可以通过定时器加入一个防抖动的机制。


demo

/*
*	int gpio_iddig_irq; 是g_extcon结构体里的私有数据
*/
//g_extcon是全局 私有数据

int request_irq_func(struct device *dev)
{
	//申请中断
	g_extcon->gpio_iddig_irq = of_get_named_gpio(dev->of_node, "gpio-iddig-irq", 0);
	ret = devm_gpio_request(dev, g_extcon->gpio_iddig_irq, "gpio-iddig-irq");
	if (ret) {
		printk("%s request gpio %d failed: %d\n", __func__, g_extcon->gpio_iddig_irq, ret);
	} else {
		printk("%s 11 request gpio %d failed: %d\n", __func__, g_extcon->gpio_iddig_irq, ret);
		gpio_direction_input(g_extcon->gpio_iddig_irq);
	}

	ret = gpio_to_irq(g_extcon->gpio_iddig_irq);
    if (ret < 0) {
        gpio_free(g_extcon->gpio_iddig_irq);
		printk("%s gpio_to_irq gpio %d failed: %d\n", __func__, g_extcon->gpio_iddig_irq, ret);
    }

    ret = request_irq(ret, gpio_irq_handler, 
		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "gpio-iddig-irq", NULL);
    if (ret) {
        gpio_free(g_extcon->gpio_iddig_irq);
		printk("%s request_irq gpio %d failed: %d\n", __func__, g_extcon->gpio_iddig_irq, ret);
    }
	
	//定时器初始化	
	timer_init_func()return 0;
}

//中断处理函数
static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{
    /* 在这里编写中断发生时需要执行的代码 */
    printk("%s GPIO interrupt detected++!\n", __func__);

	//关闭中断,防止中断嵌套
	disable_irq_nosync(g_extcon->gpio_iddig_irq);

	//定时器处理,这个定时器是消抖()
	//这段内容懒得删除了,但是中断里面不建议使用定时器,容易出现内核崩溃的情况
	//具体为:bad: scheduling from the idle thread!
	//这里建议使用延时的工作队列去处理(线程也可以)
	mod_timer(&g_extcon->usb_ed_timer, HZ / 10);						//100ms消抖

	printk("%s GPIO interrupt detected--!\n", __func__);
    return IRQ_HANDLED;
}

//定时器初始化
int timer_init_func()
{
	/*
	*	struct timer_list usb_ed_timer;是全局g_extcon里的属性
	*/
	timer_setup(&g_extcon->usb_ed_timer, usb_ed_worker, 0);
	g_extcon->usb_ed_timer.expires = jiffies + HZ/10;						//100ms定时
	add_timer(&g_extcon->usb_ed_timer);
	return 0;
}

//定时器工作函数
static void usb_ed_worker(struct timer_list* timer_l)
{
	int value;
	printk("%s ++ \n", __func__);
	value = gpio_get_value(g_extcon->gpio_iddig_irq);
	
	if(value == 0) {
		//接入U盘等设备
		printk("%s plug in perih device \n", __func__);
	} else {
		//拔出U盘
		printk("%s plug out perih device \n", __func__);
	}
	printk("%s -- \n", __func__);
	//重新使能中断
	enable_irq(g_extcon->gpio_iddig_irq);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值