TQ2440 中断按键驱动
来源:互联网 发布:用java代码输出我爱你 编辑:程序博客网 时间:2024/05/16 08:59
按键驱动程序:
#include<linux/module.h>#include<linux/kernel.h>#include<linux/fs.h>#include<linux/init.h>#include<linux/delay.h>#include<asm/irq.h>#include<linux/poll.h>#include<linux/irq.h>#include<asm/irq.h>#include<linux/interrupt.h>#include<asm/uaccess.h>#include<mach/regs-gpio.h>#include<mach/hardware.h>#include<linux/device.h>#include<linux/miscdevice.h>#include<linux/cdev.h>#define DEVICE_NAME "mybuttons"struct button_irq_desc{int irq;//中断号,中断号唯一表示一个中断int pin;//中断控制的寄存器,该寄存器的值由中断引脚设置,我们希望从该寄存器读出控制信息int pin_setting;//中断的引脚,该引脚的电平由按键来控制,从而最终我们由按键控制了寄存器的值int number;//编号char *name;//名称};//用来指定按键所用的外部中断引脚及中断触发方式、名字static struct button_irq_desc button_irqs[] ={{IRQ_EINT1, S3C2410_GPF1, S3C2410_GPF1_EINT1, 0, "KET1"},{IRQ_EINT4, S3C2410_GPF4, S3C2410_GPF4_EINT4, 1, "KET2"},{IRQ_EINT2, S3C2410_GPF2, S3C2410_GPF2_EINT2, 2, "KET3"},{IRQ_EINT0, S3C2410_GPF0, S3C2410_GPF0_EINT0, 3, "KET4"},};//按键值static volatile int key_values;//等待队列:当没有按键被按下,即没有触发中断时,如果有进程调用read函数,则该进程进入休眠static DECLARE_WAIT_QUEUE_HEAD(button_waitq);//定义了一个整型变量用于判定按键是否被按下,0未按下,1按下,中断事件标志,中断服务程序将它置1,read函数将其清0static volatile int ev_press = 0;//中断服务程序static irqreturn_t irq_interrupt(int irq,void *dev_id){struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;int up;up = s3c2410_gpio_getpin(button_irqs->pin);if(up)key_values = (button_irqs->number+1)+0x80;elsekey_values = (button_irqs->number+1);ev_press = 1;//表示中断发生wake_up_interruptible(&button_waitq);//唤醒休眠的进程return IRQ_RETVAL(IRQ_HANDLED);}static int irq_open(struct inode *inode,struct file *file){ int i;int err = 0; for(i = 0;i < sizeof(button_irqs)/sizeof(button_irqs[0]);i++) {//设置引脚 s3c2410_gpio_cfgpin(button_irqs[i].pin,button_irqs[i].pin_setting);//注册中断err = request_irq(button_irqs[i].irq,irq_interrupt,IRQ_TYPE_EDGE_BOTH,button_irqs[i].name,(void *)&button_irqs[i]);// request_irq 的返回值: 0 指示成功,或返回一个负的错误码,如 -EBUSY 表示另一个驱动已经占用了你所请求的中断线。if(err)break; }if(err){i--;for(;i >= 0; i--){if(button_irqs[i].irq < 0)continue;//释放已注册的中断disable_irq(button_irqs[i].irq);free_irq(button_irqs[i].irq,(void *)&button_irqs[i]);}return -EBUSY;}ev_press = 1; return 0;}static int irq_close(struct inode *inode,struct file *file){int i;for(i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++){//释放已注册的中断disable_irq(button_irqs[i].irq);free_irq(button_irqs[i].irq,(void *)&button_irqs[i]);}return 0;}static int irq_read(struct file *file,char __user *buff,size_t count,loff_t *offp){unsigned long err;if(!ev_press){if(file->f_flags & O_NONBLOCK)return -EAGAIN;else//如果ev_press等于0,则进入休眠wait_event_interruptible(button_waitq,ev_press);}//按键状态复制给用户进程err = copy_to_user(buff,&key_values,1);//这里ev_press等于1,将它清0ev_press = 0;return 1;}//当用户程序调用select函数时,本函数被调用,如果有按键数据,则select函数会立刻返回,如果没有按键数据,本函数使用poll_wait等待static unsigned int irq_poll(struct file *file,struct poll_table_struct *wait){unsigned int mask = 0;poll_wait(file,&button_waitq,wait);if(ev_press)mask |= POLLIN | POLLRDNORM;return mask;}static struct file_operations buttons_fops ={ .owner = THIS_MODULE, .open = irq_open, .release = irq_close,.read = irq_read,.poll = irq_poll,};static struct miscdevice misc = { .minor =MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &buttons_fops,};static int __init buttons_init(void){ int reg; reg = misc_register(&misc); printk(DEVICE_NAME" initialized\n"); return reg;}static void __exit buttons_exit(void){ misc_deregister(&misc); printk("deregister\n");}module_init(buttons_init);module_exit(buttons_exit);MODULE_AUTHOR("xh");MODULE_DESCRIPTION("learn");MODULE_LICENSE("GPL");
Makefile:
ifneq($(KERNELRELEASE),)obj-m :=key.oelse#KERNELDIR :=/lib/modules/2.6.32-21-generic/buildKERNELDIR :=/opt/EmbedSky/linux-2.6.30.4PWD :=$(shell pwd)default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesendifclean:rm -f *.o *.ko.PHONY:clean
#include<stdlib.h>#include<stdio.h>#include<unistd.h>#include<sys/ioctl.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<sys/select.h>#include<sys/time.h>#include<errno.h>#define DEV "/dev/mybuttons"int main(void){int i;int buttons_fd;int key_value = 0;struct timeval tv;//打开设备文件buttons_fd = open(DEV,O_RDWR);if(buttons_fd < 0){perror(DEV);exit(1);}while(1){fd_set rds;int ret;FD_ZERO(&rds);FD_SET(buttons_fd,&rds);//设置select超时时间,1stv.tv_sec = 1;tv.tv_usec = 0;//调用selectret = select(buttons_fd+1,&rds,NULL,NULL,&tv);if(ret < 0){perror("select");exit(1);}if(ret == 0){printf("Timeout\n");}//能读到数据else if(FD_ISSET(buttons_fd,&rds)){//调用read,读取键盘数据int ret = read(buttons_fd,&key_value,1);if(ret != 1){if(errno != EAGAIN)perror("read buttons\n");continue;}else{//打印printf("key_val = 0x%x\n",key_value);}}}return 0;}
- TQ2440 中断按键驱动
- tq2440 按键驱动 中断方式
- tq2440 按键中断 去抖 改进版 驱动
- TQ2440按键驱动1
- TQ2440按键驱动2
- 基于tq2440的按键中断服务程序
- 外部中断按键驱动
- fl2440按键中断驱动
- 按键中断驱动实例
- s3c6410中断按键驱动
- s5pc100中断按键驱动
- OK6410 按键中断驱动
- 按键中断驱动
- 按键中断驱动
- 按键中断驱动
- mtk 按键中断驱动
- 中断按键驱动
- 驱动-按键-中断模式
- dom4j parse xml
- 多线程下载网络歌曲&播放歌曲&并用seekbar调节进度&显示歌曲两边的时间
- C语言知识总结(近期笔试遇到的,锐捷,多米)
- Ubiquitous Religions(并查集)
- Rhel启动过程分析
- TQ2440 中断按键驱动
- Cocos2d-x 开发辅助之Texture packer合并图片
- 马尔可夫链蒙特卡罗算法
- 第八周项目1-计算加班费
- linux 替换目录下所有文件中某个字符串命令
- IOS开发之手势——UIGestureRecognizer 共存
- Codeforces Round #207 (Div. 1)
- windows获得服务配置(驱动路径)
- C#适应不同分辨率