天嵌 ARM开发社区

 找回密码
 注册
查看: 2753|回复: 1

关于按键中断的问题,

[复制链接]
wang12zhedi 发表于 2012-9-21 15:01:54 | 显示全部楼层 |阅读模式
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>

static struct class *button_class;
static struct class_device        *button_class_dev;
/* 定义变量*/
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);/*等待队列头,为休眠和唤醒做准备*/

/*中断事件标志,中断服务程序将其置1,read函数将它请0*/
static volatile int ev_press = 0;

static unsigned long gpio_table [] =
{
        S3C2410_GPF0,
        S3C2410_GPF1,
        S3C2410_GPF2,
        S3C2410_GPF4,
};

/* 用来指定GPIO引脚的功能:输出 */
static unsigned int gpio_cfg_table [] =
{
        S3C2410_GPF0_INP,
        S3C2410_GPF1_INP,
        S3C2410_GPF2_INP,
        S3C2410_GPF4_INP,
       
};
/*结构体类型的声明*/
struct pin_desc  {
        unsigned int pin;
        unsigned int pin_val;
};
unsigned int key_val;
/*当按下按键显示 0X01 0X02 0X04 0X08
当松开按键时,显示0X81 0X82 0X84 0X88
*/
struct pin_desc pins_desc[4] = {  //结构体数组初始化
        {S3C2410_GPF0, 0x01},
        {S3C2410_GPF1, 0x02},
        {S3C2410_GPF2, 0x03},
        {S3C2410_GPF4, 0x04},
};
/*
*确定按键值
*/
static  irqreturn_t button_irq(int irq,void *dev_id)
        {
       
        struct pin_desc * pindesc = (struct pin_desc *)dev_id;//(struct pin_desc *)强制类型转换
        unsigned int pin_value;
        pin_value=s3c2410_gpio_getpin(pindesc ->pin);
       
        if(pin_value )
                {
                 /*按下按键*/
                 key_val = 0x80 |pindesc->pin_val;
                }
        else
                {
                /*松开按键?/
               key_val = pindesc ->pin_val;
                }
        ev_press = 1;      //表示中断发生
        wake_up_interruptible(&button_waitq);  //  唤醒休眠
        //printk(" button_irq  occured\n");
        return IRQ_HANDLED;   /*return应该在函数的最后,不然return之后的代码不起作用的澹垮*/
       
        }

static int button_openNNN(struct inode *inode, struct file *file)  //此处的函数名可以随便热″?只要在fopsd的对应
                                                                                           //正确即可???????????
{
        /* 配置GPF0,2为输入引脚 */
         request_irq(IRQ_EINT0,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY4",&pins_desc[0]);
         request_irq(IRQ_EINT1,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY1",&pins_desc[1]);
         request_irq(IRQ_EINT2,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY3",&pins_desc[2]);
         request_irq(IRQ_EINT4,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY2",&pins_desc[3]);
               
      // printk("button_open\n");
        return 0;
}

ssize_t button_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
        /* 如果没有按键动作发生,休眠 */
      wait_event_interruptible(button_waitq,ev_press);////当有按键按下时,中断当前运行(终止当前休眠)
      //跳转到button_irq处继续运行,当button_irq运行完毕,再从此处继续向下运行
     /* 如果有按键动作发生,返回按键值 */
        if (size != 1)
                return -EINVAL;
       copy_to_user(buf,&key_val,1);

        ev_press = 0;
        //printk("button_read\n");
        return 1;
}
   /*释放中断函数*/
int button_release(struct inode * inode, struct file * file)
{
    free_irq(IRQ_EINT0,&pins_desc[0]);
    free_irq(IRQ_EINT1,&pins_desc[1]);
    free_irq(IRQ_EINT2,&pins_desc[2]);
    free_irq(IRQ_EINT4,&pins_desc[3]);
   // printk("button_release\n");
}

static struct file_operations button_fops = {
    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open   =   button_openNNN,     
    .read        =        button_read,         
    .release = button_release,
};


int major;
static int button_init(void)
{
        major = register_chrdev(0, "button_drv", &button_fops);

      button_class = class_create(THIS_MODULE, "buttons_irq");

        button_class_dev = device_create(button_class, NULL, MKDEV(major, 0), NULL, "Buttons_irq"); /* /dev/buttons */

   printk("button_init\n");
        return 0;
}

static void button_exit(void)
{
        unregister_chrdev(major, "button");
      device_unregister(button_class_dev);
      class_destroy(button_class);
      printk("button_exit\n");
        return 0;
}


module_init(button_init);

module_exit(button_exit);

MODULE_LICENSE("GPL");

这是我参考一个例程写的中断程序,但中断处理函数static  irqreturn_t button_irq(int irq,void *dev_id)
中的
struct pin_desc * pindesc = (struct pin_desc *)dev_id;怎么理解,

我的理解是:(struct pin_desc *)dev_id把void *dev_id强制转换成struct pin_desc 类型,但问题它怎么又能指向pin_val (key_val = 0x80 |pindesc->pin_val;)就能输出
struct pin_desc pins_desc[4] = {  //结构体数组初始化
        {S3C2410_GPF0, 0x01},
        {S3C2410_GPF1, 0x02},
        {S3C2410_GPF2, 0x03},
        {S3C2410_GPF4, 0x04},
};0X01,0X02,0X03,0X04呢?我认为只有pins_desc才能指向它们的,请解释一下
亚瑟王 发表于 2012-9-24 14:09:06 | 显示全部楼层
request_irq函数的原型:
int request_irq(
unsigned int irq,
    irqreturn_t (*handler)(int, void *, struct pt_regs *),
    unsigned long irqflags,
    const char *devname,
    void *dev_id );
其中irqreturn_t (*handler)(int, void *, struct pt_regs *),函数中的第二个参数就是reques_irq中的dev_id参数了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2025-6-17 09:42 , Processed in 2.047159 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表