request_irq()和free_irq()分析完毕后,接下来开始编写上升沿中断的按键驱动

如下图,需要设置4个按键的EINT0, EINT2, EINT11, EINT19的模式为双边沿,且设置按键引脚为中断引脚

这里我们只需要使用request_irq函数就行了, 在request_irq函数里会初始chip->set_type(设置引脚和中断模式)

1.首先添加头文件

#include  //要用到IRQ_EINT0和IRQT_RISING这些变量

2.在second_drv_open函数中,申请4个中断:

/* IRQ_EINT0: 中断号, 定义在 asm/arch/irqs.h,被linux/irq.h调用buttons_irq : 中断服务函数,IRQT_ BOTHEDGE: 双边沿中断, 定义在 asm/irq.h,被linux/irq.h调用“S1”: 保存文件到/proc/interrupt/S1,1: dev_id,中断函数的参数, 被用来释放中断服务函数,中断时并会传入中断服务函数*/request_irq(IRQ_EINT0, buttons_irq,IRQT_BOTHEDGE, “S1”, 1); request_irq(IRQ_EINT2, buttons_irq,IRQT_ BOTHEDGE, “S2”, 1);request_irq(IRQ_EINT11, buttons_irq,IRQT_ BOTHEDGE, “S3”, 1);request_irq(IRQ_EINT19, buttons_irq,IRQT_ BOTHEDGE, “S4”, 1);

3.在file_oprations结构体中添加.release成员函数,用来释放中断

static struct file_operations second_drv_fops={ .owner = THIS_MODULE, .open = second_drv_open, .read = second_drv_read, .release=second_drv_class, //里面添加free_irq函数,来释放中断服务函数};

然后写.release成员函数,释放中断:

int second_drv_class(struct inode *inode, struct file *file){ free_irq(IRQ_EINT0,1); free_irq(IRQ_EINT2,1); free_irq(IRQ_EINT11,1); free_irq(IRQ_EINT19,1); return 0;}

4.写action->handler中断服务函数,在第2小节里request_irq函数的中断服务函数是buttons_irq

static irqreturn_t buttons_irq (int irq, void *dev_id) //irq:中断号, void *:表示支持所有类型{ printk(“irq=%d”); return IRQ_HANDLED;}

5.make后,然后放在开发板里insmod,并挂载好了buttons设备节点,如下图:

6.通过exec 5

如下图,使用ps查看-sh进程为801,然后ls -l /proc/801/fd 找到描述符5指向/dev/buttons

如下图,并申请中断,当有按键按下时,就进入中断服务函数buttons_irq()打印数据:

6.通过exec 5

会进入.release成员second_drv_class()函数释放中断,

然后cat /proc/interrupts会发现申请的中断已经注销掉了,在-sh进程fd文件里也没有文件描述符5

7.改进中断按键驱动程序

使用等待队列,让read函数没有中断时,进入休眠状态,降低CPU.

使用dev_id来获取不同按键的状态,是上升沿还是下降沿触发?

7.1接下来要用到以下几个函数:

s3c2410_gpio_getpin(unsigned int pin); //获取引脚高低电平

pin: 引脚名称,例如:S3C2410_GPA0,定义在

队列3个函数(声明队列,唤醒队列,等待队列):

static DECLARE_WAIT_QUEUE_HEAD(qname); 

声明一个新的等待队列类型的中断

qname:就是中断名字,被用来后面的唤醒中断和等待中断

wake_up_interruptible(*qname); 

唤醒一个中断,会将这个中断重新添加到runqueue队列(将中断置为TASK_RUNNING状态)

qname:指向声明的等待队列类型中断名字

wait_event_interruptible(qname, condition); 

等待事件中断函数,用来将中断放回等待队列,

前提是condition要为0,然后将这个中断从runqueue队列中删除(将中断置为TASK_INTERRUPTIBLE状态),然后会在函数里一直for(; ;)判断condition为真才退出

注意:此时的中断属于僵尸进程(既不在等待队列,也不在运行队列),当需要这个进程时,需要使用wake_up_interruptible(*qname)来唤醒中断

qname: (wait queue):为声明的等待队列的中断名字

condition:状态,等于0时就是中断进入休眠, 1:退出休眠

7.2 驱动程序步骤

(1)定义引脚描述结构体数组,每个结构体都保存按键引脚和初始状态,然后在中断服务函数中通过s3c2410_gpio_getpin()来获取按键是松开还是按下(因为中断是双边沿触发),并保存在key_val里(它会在.read函数发送给用户层)

 /* *引脚描述结构体 */ struct pin_desc{ unsigned int pin; unsigned int pin_status;}; /* *key初始状态(没有按下): 0x01,0x02,0x03,0x04 *key状态(按下): 0x81,0x82,0x83,0x84 */struct pin_desc pins_desc[4]={ {S3C2410_GPF0,0x01 },  {S3C2410_GPF2, 0x02 }, {S3C2410_GPG3, 0x03 }, {S3C2410_GPG11,0x04},} ;

(2)声明等待队列类型的中断button_wait:

static DECLARE_WAIT_QUEUE_HEAD(button_ wait); //声明等待队列类型的中断

(3)定义全局变量even _press,用于中断事件标志:

static volatile int even _press = 0;

(4)在.read函数里,将even _press置0放入等待事件中断函数中,判断even _press为真,才发送数据:

even_press = 0; wait_event_interruptible(button_ wait, even _press); //当even _press为真,表示有按键按下,退出等待队列 copy_to_user(buf, &key_val, 1); //even _press为真,有数据了,发送给用户层 

(5)在中断服务函数里,发生中断时, 就将even _press置1,并唤醒中断button_wait(.read函数里就会发送数据给用户层):

even _press = 0; wake_up_interruptible(&button_wait); //唤醒中断

7.3 更改测试程序second_interrupt_text.c

最终修改如下:

#include  //调用sys目录下types.h文件#include  //stat.h获取文件属性#include #include #include /*secondtext while一直获取按键信息 */int main(int argc,char **argv){ int fd,ret; unsigned int val=0;  fd=open("/dev/buttons

linux 按键驱动中断 rockchip_7.自己写中断方式按键驱动程序(详解)相关推荐

  1. linux中以A开头的函数使用方式历程及详解

    A开头的Linux C函数 abort 异常终止程序 abort函数在调用的时候,会触发SIGABRT信号 #include <stdlib.h> #include <signal. ...

  2. 从头开始写STM32F103C8T6驱动库(四)——编写延时函数,详解Systick

    系列文章目录 Github开源地址 从头开始写STM32F103C8T6驱动库(一)--STM32CubeMX创建并调整工程结构 从头开始写STM32F103C8T6驱动库(二)--编写系统初始化程序 ...

  3. 19. linux中权限详解,Linux权限位,读写执行权限真正含义,chmod详解

    linux中权限详解,Linux权限位,读写执行权限真正含义,chmod详解 文章目录 Linux权限位 读写执行 三种权限真正含义和作用 权限对文件的作用 权限对目录的作用 示例 chmod 使用数 ...

  4. linux系统编程之进程(八):守护进程详解及创建,daemon()使用

    linux系统编程之进程(八):守护进程详解及创建,daemon()使用 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等 ...

  5. linux修改zip中文件,Linux下修改jar、zip等文件内的文件详解

    Linux下修改jar.zip等文件内的文件详解 Linux下修改jar.zip等文件内的文件详解 看到很多同事在Linux环境下修改jar包内的文本文件或zip中的文本文件时,经常是先把jar包或z ...

  6. linux系统编程笔记02——Linux命令:修改文件权限命令chmod、chgrp、chown详解

    Linux命令:修改文件权限命令chmod.chgrp.chown详解 Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权限 ...

  7. linux shell 字符串操作(长度,查找,替换)详解 BASH

    linux shell 字符串操作(长度,查找,替换)详解 在做shell批处理程序时候,经常会涉及到字符串相关操作.有很多命令语句,如:awk,sed都可以做字符串各种操作. 其实shell内置一系 ...

  8. Linux 创建网页服务,Linux使用Node.js建立访问静态网页的服务实例详解

    Linux使用Node.js建立访问静态网页的服务实例详解 一.安装node.js运行所需要的环境,: 二.创建node目录(/node/www),并在目录下创建node.js服务文件server.j ...

  9. linux两台服务器传输,Linux两台服务器之间高速数据传输命令:scp应用详解

    Linux两台服务器之间高速数据传输命令:scp应用详解 Linux scp命令用于Linux之间复制文件和目录到另外一台,这个命令在多台服务器之间传输还是非常有用的,速度也是非常快的.比window ...

最新文章

  1. 上海交大 CDNet:基于YOLOv5改进的 人行道 斑马线和汽车过线行为检测
  2. 瞬变电磁法的基本原理与TEM正演技术
  3. 学习笔记(23):Python网络编程并发编程-开启线程的两种方式
  4. 面试求职中你需要了解的Java面向对象
  5. ASP连接各类数据库的语句
  6. 嵌入式电路设计(51单片机电路设计)
  7. 《数据挖掘概念与技术》读书笔记(一)
  8. 简易XML文件对比工具
  9. Unity3d是目前主流的游戏开发引擎
  10. 银联支付接口申请开发教程-傲付宝
  11. 2037 data maker
  12. 选拔人才要关注的七个方面
  13. 计算机专业必须用英语口语要求,哪些专业需要英语口语考试
  14. 在windows 20003 下IIS6.0支持PHP的配置方
  15. 足疗小张和面向对象的7个设计原则
  16. Web3j使用教程(1)
  17. 【Java中实现微信公众号模板消息推送】
  18. java查看so函数_java - 加入星火功能时,Eclipse不检测的Java main()函数 - SO中文参考 - www.soinside.com...
  19. STM32 Cube ADC 测量土壤湿度
  20. PHP简单实现“相关文章推荐”功能的方法

热门文章

  1. 最详细的FPN论文笔记
  2. 2021年下半年网络工程师下午真题及答案解析
  3. 值得关注的AI信息安全公司
  4. HP DL G8系列服务器安装Server2003系统显卡驱动的问题
  5. vue中 vue-router的路由的2种模式 (原生js模拟演示)
  6. Android 程式开发:(二十)内容提供者 —— 20.6 自定义ContentProvider的使用
  7. Java编程思想学习(一)----对象导论中多态的理解
  8. 监控页面后退前进,浏览器文档加载事件之pageshow、pagehide
  9. WPF调用图片路径,或资源图片
  10. Android开发笔记(二)