IMX257实现GPIO-IRQ中断按键驱动程序

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

    昨天我们已经实现了中断查询的方式实现GPIO按键驱动程序,但是,有一个缺点就是,当我们把应用程序放在后台执行时,即便没有按键,应用程序while循环中的read函数也不断的在运行,严重的导致了CPU资源的浪费。


    本文中,我们在前面按键查询驱动程序的基础上来修改。


    大概介绍一下设计思路吧:


    和前面的差不多,当我们加载驱动时,首先在init函数中,对GPIO功能进行模式设置,都设置为GPIO模式,然后申请GPIO引脚的内存,


接着,当我们应用程序使用ioctl函数的gpio_input命令时,将所有的GPIO引脚设置为输入,并且22K上拉模式,当应用程序使用read函数读取时,如果按键没有按下,则会在read函数中睡眠(可被中断唤醒),交出CPU的使用权,当按键按下时,首先会在中断程序中进行唤醒操作,在read函数中接着运行,读取GPIO引脚的电平,并且将数据从内核空间传递到用户空间中,并且打印出来。


    最后,当我们不要用驱动程序时,rsmod会调用exit函数,释放所有我们已经申请的GPIO资源。


    好了,大概的思路就是这样,和前面的查询驱动程序,差不多,只不过就加了一个中断,和睡眠而已。


附上驱动程序代码:


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

  2     linux key_query

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

  4 #include

  5 #include

  6 #include

  7 #include

  8 #include

  9 #include

 10 #include

 11 #include

 12 #include

 13 #include

 14 #include

 15 #include

 16 #include //error: 'TASK_INTERRUPTIBLE' undeclared 

 17 #include

 18 

 19 #include 'mx257_gpio.h'

 20 #include 'mx25_pins.h'

 21 #include 'iomux.h'

 22 

 23 #define Driver_NAME 'key_interrupt'

 24 #define DEVICE_NAME 'key_interrupt'

 25 

 26 #define GPIO2_21    MX25_PIN_CLKO

 27 #define GPIO3_15    MX25_PIN_EXT_ARMCLK

 28 #define GPIO2_10    MX25_PIN_A24

 29 #define GPIO2_11    MX25_PIN_A25

 30 #define GPIO2_8     MX25_PIN_A22

 31 #define GPIO2_9     MX25_PIN_A23

 32 #define GPIO2_6     MX25_PIN_A20

 33 #define GPIO2_7     MX25_PIN_A21

 34 //command

 35 #define key_input     0

 36 #define version        1

 37 

 38 //interrupt head

 39 static DECLARE_WAIT_QUEUE_HEAD(key_interrupt_wait);

 40 static volatile unsigned char ev_press;  

 41 

 42 static int major=0;

 43 

 44 //auto to create device node

 45 static struct class *drv_class = NULL;

 46 static struct class_device *drv_class_dev = NULL;

 47 

 48 

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

 50  * 就会调用key_open函数*/

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

 52 {

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

 54     

 55     return 0;

 56 }

 57 

 58 /* 中断程序key_irq */

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

 60 {

 61     //发生了中断

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

 63     ev_press = 1;

 64     wake_up_interruptible(&key_interrupt_wait);

 65 

 66     return IRQ_RETVAL(IRQ_HANDLED);

 67 }

 68 

 69 

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

 71 {

 72     int ret;

 73     //nt cnt=0;

 74     unsigned char key_vals[8];

 75 

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

 77     wait_event_interruptible(key_interrupt_wait,ev_press);

 78 

 79     // reading the pins value

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

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

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

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

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

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

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

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

 88     

 89     ret = copy_to_user(buff,key_vals,sizeof(key_vals));

 90     if(ret){

 91         ;

 92     }

 93     ev_press = 0;

 94     //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]); 

 95 

 96     return sizeof(key_vals);

 97 }

 98 

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

100 {

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

102     

103     return 1;

104 }

105 

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

107 {

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

109     //释放中断

110     free_irq(IOMUX_TO_IRQ(GPIO2_21), (void *)1);

111     //free_irq(IOMUX_TO_IRQ(GPIO3_15), (void *)1);

112     free_irq(IOMUX_TO_IRQ(GPIO2_11), (void *)1);

113     free_irq(IOMUX_TO_IRQ(GPIO2_10), (void *)1);

114     free_irq(IOMUX_TO_IRQ(GPIO2_9), (void *)1);

115     //free_irq(IOMUX_TO_IRQ(GPIO2_8), (void *)1);

116     free_irq(IOMUX_TO_IRQ(GPIO2_7), (void *)1);

117     free_irq(IOMUX_TO_IRQ(GPIO2_6), (void *)1);

118     return 0;

119 }

120 

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

122 {

123     int ret;

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

125     switch (command) {

126         case key_input:    

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

128             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_21));

129             gpio_direction_input(IOMUX_TO_GPIO(GPIO3_15));

130             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));

131             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));

132             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_8));

133             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));

134             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_6));

135             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_7));

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

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

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

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

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

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

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

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

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

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

146 

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

148             request_irq(IOMUX_TO_IRQ(GPIO2_7), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_7', (void *)1);

149             request_irq(IOMUX_TO_IRQ(GPIO2_6), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_6', (void *)1);

150             request_irq(IOMUX_TO_IRQ(GPIO2_9), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_9', (void *)1);

151             request_irq(IOMUX_TO_IRQ(GPIO2_10), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_10', (void *)1);

152             request_irq(IOMUX_TO_IRQ(GPIO2_11), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_11', (void *)1);

153             request_irq(IOMUX_TO_IRQ(GPIO2_21), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_21', (void *)1);

154             //request_irq(IOMUX_TO_IRQ(GPIO3_15), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO3_15', (void *)1);

155             //request_irq(IOMUX_TO_IRQ(GPIO2_8), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_8', (void *)1);

156             printk('<0>have setting all pins to gpio interrupt mod by IRQF_TRIGGER_FALLING !n');

157 

158             break;

159         case version:

160             printk('<0>hello,the version is 0.1.0nn');

[1] [2]
关键字:GPIO  IRQ  中断按键 引用地址:IMX257实现GPIO-IRQ中断按键驱动程序

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

推荐阅读最新更新时间:2024-11-12 23:04

STM32自学笔记GPIO寄存器
GPIO寄存器一览 以下图片全部摘自STM32中文参考手册 GPIOx- CRL(x=A…E) 这个寄存器主要是设置GPIO的低8位(0~7)端口的配置 MODE 用来设置端口输出的速度 (在输入模式下不需要配置,仅在输出模式下需要配置) CNF 用来设置输入模式或者输出模式 例如 设置PA0为推挽输出速度为50MHz GPIOA- CRL&=0XFFFFFFF0;//PA0配置清零 GPIOA- CRL|=0X00000003;//PA0输出 速度50MHz 设置PA0为上下拉输入(默认下拉) GPIOA- CRL&=0XFFFFFFF0;//PA0配置清零 GPIOA- CRL|=0X00000008
[单片机]
STM32自学笔记<font color='red'>GPIO</font>寄存器
S3C6410 GPIO操作接口
一、配置GPIO S3C6410要使用其引脚时,需要对其进行配置,如配置为输入/输出/中断等功能,根据芯片手册来配置,所用的这些配置工作都在Gpiolib.c(/arch/arm/plat-s3c64xx)中完成,当然,你在起步阶段可以用基本的__raw_readl和__raw_writel来操作,了解其基本的原理。 1. 配置为上拉/下拉 arm芯片一般都可以内部配置为上拉或下拉,如此就不需要外部接上拉电阻,简化电路。配置成上拉,驱动能力更强,例外防止其处在电平悬浮状态。 操作:把GPB第一个引脚配置为上拉 函数:s3c_gpio_setpull(S3C64XX_GPB(0),S3C_GPIO_PULL_UP);
[单片机]
GPIO流水灯—基于Stm32CubeMX创建工程实现流水灯
一、了解GPIO结构 二、GPIO的工作模式 GPIO有8种工作模式 1.输入浮空 当GPIOx_ CRL 或GPIOx_CRH 寄存器的CNF 位设置为01,并且MODE 位设置为00时,对应引脚被设置为浮空输入模式,该模式也是STM32复位之后默认模式。浮空输入模式是相对与上拉或者下拉输入模式,浮空就是不上拉也不下拉。浮空输入模式下GPIO结构中信号流向见图11-2。 I/O引脚信号接入到施密特触发器的输入端,在每来一个APB2时钟脉冲就把输入端的信号传输到触发器的输出端,施密特触发器的输出端又是与输入数据寄存器(GPIOx_IDR)连通的,所以该数据就保存在输入数据寄存器内,寄存器本身就是一个存储单元(起到缓冲区
[单片机]
<font color='red'>GPIO</font>流水灯—基于Stm32CubeMX创建工程实现流水灯
STM32中GPIO的这八种配置种类你知道几种?
在Cortex-M3里,对于GPIO的配置种类有8种: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_IPU 上拉输入 (5)GPIO_Mode_Out_OD 开漏输出 (6)GPIO_Mode_Out_PP 推挽输出 (7)GPIO_Mode_AF_OD 复用开漏输出 (8)GPIO_Mode_AF_PP 复用推挽输出 1、推挽输出 推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效
[单片机]
STM32中<font color='red'>GPIO</font>的这八种配置种类你知道几种?
按键程序 PORT中断程序
MSP 430里面 P1口和P2口有中断功能。 我们的项目里面,P1口的1-7管脚做键盘,0脚做风速传感器的输入。P2口的0-4做键盘,5-7做其他用。 //键盘引脚配置 P1DIR=0x00; // P1 口为输入(0:风速传感器输入,1-7中断信号输入) P2DIR&=~(BIT0+BIT1+BIT2+BIT3+BIT4); //把P2.0-P2.4设为输入 //下降沿触发是指按下的时候进入中断,上升沿触发是在放开按键的时候进入中断 P1IES|=BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+
[单片机]
MSP430F149-利用IO中断方式实现按键检测程序
#include msp430x14x.h #define key1 0x01 #define key2 0x02 #define key3 0x04 #define delay_small 200 #define key_1 0xfe //定义返回键值1 #define key_2 0xfd //定义返回键值2 #define key_3 0xfb //定义返回键值3 void key_process_0(void); void key_process_1(void); void key_process_2(void); void key_check (void); unsigned char key_value
[单片机]
再造STM32---第十一部分:GPIO—位带操作
本章参考资料:《STM32F4xx 中文参考手册》存储器和总线构架章节、 GPIO 章节,《Cortex®-M4 内核编程手册》 2.2.5 Bit-banding。学习本章时,配套这些参考资料学习效果会更佳。 11.1 位带简介: 位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见。 51 单片机中通过关键字 sbit 来实现位定义, F429 中没有这样的关键字,而是通过访问位带别名区来实现。 在 F429 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,另一个是外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的
[单片机]
再造STM32---第十一部分:<font color='red'>GPIO</font>—位带操作
STM8S 固件库GPIO设置问题
ST对STM8S系列都有提供固件库,而不同的版本自然存在一些不同,版本也一直从V1.0.0升级到目前的V1.1.1。 环境: FWLIB V1.0.1版本,采用STM8SF103 在使用GPIO库时,一个偶然发现stm8s_gpio.h中的宏定义是存在问题的。 代码定义如下: ****************************************************************************** * @file stm8s_gpio.h * @brief This file contains all functions prototype and macros for the
[单片机]
STM8S 固件库<font color='red'>GPIO</font>设置问题
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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