

Linux驱动开发-外部中断的注册使用(按键为例)
source link: https://blog.51cto.com/u_11822586/5235391
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Linux驱动开发-外部中断的注册使用(按键为例)
原创DS小龙哥 2022-04-21 09:09:22 博主文章分类:Linux驱动及系统编程 ©著作权
1. 外部中断介绍
前面有篇文章使用杂项设备完成了按键驱动的编写,实现了按键轮询检测,通过read函数向应用层传递按键值,这篇文章使用按键为例,介绍Linux内核里中断的注册方法,使用中断的方式检测按键是否按下,中断在单片机、设备驱动开发里使用的都非常多,可以更加实时的检测到按键触发的情况。
Linux内核提供了中断的注册接口:
(1)注册中断
头文件 include\linux\interrupt.h
定义文件 include\linux\interrupt.h
函数原型 int request_irq(unsigned int irq,/*做实参传递给中断服务函数第1个参数*/
irq_handler_t handler, /*中断服务函数指针*/
unsigned long flags,
const char *name,
void *dev_id); /*做实参传递给中断服务函数第2个参数*/
函数功能 向内核注册一个中断服务函数;
当发生中断号为 irq 的中断时候,会执行 handler 指针函数。
函数参数
irq:中断编号(每个中断源有惟一的编号)。
handler:中断服务函数指针。
原型 typedef irqreturn_t (*irq_handler_t)(int, void *)。
flag:中断的标志,用来描述本中断的基本特征的。
有固定的值,由中断源的特征决定;
比如外中断有:上升沿,下降沿触发中断这类标志。
name:中断名字, 注册后会出现cat /proc/interrupts
dev_id: 这个参数是传递给中断服务函数。
对共享中断来说, 这个参数一定有要;
当注销共享中断中的其中一个时, 用这个来标识要注销哪一个。
对于有惟一入口的中断,可以传递 NULL;
但是一般来说都会传递一个有意义指针,在中断程序中使用, 以方便编程。
返回值 0 表示成功
-EINVAL (无效参数22)表示中断号无效。
-EBUSY (设备或者资源忙16)表示中断已经被占用。
(2)注销中断
void free_irq(unsigned int irq,void * dev_id)
irq: 要注销的中断号
dev_id:其实就是注册时候使用的dev参数,在共享中断必不可少,不能传递NULL。
注意:为了防止在注销时同时发生中断,调用时候,先禁止中断。
(3)中断开启与关闭
禁止中断
void disable_irq_nosync(unsigned int irq);
void disable_irq(unsigned int irq);
参数:irq,要禁止的中断对应的编号。
注意:在中断服务程序中不能使用 disable_irq 这个函数,否则内核崩溃,可以使用 disable_irq_nosync。
disable_irq:函数调用后,函数不会马上返回,而等待中断程序执行完成才返回,在中断调用会导致死锁。
disable_irq_nosync:调用后,函数马上返回。
使能中断
void enable_irq(unsigned int irq);
参数:irq,要使能的中断对应的编号
(4)获取irq中断号
int gpio_to_irq(unsigned gpio);
2. 外部中断驱动编写
2.1 按键原理图
2.2 驱动示例代码
insmod
安装驱动之后就直接注册按键中断,没有注册字符设备框架,当按键按下之后,直接在驱动层通过printk
打印数据提示到终端。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
/*存放按键的信息*/
struct m_key_info
{
int gpio;
char name[50];
int val;
int irq;
};
struct m_key_info key_info[]=
{
{EXYNOS4_GPX3(2),"key_irq_1",0x01},
{EXYNOS4_GPX3(3),"key_irq_2",0x02},
{EXYNOS4_GPX3(4),"key_irq_3",0x03},
{EXYNOS4_GPX3(5),"key_irq_4",0x04},
};
/*
中断服务函数
*/
static irqreturn_t key_irq_handler(int irq, void *dev)
{
struct m_key_info *p=(struct m_key_info*)dev;
if(gpio_get_value(p->gpio)==0) //判断按键是否按下
{
printk("按键值:%#x\n",p->val);
}
else
{
printk("按键值:%#x\n",p->val|0x80);
}
return IRQ_HANDLED;
}
static int __init tiny4412_interrupt_drv_init(void)
{
int i;
for(i=0;i<sizeof(key_info)/sizeof(key_info[0]);i++)
{
/*1. 获取中断号*/
key_info[i].irq=gpio_to_irq(key_info[i].gpio);
/*2. 注册中断*/
if(request_irq(key_info[i].irq,key_irq_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,key_info[i].name,&key_info[i]))
{
printk("中断号%d注册失败:%s\n",key_info[i].irq,key_info[i].name);
}
}
printk("按键中断 驱动注册-安装成功.\n");
return 0;
}
static void __exit tiny4412_interrupt_drv_exit(void)
{
/*注销中断*/
int i=0;
for(i=0;i<sizeof(key_info)/sizeof(key_info[0]);i++)
{
free_irq(key_info[i].irq,&key_info[i]);
}
printk("按键中断 驱动注销成功.\n");
}
/*驱动入口*/
module_init(tiny4412_interrupt_drv_init);
/*驱动出口*/
module_exit(tiny4412_interrupt_drv_exit);
/*许可证*/
MODULE_LICENSE("GPL");
2.3 makefile代码
KER_DRI=/home/wbyq/work/linux-3.5/linux-3.5
all:
make -C $(KER_DRI) M=`pwd` modules
cp *.ko /home/wbyq/work/rootfs/code -f
make -C $(KER_DRI) M=`pwd` modules clean
obj-m += interrupt_key.o
- 赞
- 收藏
- 评论
- 分享
- 举报
Recommend
-
6
HAL 库开发笔记(三)- 外部中断上一篇文章我们提到,用轮询的方法消除按键抖动、检测输入,有可能会消耗过多的系统资源并导致卡机,也有可能会错过检测。这就是为什么我们需要使用中断了。基本原理
-
7
请保留-> 【原文: https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】 上一篇中,实现了按键的控制功能。...
-
5
ivshmem PCI设备中断机制驱动示例ivshmem-doorbell提供了两种中断方式,一种是传统的基于INTx的中断, 它主要使用BAR0的Interrupt Mask和Interrupt Status两个寄存器;另一种是基于MSI-...
-
8
在Switch上使用Arduino Uno R3开发板模拟手柄按键连发 发表于...
-
5
嵌入式软件设计(外部中断输入)
-
10
Netflix iOS应用加入外部连接按键,可直接官网购买订阅
-
4
STM32CubeMX之外部中断1.中断简介 中断,是指处理机处理程序运行中出现的紧急事件的整个过程。程序运行过程中,系统外部、系统内部或者现行程序本身若出现紧急事件,处理机立即中止现行程序的运行,自动转入相应的处理程序...
-
6
SpringBoot部署到外部Tomcat无法注册到Nacos服务端 - 东北小狐狸 - 博客园 近期做一个项目投标演示(POC)环境支持,需要集成Nacos服务端。考虑到现有项目中已经有了Nacos相关依赖,那还不简单?新建个服务端,配置几下重启不就搞定...
-
7
全志V3S嵌入式驱动开发(多按键输入驱动) ...
-
9
用户在使用驱动人生时,驱动人生能检测驱动异常但没有修复按键,一般是驱动人生软件文件损坏、不完整导致的,我们只要先将它卸载然后重新下载就可以啦,下面看看详细解决方法吧! 驱动人生能检测驱动异常但没有修复按键: 1、...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK