基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ
基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ
0. 导语
学习进入到了下一个阶段,还是以AD9833为例,这次学习是向设备申请中断,实现触发,在未来很多场景,比如做用户级的SPI传输完毕数据之后,怎么知道从设备要发数据呢,则需要一个IO信号通知主设备来读从设备的数据,那么就需要一个外部的IO中断信号,所以呢,对于中断的处理十分重要,本demo实现这样的一个功能增加一个GPIO口,这个GPIO口接的是一个按键,通过触发信号,进入中断服务函数,在中断服务函数内改变AD9833的波形。以此达到学习实验目的。
之前的代码都是一样的,在这里尽量剥离AD9833驱动和Linux的代码模板,只写中断相关相关程序。
效果演示视频: https://v.youku.com/v_show/id_XMzY4MjAwOTA0MA==.html?spm=a2h3j.8428770.3416059.1
1. 前篇导读:
原理图:

2. 申请中断准备
首先需要两个头文件:
#include <linux/interrupt.h>#include <linux/irq.h>IO口配置准备
在此次使用中断中,主要用的是GPIO口,我们使用电平跳变使之进入到中断处理程序中,所以作为IO口,需要配置IO口的方向为输入方向。我的OMAPL138中给的IO口操作使用GPIO_TO_PIN这个宏函数进行,在IO口操作上每个平台都会给定自己的寻IO口的方法,然后使用linux通用gpio_direction_output进行设定该GPIO口为输入方向,如上面的原理图,本demo的驱动使用的GPIO6[1],所以as follow:gpio_direction_output( GPIO_TO_PIN(6, 1) , 0 );硬件中断号IRQ
我参考了很多文献,也找了很多书籍,对于硬件中断号码从哪里得到一笔带过,也没有具体说明,不过,经过一下午的努力,我找到了查找中断号码的方法。使用gpio_to_irq这个函数方法可以得到irq。我之前找到手册,看到了手册里面说GPIO6 BANK的IRQ为48号,我尝试加载到内核里面,每次初始化的时候都告诉我中断申请失败,这个号看来不是datasheet给定的48号,在Linux内核里面对于硬件IRQ又进行了重新映射。中断事件
在内核中断申请的时候,需要指定中断事件是什么,边沿信号,高电平触发,低电平触发,在irq.h里面定义了:
IRQ_TYPE_NONE = 0x00000000,
IRQ_TYPE_EDGE_RISING = 0x00000001,
IRQ_TYPE_EDGE_FALLING = 0x00000002,
IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING),
IRQ_TYPE_LEVEL_HIGH = 0x00000004,
IRQ_TYPE_LEVEL_LOW = 0x00000008,
IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH),
IRQ_TYPE_SENSE_MASK = 0x0000000f
我们需要指定这个事件。
- 中断的名字
这个使用#cat /proc/interrupts查看当前内核中断资源的时候就可以看到你指定注册的名字。

- 中断服务程序
这个我们自己定一个函数就可以,然后一会儿使用中断申请的时候将数据传输进去就好。我们在中断服务函数里面进行按键进行波形切换:
static int key_count = 0;
static irqreturn_t ad9833_press_intHandle( int irq, void *dev_id )
{
printk( DRV_NAME "\t press trigger!\n" );
if( key_count == 0 ) {
ad9833->set_wave_type( ad9833, SIN );
printk( DRV_NAME "\tSet wave is SIN.\n" );
}else if( key_count == 2 ) {
ad9833->set_wave_type( ad9833, TRI );
printk( DRV_NAME "\tSet wave is TRI.\n" );
}else if( key_count == 4 ) {
ad9833->set_wave_type( ad9833, SQU );
printk( DRV_NAME "\tSet wave is SQU.\n" );
}
key_count ++;
if( key_count >= 5 )
key_count = 0;
return IRQ_RETVAL( IRQ_HANDLED );
}
3. 申请中断准备
使用request_irq函数就好,我们在初始化函数里面,申请irq。在申请irq前,为了更好的管理中断函数,我们定义了一个结构体,专门进行irq配置。
struct gpio_irq_desc {
int irq;
unsigned long flags;
char *name;
} press_dev_desc = {
0,
IRQ_TYPE_EDGE_FALLING,
"sw6_push_button"
};
第一个是irq,我们在向内核申请中断的时候会使用gpio_to_irq进行irq的赋值,flags就是中断事件的触发条件,这里是下降边沿触发,最后一个name就是上面注册号中断分配的名字,初始化程序如下:
/*
* interrupt apply
* */
press_dev_desc.irq = gpio_to_irq(ad9833_gpios[3]);
ret = request_irq( press_dev_desc.irq , &ad9833_press_intHandle, press_dev_desc.flags, press_dev_desc.name, (void*)0 );
if( ret ) {
printk( DRV_NAME "\terror %d: IRQ = %d number failed!\n",ret,gpio_to_irq(ad9833_gpios[3]) );
ret = -EBUSY;
unregister_chrdev_region( devno,1 );
for( i = 0; i < ARRAY_SIZE(ad9833_gpios); i++)
gpio_free( ad9833_gpios[i] );
kfree(ad9833);
return ret;
}
printk( DRV_NAME "\tiqr apply ok!!\n" );
到此我们就完成了中断配置。
4. 中断释放
使用freqq_irq进行释放。这个函数应该放在exit驱动的函数里面。
free_irq( press_dev_desc.irq, (void*)0 );
源代码下载
链接: https://pan.baidu.com/s/1JgPgGP1Ag_oixHmHOy3QEw 密码: 5x84
参考文献
[1] 创龙电子科技, OMAPL138的GPIO输出输入, 百度文库, 2014年5月8日
[2] wh_19910525, Linux的 标准GPIO及中断API函数, CSDN博客, 2013年12月25日
[3] wangcong02345, Linux内核---44.关于中断号与中断引脚, CSDN博客, 2016年7月9日
[4] GreenHand#, Linux设备驱动中断机制, CNBLOGS, 2016年12月27日
基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ的更多相关文章
- 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(一)之miscdevice和ioctl
基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(一)之miscdevice和ioctl 0. 导语 在嵌入式的道路上寻寻觅觅很久,进入嵌入式这个行业也有几年的时间了,从2011年后 ...
- 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read、write
基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read.write 0. 导语 在上一篇博客里面,基于OMAPL138的字符驱动_GPIO驱动AD9833(一)之 ...
- 基于335X平台Linux交换芯片驱动开发
基于335X平台Linux交换芯片驱动开发 一.软硬件平台资料 1.开发板:创龙AM3359核心板,网口采用RMII形式. 2.Kernel版本:4.4.12,采用FDT 3.交换芯片MARVEL ...
- linux设备驱动归纳总结(三):2.字符型设备的操作open、close、read、write【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-59417.html linux设备驱动归纳总结(三):2.字符型设备的操作open.close.rea ...
- linux设备驱动归纳总结(三):1.字符型设备之设备申请【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-59416.html linux设备驱动归纳总结(三):1.字符型设备之设备申请 操作系统:Ubunru ...
- 基于STM32F1的时钟芯片DS1302驱动
目录 DS1302.h源代码 DS1302.c源代码 DS1302.h源代码 /** ********************************************************* ...
- 【Linux开发】linux设备驱动归纳总结(三):2.字符型设备的操作open、close、read、write
linux设备驱动归纳总结(三):2.字符型设备的操作open.close.read.write 一.文件操作结构体file_operations 继续上次没讲完的问题,文件操作结构体到底是什么东西, ...
- 【Linux开发】linux设备驱动归纳总结(三):1.字符型设备之设备申请
linux设备驱动归纳总结(三):1.字符型设备之设备申请 操作系统:Ubunru 10.04 实验平台:S3C2440 + linux2.6.29内核 注:在今后驱动程序的学习中经常需要查看内核源代 ...
- Linux内核驱动学习(三)字符型设备驱动之初体验
Linux字符型设备驱动之初体验 文章目录 Linux字符型设备驱动之初体验 前言 框架 字符型设备 程序实现 cdev kobj owner file_operations dev_t 设备注册过程 ...
随机推荐
- SQL Server 没有足够的内存继续执行程序 (mscorlib)的解决办法
问题: SQL Server 执行大脚本时,出现如下提示信息: 解决方法: 使用 sqlcmd.exe 导入 1.win + r,输入 cmd 进入 C:\Program Files\Microsof ...
- linux(centos)设置tomcat开机启动
方法一: linux 下tomcat开机自启动修改Tomcat/bin/startup.sh 为: export JAVA_HOME=/usr/java/j2sdk1.4.2_08 export CL ...
- JAVA中的那些名词解释!
1.JDO: (Java Data Object )是Java对象持久化的新的规范,也是一个用于存取某种数据仓库中的对象的标准化API.作用:用于存取某种数据仓库中的对象 2.JPA: JPA是Jav ...
- 记账本app(一)
计划开发一款小程序应用,主要来记录自己的财务账目. 通过使用SpringBoot开发后端应用,提供接口,对应前端使用微信小程序来实现. 功能模块(用户信息,账本.账目列表,新增一笔账,修改一笔账,删除 ...
- vue-cli中自定义路径别名 assets和static文件夹的区别
转自:vue-cli中自定义路径别名 assets和static文件夹的区别 静态资源处理: assets和static文件夹的区别 相信有很多人知道vue-cli有两个放置静态资源的地方,分别是sr ...
- python UI自动化实战记录十:执行测试及测试报告
使用简单的unittest.TextTestRunner. 思路: 1 在report目录下创建当日测试报告目录 20190113 2 创建测试报告文件 f = 时间戳.txt 3 加载测试集,运行测 ...
- IOS AFN (第三方请求)
什么是AFN全称是AFNetworking,是对NSURLConnection.NSURLSession的一层封装虽然运行效率没有ASI高,但是使用比ASI简单在iOS开发中,使用比较广泛 AFN的g ...
- UVa 11582 - Colossal Fibonacci Numbers!(数论)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- CF13C Sequence
嘟嘟嘟 偶然看到的这道题,觉得有点意思,就做了. 首先题里说修改后的数列只能出现修改前的数,那么状态之间的转移也就之可能在这些数之间. 令f[i][j]表示第 i 个数改成原序列第 j 小的数时的最小 ...
- 单表60亿记录等大数据场景的MySQL优化和运维之道 | 高可用架构
015-08-09 杨尚刚 高可用架构 此文是根据杨尚刚在[QCON高可用架构群]中,针对MySQL在单表海量记录等场景下,业界广泛关注的MySQL问题的经验分享整理而成,转发请注明出处. 杨尚刚,美 ...