在前面的文章中,已经描述了一个字符设备驱动模型和如何控制字符设备,现在需要来考虑一下,对于字符设备的输入型设备,如何来获取其信息,这里以按键驱动为例。
一、设备的操作方式
1、理论基础
通常而言,对于像按键这样的设备,在Linux内核均使用中断的方式来监控按键的状态。在Linux内核中使用request_irq接口来注册一个中断。其原型如下:
- irq:中断号
- handler:其原型为typedef irqreturn_t (*irq_handler_t)(int, void *);这个回调函数作为中断处理程序。
- flags:与中断管理相关的标志选项
实际上就是外部中断的触发方式。 - name:设备的名称
- dev:共享中断时使用,表示设备的ID,即为dev_id,共享中断号。
- 返回值:返回0时表示成功,失败时返回一个错误码。
2、中断的注册
对于中断的注册,实际上只需要使用接口request_irq直接注册即可。首先第一件事就是查看原理图:
从以上原理图可知,按键与CPU的哪些接口进行连接,在这里我们先实现1路按键,使用的是KEY1,KEY1与CPU的GPH0_0口进行连接。并且当按键按下时,GPIO口的电平状态为低电平。
我们想要注册关于KEY1的外部中断,就必须找到代表GPH0_0口的中断号。笔者在这里使用的CPU为S5PV210,所以根据其Datasheet分析如下:
当需要将GPH0_0口作为外部中断功能使用时,需要将GPH0CON寄存器的位[3:0]配置为1111b,作为EXT_INT[0],实际上就是外部中断0。
在Linux板级文件夹中包含有关于中断相关的参数的定义或者声明,笔者使用的是S5PV210,所以其路径为:linux-3.0.8/arch/arm/mach-s5pv210/include/mach/irqs.h
如上图IRQ_EINT0就是外部中断0的中断号了(注:在此对于中断只做简述,后续的文章再对中断进行详细的分析)。
二、在Linux内核空间监听外部中断
1、确定硬件接口
在前面的原理图的分析中,已知所使用的按键KEY1所连接的I/O口为GPH0_0口,需要将其配置为外部中断EXT_INT[0](外部中断0);
2、设备结构体的定义
如上图为所定义的结构,GPH0CON为GPH0口的基地址,struct
key_device结构体作为按键驱动所包含的内容,dev_class为设备类指针,和成员dev在创建设备节点是需要,并且表示一个设备;cdev表示字符设备,chrdev小时设备号。
定义一个结构指针:struct key_device* button_dev;
3、设备的初始化
如上图所示,还是基于最基本的字符设备驱动模型进行编写的程序,我们所需要关注的应该是两个新内容,分别是硬件的初始化button_hw_init();和中断的申请与注册request_irq。
4、硬件初始化函数button_hw_init
实际上非常简单,就是将GPH0CON寄存器的位[3:0]配置为1111b,
5、中断的申请、注册与响应
IRQ_EINT0为中断号:Key_hw_interrupt为中断服务程序的入口地址;IRQF_TRIGGER_FALLING标志这下降沿产生中断,因为当按键按下时,产生下降沿;中断名称为key,不使用共享中断。
当按键按下是,产生中断,可以通过判断GPH0DAT寄存器的位[0]的状态来判断是不是当前已经产生了中断。在这里对中断的处理就是打印出响应的标识printk("key1
down! ");。
6、关于程序中的struct file_operations
在注册字符设备的时候,也注册了一个struct file_operations,即为:
因为这个程序只是作为一个功能的验证,并没有使用到应用程序,所以struct file_operations的定义非常简单。
7、卸载函数所做的操作
在这里特别注意的一点就是,因为在驱动程序在进行装载时,申请了中断和button_dev堆空间,所以在卸载驱动是,需要将其释放,分别是free_irq(IRQ_EINT0,
0);和kfree(button_dev);。
8、Makefile
三、实验现象
将内核驱动进行编译,得到button_driver.ko文件,将其拷贝到开发板的根文件系统。执行命令:insmod
button_driver.ko插入内核驱动模块。然后按下按键,有如下效果显示:
更多Linux教程请查看菜单
Linux字符设备驱动模型之操作函数集
Linux字符设备驱动模型之设备号
Linux字符设备驱动模型之框架解说
Linux字符设备驱动模型之字符设备驱动代码模板
Linux字符设备驱动模型之Linux内核模块参数
Linux字符设备驱动模型之字符设备初始化
Linux字符设备驱动模型之Linux内核驱动访问揭秘
Linux字符设备驱动模型之点亮LED灯
Linux字符设备驱动模型之在Linux内核源码中编写驱动