在嵌入式系统中,经常会用到gpio外部中断来获取外部事件,比如按键、传感器、网络通信等等。一般中断都会绑定一个中断回调函数,来执行产生中断后的一些任务。Linux的中断是操作系统管理的资源,需要在内核层配置中断以及绑定回调函数。
内核编程可以直接修改内核源码,也可以使用Linux提供的模块编程方式。使用模块很方便,编译很快而且可以很方便的插入和移除。当然插入和移除操作需要管理员权限,与模块相关的命令有lsmod、insmod和rmmod。
详细的模块编程的方法网上和书上一大堆,很容易找到。
主要结构
1、init函数
2、exit函数
3、module_init和module_exit
4、作者、版权声明等。
注意:模块的编译需要用到源码,就是安装一个以headers结尾的东西。
在/usr/src下会有对应的目录,使用uname -r看看版本是否一致,如果不一样一般是当前系统的要比较旧,可以使用apt-get upgrade升级系统。不同的版本编译的模块不能加载,会提示格式无法识别之类的错误。
另外,内核编程用到的头文件和应用编程用到的头文件也不是一个系统的,内核编程用的是
/usr/src/linux-headers-xxx/include下的头文件,而应用编程用的是/usr/include/下的头文件。
ok,回到gpio中断。
在init函数里,使用gpio需要先请求一个并配置它的模式,使用gpio_request_one()函数,三个参数分别是gpio号、模式和名称。
使用函数enable_irq()使能中断,参数是中断号,gpio对应的中断号可以使用gpio_to_irq()获取。
调用request_irq()配置中断的回调函数、触发方式、名称和传入参数。
在exit函数中,对应的我们需要释放中断和对应的gpio。
编写中断回调函数。中断回调函数的格式定义如下:
Linux的中断函数分为了两个部分:顶半部和底半部。 顶半部是真正的回调函数,执行在中断上下文中,一般是不能被打断的,所以这里要尽可能短,只做非做不可的事。
底半部由顶半部触发,执行中断回调的其他不太紧急的事务。底半部的机制由软中断、tasklet、工作队列等(不知道是否有其它新技术了)。底半部的程序会参与内核的调度,可以被中断。
一些必要的头文件:
编译模块我看大家都用make,还好写个简单的Makefile也不复杂。小写的makefile有时候make不认识,不知道什么原因,如果遇到改成大写就好。
make然后插入模块
查看模块lsmod
使用dmesg查看log信息。如果init函数有printk打印可以看到信息。
在/proc/interrupts中可以看到中断比较详细的信息,红框就是我们的gpio中断。
在/proc/stat中也有关于中断的信息。intr(黄框)就是所有的中断统计情况,最后四个(红线)就是gpio中断的次数。
在proc/irq/下有以中断号命名的目录,目录下有跟中断相关的文件。
关于Linux的gpio中断目前就知道这么多了,欢迎大家补充交流。 限于个人水平,肯定会有遗漏和错误的地方,还望大家海涵。 在另一篇关于字符设备的专栏里,我会讲如何通过创建字符设备把内核的数据(比如中断处理的结果)传给用户空间,欢迎大家阅读。
全部0条评论
快来发表一下你的评论吧 !