博客
关于我
7.【linux驱动】中断
阅读量:679 次
发布时间:2019-03-17

本文共 4339 字,大约阅读时间需要 14 分钟。

用GPIOB_31模拟按键功能,设置上拉,下降沿触发

寄存器版本

linux驱动几乎不用管硬件中断了,内核已经帮我们管理好了所有硬件中断号,并且定义了相应的内核中断号,我们只需要看一下内核中断号。

arch/arm/mach-s5p4418/include/mach/s5paa18_irq.h
在这里插入图片描述
这里GPIOB_31直接用IRQ_GPIO_B_START + 31就好。
在这里插入图片描述
数据手册中得到下降沿触发值为0b010=2。有关GPIO寄存器的定义和操作可以见这篇文章:

#include 
#include
#include
#include
//含有request_irq、free_irq函数#include
//含有IRQ_HANDLED\IRQ_TYPE_EDGE_RISING#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");#pragma pack(4)static struct GPIO_B{ unsigned int out_put; unsigned int out_enb; unsigned int detect_md_0; unsigned int detect_md_1; unsigned int int_enb; unsigned int event_detect; unsigned int pad_state; unsigned int resv; unsigned int func0; unsigned int func1; unsigned int DETMODEEX; unsigned int DETENB; unsigned int SLEW; unsigned int SLEW_DISABLE_DEFAULT; unsigned int DRV1; unsigned int DRV1_DISABLE_DEFAULT; unsigned int DRV0; unsigned int DRV0_DISABLE_DEFAULT; unsigned int pull_sell; unsigned int PULLSEL_DISABLE_DEFAULT; unsigned int pull_enb;}* gpio_b;#pragma pack()dev_t devid;unsigned int int_num,gpio_b_31_int_num;static irqreturn_t hello_irq(int irq,void * dev_id){ printk("gpiob_31 down,MAJOR:%d MINOR:%d\n",MAJOR((dev_t)dev_id),MINOR((dev_t)dev_id)); return IRQ_HANDLED;}static int __init hello_init(void){ int ret = 0; devid = MKDEV(241, 1); //换算设备号 ret = register_chrdev_region(devid, 1, "char_test");//注册设备,在/proc/drivers下面可以看到 if (ret < 0) goto err0; gpio_b = (struct GPIO_B *)ioremap(0xc001b000,sizeof(struct GPIO_B));//映射地址 gpio_b->func1 |= (1 << 30); //设置gpio功能 gpio_b->out_enb &= ~(1 << 31); //禁用输出 gpio_b->pull_enb |= (1 << 31); //使能上下拉 gpio_b->pull_sell |= (1 << 31); //设置为上拉 gpio_b->int_enb |= (1 << 31); //中断使能 gpio_b->detect_md_1 |= (2 << 30); //中断模式为下降沿触发 gpio_b_31_int_num = IRQ_GPIO_B_START + 31; if (!request_irq(gpio_b_31_int_num,hello_irq,IRQF_DISABLED | IRQF_SHARED,"gpio_irq0",(void *)devid)){ printk("irq registed:%d\n", gpio_b_31_int_num); int_num = gpio_b_31_int_num; }else{ printk("irq regist fail:%d\n",gpio_b_31_int_num); } printk("hello init\n"); return 0; err0: return ret;}static void __exit hello_exit(void){ if(int_num){ free_irq(gpio_b_31_int_num,(void *)devid); //取消中断函数注册 } unregister_chrdev_region(devid, 1); gpio_b->int_enb &= ~(1 << 31); //禁用中断 printk("hello exit\n");}module_init(hello_init);module_exit(hello_exit);

API版本

api版本需要看一下中断模式的设置,从注释看出来下降沿触发依然是2。

arch/arm/mach-s5p4418/soc/gpio.c
在这里插入图片描述

#include 
#include
#include
#include
//含有request_irq、free_irq函数#include
//含有IRQ_HANDLED\IRQ_TYPE_EDGE_RISING#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");dev_t devid;unsigned int int_num,gpio_b_31_int_num;static irqreturn_t hello_irq(int irq,void * dev_id){ printk("gpiob_31 down,MAJOR:%d MINOR:%d\n",MAJOR((dev_t)dev_id),MINOR((dev_t)dev_id)); return IRQ_HANDLED;}static int __init hello_init(void){ int ret = 0; devid = MKDEV(241, 1); //换算设备号 ret = register_chrdev_region(devid, 1, "char_test");//注册设备,在/proc/drivers下面可以看到 if (ret < 0) goto err0; nxp_soc_gpio_set_io_func(PAD_GPIO_B + 31, 1); //设置gpio功能 nxp_soc_gpio_set_io_pull_enb(PAD_GPIO_B + 31, 1); //使能上下拉 nxp_soc_gpio_set_io_pull_sel(PAD_GPIO_B + 31, 1); //设置为上拉 nxp_soc_gpio_set_int_enable(PAD_GPIO_B + 31, 1); //中断使能 nxp_soc_gpio_set_int_mode(PAD_GPIO_B + 31, 2); //中断模式为下降沿触发 gpio_b_31_int_num = IRQ_GPIO_B_START + 31; if (!request_irq(gpio_b_31_int_num,hello_irq,IRQF_DISABLED | IRQF_SHARED,"gpio_irq0",(void *)devid)){ printk("irq registed:%d\n", gpio_b_31_int_num); int_num = gpio_b_31_int_num; }else{ printk("irq regist fail:%d\n",gpio_b_31_int_num); } printk("hello init\n"); return 0; err0: return ret;}static void __exit hello_exit(void){ if(int_num){ free_irq(gpio_b_31_int_num,(void *)devid); //取消中断函数注册 } unregister_chrdev_region(devid, 1); nxp_soc_gpio_set_io_pull_enb(PAD_GPIO_B + 31, 0); //禁用上下拉 nxp_soc_gpio_set_int_enable(PAD_GPIO_B + 31, 0); //禁用中断 printk("hello exit\n");}module_init(hello_init);module_exit(hello_exit);

运行一下

[root@minicoco int_register]# insmod gpiob_31.ko[  128.636000] irq registed:127[  128.636000] hello init[root@minicoco int_register]# [  134.824000] gpiob_31 down,MAJOR:241 MINOR:1[  135.240000] gpiob_31 down,MAJOR:241 MINOR:1[  136.444000] gpiob_31 down,MAJOR:241 MINOR:1

转载地址:http://ipzhz.baihongyu.com/

你可能感兴趣的文章
Nginx配置参数中文说明
查看>>
Nginx配置后台网关映射路径
查看>>
nginx配置域名和ip同时访问、开放多端口
查看>>
Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
查看>>
Nginx配置如何一键生成
查看>>
Nginx配置实例-负载均衡实例:平均访问多台服务器
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Nginx配置负载均衡到后台网关集群
查看>>
ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
查看>>
NHibernate学习[1]
查看>>
NHibernate异常:No persister for的解决办法
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
查看>>
NIFI1.23.2_最新版_性能优化通用_技巧积累_使用NIFI表达式过滤表_随时更新---大数据之Nifi工作笔记0063
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_无分页功能_02_转换数据_分割数据_提取JSON数据_替换拼接SQL_添加分页---大数据之Nifi工作笔记0037
查看>>