驱动-按键-中断模式

发布者:快乐之源最新更新时间:2019-09-16 来源: eefocus关键字:驱动  按键  中断模式 手机看文章 扫描二维码
随时随地手机看文章

驱动-按键-中断模式




eint_drv.c


/*******驱动代码************/

 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

 

static struct class *eintdrv_class;

static struct class_device *eintdrv_class_dev;

 

volatile unsigned long *gpfcon;

volatile unsigned long *gpfdat;

 

volatile unsigned long *gpgcon;

volatile unsigned long *gpgdat;

 

/*声明等待队列头,名字为button_waitq*/

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

 

/* 中断事件标志, 中断服务程序将它置1,eint_drv_read将它清0 */

static volatile int ev_press = 0;

 

 

struct pin_desc{

unsigned int pin;

unsigned int key_val;

};

 

 

/* 键值: 按下时, 0x01, 0x02, 0x03, 0x04 */

/* 键值: 松开时, 0x81, 0x82, 0x83, 0x84 */

static unsigned char key_val;

 

struct pin_desc pins_desc[4] = {

{S3C2410_GPF0, 0x01},

{S3C2410_GPF2, 0x02},

{S3C2410_GPG3, 0x03},

{S3C2410_GPG11, 0x04},

};

 

 

/*

  * 确定按键值

  */

static irqreturn_t buttons_irq(int irq, void *dev_id)

{

struct pin_desc * pindesc = (struct pin_desc *)dev_id;

unsigned int pinval;

pinval = s3c2410_gpio_getpin(pindesc->pin);

 

if (pinval)

{

/* 松开 */

key_val = 0x80 | pindesc->key_val;

printk("pinval1=%dn", pinval);

 

}

else

{

/* 按下 */

key_val = pindesc->key_val;

printk("pinval2=%dn", pinval);

}

 

  /* 表示中断发生了 */

  ev_press=1;

 

  /* 唤醒休眠的进程 */

  wake_up_interruptible(&button_waitq);

 

 

return IRQ_RETVAL(IRQ_HANDLED);

}

 

static int eint_drv_open(struct inode *inode, struct file *file)

{

/* 配置GPF0,2为输入引脚 */

//*gpfcon &= ~((3<<4)|(3<<0));

*gpfcon &=~((1<<0)|(1<<2));

 

/* 配置GPG3,11为输入引脚 */

//*gpgcon &= ~((3<<6)|(3<<22));

*gpgcon &= ~((1<<3)|(1<<11));

/*request_irq(中断类型,响应函数,触发方式,名称,数据)*/ 

request_irq(IRQ_EINT0, buttons_irq, IRQT_BOTHEDGE, "S2", &pins_desc[0]);

    request_irq(IRQ_EINT2, buttons_irq, IRQT_BOTHEDGE, "S3", &pins_desc[1]);

    request_irq(IRQ_EINT11, buttons_irq, IRQT_BOTHEDGE, "S4", &pins_desc[2]);

    request_irq(IRQ_EINT19, buttons_irq, IRQT_BOTHEDGE, "S5", &pins_desc[3]);  

 

 

 

return 0;

}

 

ssize_t eint_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)

{

if (size != 1)

return -EINVAL;

 

/* 如果没有按键动作, 休眠 */

wait_event_interruptible(button_waitq,ev_press);

 

/* 如果有按键动作, 返回键值 */

copy_to_user(buf, &key_val, 1);

ev_press = 0;

return 1;

}

 

 

int eint_drv_close(struct inode *inode, struct file *file)

{

/*free_irq*/

free_irq(IRQ_EINT0,&pins_desc[0]);

free_irq(IRQ_EINT2,&pins_desc[1]);

free_irq(IRQ_EINT11,&pins_desc[2]);

free_irq(IRQ_EINT19,&pins_desc[3]);

 

return 0;

}

 

 

static struct file_operations sencod_drv_fops = {

    .owner   =  THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

    .open    =  eint_drv_open,     

.read = eint_drv_read,    

.release =  eint_drv_close,    

};

 

 

int major;

static int eint_drv_init(void)

{

major = register_chrdev(0, "eint_drv", &sencod_drv_fops);

 

eintdrv_class = class_create(THIS_MODULE, "eint_drv");

 

eintdrv_class_dev = class_device_create(eintdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */

 

gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);

gpfdat = gpfcon + 1;

 

gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);

gpgdat = gpgcon + 1;

 

return 0;

}

 

static void eint_drv_exit(void)

{

unregister_chrdev(major, "eint_drv");

class_device_unregister(eintdrv_class_dev);

class_destroy(eintdrv_class);

iounmap(gpfcon);

iounmap(gpgcon);

return 0;

}

 

 

module_init(eint_drv_init);

 

module_exit(eint_drv_exit);

 

MODULE_LICENSE("GPL");

 


eintTest.c



#include

#include

#include

#include

#include

 

/* thirddrvtest 

  */

int main(int argc, char **argv)

{

int fd;

unsigned char key_val;

fd = open("/dev/eintTest", O_RDWR);//O_RDWR 读、写打开。

if (fd < 0)

{

printf("can't open!n");

}

 

while (1)

{

read(fd, &key_val, 1);

printf("key_val = 0x%xn", key_val);

sleep(5);

}

return 0;

}

 


makefile

KERN_DIR = /work/system/linux-2.6.22.6

 

all:

make -C $(KERN_DIR) M=`pwd` modules 

 

clean:

make -C $(KERN_DIR) M=`pwd` modules clean

rm -rf modules.order

 

obj-m += eint_drv.o

关键字:驱动  按键  中断模式 引用地址:驱动-按键-中断模式

上一篇:按键-LED
下一篇:中断-按键控制LED灯

小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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