s3c2440使用中断方式读取按键终端

来源:互联网 发布:mac怎么删除东西 编辑:程序博客网 时间:2024/05/16 11:14
/*功能:使用中断方式读取按键终端
2016年5月4日22:54:53
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>




static struct class *thirddrv_class;
static struct class_device *thirddrv_class_devs[4];


volatile unsigned long * gpfcon;
volatile unsigned long * gpfdat;


volatile unsigned long * gpgcon;
volatile unsigned long * gpgdat;




//serial21285_tx_chars




static irqreturn_t buttons_irq(int irq, void *dev_id)
{
printk("irq = %d\n",irq);


return IRQ_HANDLED;
}


static int third_drv_open(struct inode * inode, struct file * file)
{
/*配置GPF0,2  位输入引脚 */
/*配置GPG3,11为输入引脚 */
/*
IRQ_EINT0是在irqs.h中定义的
IRQT_BOTHEDGE是在s3c_irqext_type函数中找到,在irq.h中定义




*/
//向内核注册中断处理函数
request_irq(IRQ_EINT0,buttons_irq,IRQT_BOTHEDGE,"s2",1);
request_irq(IRQ_EINT2,buttons_irq,IRQT_BOTHEDGE,"s3",1);
request_irq(IRQ_EINT11,buttons_irq,IRQT_BOTHEDGE,"s4",1);
request_irq(IRQ_EINT19,buttons_irq,IRQT_BOTHEDGE,"s5",1);





return 0;
}










/*函数的参数是用户空间的函数的参数*/
static ssize_t third_drv_read(struct file *file, const __user char *buffer,size_t count, loff_t *ppos)
{
if(count != sizeof(key_vals)
return -EINVAL;//返回错误值

/*返回四个引脚的电平状态*/
unsigned char key_vals[4];
int regval;
/*读GPF0,2引脚*/
regval = *gpfdat;
key_vals[0] = (regval & (1<<0)) ? 1 : 0;
key_vals[1] = (regval & (1<<2)) ? 1 : 0;


/*读GPG3,11引脚*/
regval = *gpgdat;
key_vals[2] = (regval & (1<<3)) ? 1 : 0;
key_vals[3] = (regval & (1<<11)) ? 1 : 0;


/*用户空间和内核空间之间是通过参数来传递的,
static ssize_t third_drv_read(struct file *file, const __user char *buffer,size_t count, loff_t *ppos)
函数的参数是用户空间的,内核空间的参数是我们自己定义的,他们之间传递参数都是用指针来实现的
*/
copy_to_user(buffer ,key_vals,sizeof(key_vals));
return sizeof(key_vals);





}




/*入口函数*/
int major;
static int third_drv_init (void)
{
major = register_chrdev(0,"secod_drv",&third_drv_fops);


thirddrv_class = class_create(THIS_MODULE, "secod_drv");//创建个类

thirddrv_class_devs = class_device_create(thirddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */



gpfcon = (volatile unsigned long *)ioremap(0x56000050,16);
gpfdat = gpfcon + 1;//指向0x56000054


gpgcon = (volatile unsigned long *)ioremap(0x56000060,16);
gpgdat = gpgcon + 1;//指向0x56000064


return 0;


}






/*出口函数*/
int major;
static int third_drv_exit (void)
{
unregister_chrdev(major,"secod_drv");

class_device_unregister(thirddrv_class_devs);
 
class_destroy(thirddrv_class);



iounmap(gpfcon);
iounmap(gpgcon);
return 0;


}


int third_drv_close (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;


}




static struct file_operations third_drv_fops = {
    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open   =   third_drv_open,    //表示将first_drv_open函数的地址赋给file_operations结构体中open函数,
.read =third_drv_read, //以后执行 first_drv_open函数时会自动调用file_operations结构体中的open函数
.close =   third_drv_close,//关闭设备的时候,释放open函数中配置的irq
};


/*修饰*/
modules_init(third_drv_init);
modules_exit(third_drv_exit);


MODULE_LICENSE("GPL");



0 0
原创粉丝点击