设为首页 加入收藏

TOP

在Linux下的中断方式读取按键驱动程序(二)
2016-12-12 08:15:23 】 浏览:327
Tags:Linux 中断 方式 读取 按键 驱动程序


//write时候调用


static ssize_t Eint_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)


{


}


//read时候调用


//读取按键值


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


{


if(size != 1)


return -EINVAL;


if (file->f_flags & O_NONBLOCK)


{


//非阻塞 立马返回


if (!ev_press)


return -EAGAIN;


}


else


{


//如果没有按键按下 则休眠


wait_event_interruptible(button_waitq,ev_press);


}


//如果有按键动作发生的话 则返回


copy_to_user(buf, &key_val, 1);


ev_press = 0;//清中断标志位


// printk("key_val = 0x%x\n", key_val);


}


//关闭驱动时候调用


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


{


#if usingatomic


atomic_inc(&canopen);//自加1


#else


up(&button_lock);


#endif


free_irq(IRQ_EINT0, &pins_desc[0]);//EINT0释放中断


free_irq(IRQ_EINT2, &pins_desc[1]);//EINT2释放中断


free_irq(IRQ_EINT11, &pins_desc[2]);//EINT11释放中断


free_irq(IRQ_EINT19, &pins_desc[3]);//EINT19释放中断


printk("Eint_drv_colse successed!\n");


}


//poll时候调用


// 在规定时间内没有按下按键 就返回超时


//中断没有发生 就return 0,在do_sys_poll中就会让系统休眠,唤醒休眠是chedule_timeout(__timeou)超时


//中断发生 return POLLIN | POLLRDNORM,在do_sys_poll退出休眠,唤醒进程


static unsigned int Eint_drv_poll(struct file *file, poll_table *wait)


{


unsigned int mask = 0;


poll_wait(file, &button_waitq, wait); //加入队列 不会立即休眠


if (ev_press)


mask |= POLLIN | POLLRDNORM;


return mask;


}


//在应用程序中使用fcnt() 时候调用


static int Eint_drvl_fasync (int fd, struct file *filp, int on)


{


printk("\ndrivec:signal_fasync successed !\n");


return fasync_helper (fd, filp, on, &button_async_queue);


}


//告诉内核


static struct file_operations Eint_drv_fops = {


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


.open = Eint_drv_open,


.write = Eint_drv_write,


.read = Eint_drv_read,


.release= Eint_drv_colse,


.poll = Eint_drv_poll,


.fasync = Eint_drvl_fasync,


};


int major;//自动分配主设备号


//安装驱动的时候调用


//注册驱动 创建设备类 创建设备节点 创建虚拟地址 创建定时器任务


int Eint_drv_init(void)


{


// 创建一个定时器


init_timer(&buttons_timer);


buttons_timer.function = buttons_timer_function;


add_timer(&buttons_timer);


major=register_chrdev( 0, "key_drv",&Eint_drv_fops);//告诉内核 注册驱动


Eint_class = class_create(THIS_MODULE, "key_drv");//获取一个设备信息类


if (IS_ERR(Eint_class))


return PTR_ERR(Eint_class);


Eint_class_devs = class_device_create(Eint_class, NULL, MKDEV(major, 0), NULL, "buttons");


if (unlikely(IS_ERR(Eint_class_devs)))


return PTR_ERR(Eint_class_devs);


//转换虚拟地址


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


gpfdat = gpfcon+1;


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


gpgdat =gpgcon+1;


printk("Eint_drv_init successed!\n");


return 0;


}


//卸载驱动程序的时候调用


//卸载驱动 删除设备 删除设备节点 删除地址映射


void Eint_drv_exit(void)


{


unregister_chrdev( major, "key_drv");//卸载驱动


class_device_unregister(Eint_class_devs);//删除设备


class_destroy(Eint_class);//删除设备节点


iounmap(gpgcon);//删除地址映射


iounmap(gpfcon);


printk("\nEint_drv_exit successed!\n");


}


module_init(Eint_drv_init);


module_exit(Eint_drv_exit);


MODULE_LICENSE("GPL");


首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Linux驱动开发之块设备初入门 下一篇NOR Flash驱动编写札记

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目