【改进Poll定时查询】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

发布者:ArtisticSoul最新更新时间:2024-08-16 来源: cnblogs关键字:中断按键 手机看文章 扫描二维码
随时随地手机看文章

按键驱动程序中,如果不使用read函数中使程序休眠的,而是还是使用查询方式的话,可以使用Poll函数,来控制一定时间内,如果有按键发生,则立即返回键值。

同时,poll也可以同时监控多个(比如说按键,鼠标,等)一旦发生事件则立即返回。

我们在linux查看帮助:

从帮助中的说明得知,

poll, ppoll - wait for some event on a file descriptor

poll就是监控某个设备的事件。

 

修改驱动程序

1.增加头文件 #include

2.增加key_poll 方法

 

static unsigned key_poll(struct file *file,poll_table *wait)

 

file_opreation中增加:

.poll = key_poll,

 

 

3.在key_poll函数中设置函数不睡眠

 

4.此时可以把以前的read函数中的中断睡眠代码注释掉

 

5.编译代码,测试

 

附上驱动程序。

 

  1 /******************************

  2     linux key_query

  3  *****************************/

  4 #include

  5 #include

  6 #include

  7 #include

  8 #include

  9 #include

 10 #include gpio.h>

 11 #include

 12 #include

 13 #include

 14 #include

 15 #include

 16 #include //error: 'TASK_INTERRUPTIBLE' undeclared 

 17 #include

 18 #include

 19 

 20 #include 'mx257_gpio.h'

 21 #include 'mx25_pins.h'

 22 #include 'iomux.h'

 23 

 24 #define Driver_NAME 'key_interrupt'

 25 #define DEVICE_NAME 'key_interrupt'

 26 

 27 #define GPIO2_21    MX25_PIN_CLKO

 28 #define GPIO3_15    MX25_PIN_EXT_ARMCLK

 29 #define GPIO2_10    MX25_PIN_A24

 30 #define GPIO2_11    MX25_PIN_A25

 31 #define GPIO2_8     MX25_PIN_A22

 32 #define GPIO2_9     MX25_PIN_A23

 33 #define GPIO2_6     MX25_PIN_A20

 34 #define GPIO2_7     MX25_PIN_A21

 35 //command

 36 #define key_input     0

 37 #define version        1

 38 //定义各个按键按下的键值

 39 struct pin_desc{

 40     unsigned int pin;

 41     unsigned int key_val;

 42 };

 43 //当按键按下时,键值分别为 以下值

 44 struct pin_desc pins_desc[8] = {

 45     {GPIO2_6,    0x01},

 46     {GPIO2_7,    0x02},

 47     {GPIO2_8,    0x03},

 48     {GPIO2_9,    0x04},

 49     {GPIO2_10,    0x05},

 50     {GPIO2_11,    0x06},

 51     {GPIO2_21,    0x07},

 52     {GPIO3_15,    0x08},

 53 };

 54 //定义一个全局变量,用于保存按下的键值

 55 static unsigned int key_val;

 56 

 57 //interrupt head

 58 static DECLARE_WAIT_QUEUE_HEAD(key_interrupt_wait);

 59 static volatile unsigned char ev_press;  

 60 

 61 static int major=0;

 62 

 63 //auto to create device node

 64 static struct class *drv_class = NULL;

 65 static struct class_device *drv_class_dev = NULL;

 66 

 67 

 68 /* 应用程序对设备文件/dev/key_query执行open(...)时,

 69  * 就会调用key_open函数*/

 70 static int key_open(struct inode *inode, struct file *file)

 71 {

 72     printk('<0>function open!nn');

 73     

 74     return 0;

 75 }

 76 

 77 /* 中断程序key_irq */

 78 static irqreturn_t key_irq(int irq, void *dev_id)

 79 {

 80     struct pin_desc * pindesc = (struct pin_desc *)dev_id;

 81     //发生了中断

 82     //printk('<0>function interrupt key_irq!nn');

 83     //获取按键键值

 84     if(gpio_get_value(IOMUX_TO_GPIO(pindesc->pin))){

 85         /* 按下 */

 86         key_val = pindesc->key_val;

 87     }else{

 88         key_val = 0x80 | pindesc->key_val;

 89     }

 90     printk('<0>get key 0x%x',key_val);    

 91     ev_press = 1;

 92     wake_up_interruptible(&key_interrupt_wait);

 93 

 94     return IRQ_RETVAL(IRQ_HANDLED);

 95 }

 96 

 97 

 98 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

 99 {

100     int ret;

101     //如果按键没有按下,没有中断,休眠

102     //wait_event_interruptible(key_interrupt_wait,ev_press);

103 

104     ret = copy_to_user(buff,&key_val,sizeof(key_val));

105     if(ret){

106         ;

107     }

108     ev_press = 0;

109     return sizeof(key_val);

110 

111     //int cnt=0;

112     //unsigned char key_vals[8];

113 

114     /*

115     // reading the pins value

116     key_vals[0] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_6)) ? 1 : 0;

117     key_vals[1] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_7)) ? 1 : 0;

118     key_vals[2] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_8)) ? 1 : 0;

119     key_vals[3] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_9)) ? 1 : 0;

120     key_vals[4] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_10)) ? 1 : 0;

121     key_vals[5] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_11)) ? 1 : 0;

122     key_vals[6] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_21)) ? 1 : 0;

123     key_vals[7] = gpio_get_value(IOMUX_TO_GPIO(GPIO3_15)) ? 1 : 0;

124     

125     //printk('<0>%04d key pressed: %d %d %d %d %d %d %d %dn',cnt++,key_vals[0],key_vals[1],key_vals[2],key_vals[3],key_vals[4],key_vals[5],key_vals[6],key_vals[7]); 

126     */

127 }

128 

129 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)

130 {

131     printk('<0>function write!nn');

132     

133     return 1;

134 }

135 

136 static int  key_release(struct inode *inode, struct file *filp)

137 {

138     printk('<0>function release!nn');

139     //释放中断

140     free_irq(IOMUX_TO_IRQ(GPIO2_21),  &pins_desc[6]);

141     //free_irq(IOMUX_TO_IRQ(GPIO3_15),&pins_desc[7]);

142     free_irq(IOMUX_TO_IRQ(GPIO2_11),  &pins_desc[5]);

143     free_irq(IOMUX_TO_IRQ(GPIO2_10),  &pins_desc[4]);

144     free_irq(IOMUX_TO_IRQ(GPIO2_9),   &pins_desc[3]);

145     //free_irq(IOMUX_TO_IRQ(GPIO2_8), &pins_desc[2]);

146     free_irq(IOMUX_TO_IRQ(GPIO2_7),   &pins_desc[1]);

147     free_irq(IOMUX_TO_IRQ(GPIO2_6),   &pins_desc[0]);

148     return 0;

149 }

150 

151 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)

152 {

153     int ret;

154     printk('<0>function ioctl!nn');

155     switch (command) {

156         case key_input:    

157             //设置所有的引脚为输入

158             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_21));

159             gpio_direction_input(IOMUX_TO_GPIO(GPIO3_15));

160             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));

161             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));

162             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_8));

163             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));

164             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_6));

165             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_7));

166             printk('<0>have setting all pins to gpio input mod !n');

167             //设置GPIO引脚为上拉模式

168             mxc_iomux_set_pad(GPIO2_6, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

169             mxc_iomux_set_pad(GPIO2_7, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

170             //mxc_iomux_set_pad(GPIO2_8, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

171             mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

172             mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

173             mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

174             mxc_iomux_set_pad(GPIO2_21, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

175             //mxc_iomux_set_pad(GPIO3_15, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

176 

177             //设置GPIO引脚中断  ,下降沿触发

178             request_irq(IOMUX_TO_IRQ(GPIO2_6), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_6', &pins_desc[0]);

[1] [2]
关键字:中断按键 引用地址:【改进Poll定时查询】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

上一篇:【改进信号量】IMX257实现GPIO-IRQ中断按键获取键值驱动程序
下一篇:【改进】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

推荐阅读最新更新时间:2026-03-20 10:58

【改进Poll定时查询IMX257实现GPIO-IRQ中断按键获取键值驱动程序
按键驱动程序中,如果不使用read函数中使程序休眠的,而是还是使用查询方式的话,可以使用Poll函数,来控制一定时间内,如果有按键发生,则立即返回键值。 同时,poll也可以同时监控多个(比如说按键,鼠标,等)一旦发生事件则立即返回。 我们在linux查看帮助: 从帮助中的说明得知, poll, ppoll - wait for some event on a file descriptor poll就是监控某个设备的事件。 修改驱动程序 1.增加头文件 #include linux/poll.h 2.增加key_poll 方法 static unsigned key_poll(struct file *fil
[单片机]
【改进<font color='red'>Poll</font><font color='red'>定时</font><font color='red'>查询</font>】<font color='red'>IMX257</font>实现<font color='red'>GPIO-IRQ</font><font color='red'>中断</font><font color='red'>按键</font>获取键值驱动程序
IMX257实现GPIO-IRQ中断按键驱动程序
昨天我们已经实现了中断查询的方式实现GPIO按键驱动程序,但是,有一个缺点就是,当我们把应用程序放在后台执行时,即便没有按键,应用程序while循环中的read函数也不断的在运行,严重的导致了CPU资源的浪费。 本文中,我们在前面按键查询驱动程序的基础上来修改。 大概介绍一下设计思路吧: 和前面的差不多,当我们加载驱动时,首先在init函数中,对GPIO功能进行模式设置,都设置为GPIO模式,然后申请GPIO引脚的内存, 接着,当我们应用程序使用ioctl函数的gpio_input命令时,将所有的GPIO引脚设置为输入,并且22K上拉模式,当应用程序使用read函数读取时,如果按键没有按下,则会在r
[单片机]
<font color='red'>IMX257</font>实现<font color='red'>GPIO-IRQ</font><font color='red'>中断</font><font color='red'>按键</font>驱动程序
专题2-通过按键中断\2440按键中断编程lesson2
1、程序优化 修改Makefile 把main.c里面的mmu代码复制到mmu.c并修改如下 main.c的修改 由于在bootloader当中一般不会使用MMU,所以 main.c 加入led.c文件 makefile 2440中断源初始化 打开开发板底板与核心板原理图 底板 比如K1对应EINT1,然后到核心板去搜EINT1 然后去2440芯片手册去找到GPF这一组IO口 创建一个button.c,加入到makefile里面去button.o 按键初始化 编写button.c文件 #define GPFCON (volatile unsigned long *)0x56000050
[单片机]
专题2-通过<font color='red'>按键</font>玩<font color='red'>中断</font>\2440<font color='red'>按键</font><font color='red'>中断</font>编程lesson2
专题2-通过按键中断\第1课-中断处理流程深度剖析-lesson1
中断概念 1、中断生命周期 串口先产生一个事件,该事件传送到中断控制器里面,中断控制器会进行相应过滤,能通过过滤,那么就交给CPU去处理。 2、中断源 2440芯片手册 6410芯片手册 3、中断过滤 4、中断处理 cpu处理方式有两种: 非向量方式: 向量方式: 总结:整个生命周期中软件的角色
[单片机]
专题2-通过<font color='red'>按键</font>玩<font color='red'>中断</font>\第1课-<font color='red'>中断</font>处理流程深度剖析-lesson1
(linux自学笔记)linux按键中断驱动
通常开发板自带按键中断的驱动,中断已被注册至内核。重新编译linux内核去掉自带驱动才能使用自己编写的驱动。 linux中断程序可分解为顶半部与底半部机制。顶半部完成尽可能少的紧急功能,底半部可以被新的中断打断。 驱动程序 #include linux/module.h #include linux/kernel.h #include linux/fs.h #include linux/init.h #include linux/delay.h #include linux/poll.h #include linux/irq.h #include asm/irq.h #include linux/inter
[单片机]
(linux自学笔记)linux<font color='red'>按键</font><font color='red'>中断</font>驱动
Tiny 6410 按键中断驱动笔记
1. 先查看《Tiny6410SDK-1103 底板原理图》,找到按键部分:   从上图可知,当按键按下时,相当于接地,即低电平,从而产生一个由高电平到低电平的跳变。   Tiny6410的底板有8个按键: 2. 查看《Tiny6410-1170 CPU核心板原理图》,找到EINT0的连接图:   从上图可知:   EINT0 接 GPN0   EINT1 接 GPN1   EINT2 接 GPN2   ENIT3 接 GPN3   EINT4 接 GPN4   EINT5 接 GPN5   EINT19 接 GPL11   EINT20 接 GPL12 知识点: 由s3c6410外部触发的中断就是外部中断,
[单片机]
Tiny 6410 <font color='red'>按键</font><font color='red'>中断</font>驱动笔记
S3C2440 按键中断方式汇编代码
SRCPND EQU 0X4A000000 INTMSK EQU 0X4A000008 INTPND EQU 0X4A000010 EINTMASK EQU 0X560000A4 EINTPEND EQU 0X560000A8 EXTINT1 EQU 0X5600008C EXTINT2 EQU 0X56000090 INTMOD EQU 0X4A000004 AREA INT_KEY,CODE,READONLY ENTRY CODE32 ResetEntry b Reset ; //0x04: 未定义指令中止模式的向量地址 HandleUndef b HandleUndef ; //0x08: 管理模式的向量地址,通过
[单片机]
linux设备树-按键中断驱动
---------------------------------------------------------------------------------------------------------------------------- 内核版本:linux 5.2.8 根文件系统:busybox 1.25.0 u-boot:2016.05 ---------------------------------------------------------------------------------------------------------------------------- 回到顶部 一、修改设备树
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved