⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myirq.c

📁 2440 下的5*5按键驱动程序.请参看具体代码内容.
💻 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 + -