📄 myirq.c
字号:
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/hardware.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm-arm/arch-s3c2410/regs-gpio.h>
#include <asm/io.h>
#include <asm-arm/arch-s3c2410/irqs.h>
#include <asm-arm/irq.h>
#include <linux/interrupt.h>
#include <linux/wait.h>#include <linux/irq.h>#include "devfs_fs_kernel.h"
#define BUTTON_IRQ IRQ_EINT8 //申请的中断号 s1//------------------------------------------------------
#define DEVICE_NAME "button" //设备名字
#define button_Major 232
DECLARE_WAIT_QUEUE_HEAD(wq); //申请等待队列并初始化
static unsigned char key_down_cnt=0; //中断计数
static int ev_press=0; //唤醒等待的条件
//设备号
static irqreturn_t button_irq_ser(int irq,void *dev_id,struct pt_regs *regs) //中断服务程序
{ key_down_cnt++; //来一次,中断计数加一
ev_press = 1; //表示中断发生了
wake_up_interruptible(&wq); //唤醒休眠的进程
return 0;
}
static int s3c2410_button_open(struct inode *inode,struct file *filp) //open 函数
{ int ret;
ret= request_irq(BUTTON_IRQ,button_irq_ser,SA_INTERRUPT,DEVICE_NAME,NULL); //注册中断
if(ret<0)
{ printk("could not register interrupt !");
return ret;
}
printk("interrupt register successed");
return 0;
}
static int s3c2410_button_release(struct inode *inode,struct file *filp) //关闭设备
{ free_irq(BUTTON_IRQ,NULL); //释放中断
return 0;
}
//读设备
static ssize_t s3c2410_button_read(struct file *filp,char __user *buff,size_t count,loff_t *offp)
{ //printk("sleep\n");
//如果ev_press = 0,则继续休眠
wait_event_interruptible(wq,ev_press);
//若执行到这儿,ev_press = 1
printk("wake up \n");
//清除ev_press
ev_press = 0;
//拷贝key_down_cnt 到用户空间
copy_to_user(buff,(const void *)&key_down_cnt,sizeof(char));
printk("process is waked up after");
// key_down_cnt = 0;
return sizeof(unsigned char);
}
static struct file_operations s3c2410_button_flops = {
.owner = THIS_MODULE,
.open = s3c2410_button_open,
.read = s3c2410_button_read,
.release = s3c2410_button_release,
};
//模块初始化
static int __init s3c2410_button_init(void)
{ /* int ret; ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &qq2440_buttons_fops); if (ret < 0) { printk(DEVICE_NAME " can't register major number\n"); return ret; } devfs_mk_cdev(MKDEV(BUTTON_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME); printk(DEVICE_NAME " initialized\n"); return 0;}*/ int ret;
set_irq_type(BUTTON_IRQ,IRQT_FALLING); //设置触发中断的类型,下降沿触发
ev_press = 0; //初始化ev_press
//注册设备,返回主设备号
ret=register_chrdev(button_Major,DEVICE_NAME,&s3c2410_button_flops);
if(ret<0)
{
printk(DEVICE_NAME"can not register the number!");
return ret;
}
//建立设备节点
devfs_mk_cdev(MKDEV(button_Major,0),S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,DEVICE_NAME);
printk("button_init initialized successed!\n");
return 0;
}
//卸载模块
static void __exit s3c2410_button_exit(void)
{
devfs_remove(DEVICE_NAME);
unregister_chrdev(button_Major,DEVICE_NAME);
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("the s3c2410 key interrupt driver");
module_init(s3c2410_button_init);
module_exit(s3c2410_button_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -