ok6410增加工作队列的platform按键驱动程序
来源:互联网 发布:美发软件那个好 编辑:程序博客网 时间:2024/06/06 02:54
plat_btn_device.c
#include <linux/module.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/platform_device.h>#include <linux/interrupt.h>#include <linux/device.h>#include <linux/io.h>#define DEVICE_NAME "ok6410_plat_btn"/*平台资源的定义,按键中断*/static struct resource s3c_buttons_resource[] = {[0]={.start = IRQ_EINT(0),.end = IRQ_EINT(0),.flags = IORESOURCE_IRQ,},[1]={.start = IRQ_EINT(1),.end = IRQ_EINT(1),.flags = IORESOURCE_IRQ,},[2]={.start = IRQ_EINT(2),.end = IRQ_EINT(2),.flags = IORESOURCE_IRQ,},[3]={.start = IRQ_EINT(3),.end = IRQ_EINT(3),.flags = IORESOURCE_IRQ,},[4]={.start = IRQ_EINT(4),.end = IRQ_EINT(4),.flags = IORESOURCE_IRQ,},[5]={.start = IRQ_EINT(5),.end = IRQ_EINT(5),.flags = IORESOURCE_IRQ,}};static struct platform_device *s3c_buttons;static int __init platform_init(void){ s3c_buttons = platform_device_alloc(DEVICE_NAME,-1);//为平台设备s3c_buttons添加平台资源 platform_device_add_resources(s3c_buttons,&s3c_buttons_resource,6); /*平台设备的注册*/ platform_device_add(s3c_buttons);}static void __exit platform_exit(void){ platform_device_unregister(s3c_buttons);}module_init(platform_init);module_exit(platform_exit);MODULE_AUTHOR("Sola");MODULE_LICENSE("GPL");MODULE_ALIAS("platform:mini2440buttons");
plat_btn_driver.c
#include <linux/module.h>#include <linux/types.h>#include <linux/miscdevice.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/platform_device.h>#include <linux/interrupt.h>#include <linux/clk.h>#include <linux/uaccess.h>#include <linux/io.h>#include <mach/map.h>#include <linux/poll.h>#include <linux/irq.h>#include <asm/unistd.h>#include <linux/device.h>#define DRIVER_NAME "ok6410_plat_btn"//定义并初始化等待队列头static DECLARE_WAIT_QUEUE_HEAD(button_waitq);static volatile int ev_press = 0;static int key_value;static struct device *buttons_dev;/* platform device attached to */static struct resource *buttons_irq;int temp_irq;//保存当前按键中断的中断号struct delayed_work dwork;//用于按键中断底半部的延迟工作static int button_irqs[6];//中断号 /*按键中断处理函数*/static irqreturn_t buttons_interrupt(int irq, void *dev_id){temp_irq = irq;//保存当前中断的中断号schedule_delayed_work(&dwork,HZ/50);//延迟20ms,用作按键消斗,然后会自动调用延迟回调函数 return IRQ_RETVAL(IRQ_HANDLED);}/*延迟工作的回调函数*/static void buttons_work_func(struct work_struct *w){int i;for(i=0; i<6; i++){if(temp_irq == button_irqs[i]){//printk("==>interrput number:%d\n",irq); key_value = i;//获得键值ev_press =1;//键是否被按下//唤醒等待队列wake_up_interruptible(&button_waitq);}}}static int s3c6410_buttons_open(struct inode *inode, struct file *file){int i;int err = 0;/*注册中断*/for(i=0; i<6; i++){if (button_irqs[i] < 0) continue; /*中断触发方式:下降沿触发,中断接口函数*/ err = request_irq(button_irqs[i],buttons_interrupt,IRQF_TRIGGER_FALLING,NULL,NULL);if(err) break;}if (err) {i--;for (; i >= 0; i--) {if (button_irqs[i] < 0) {continue;}disable_irq(button_irqs[i]);free_irq(button_irqs[i], NULL);}return -EBUSY;} ev_press = 0; return 0;}static int s3c6410_buttons_close(struct inode *inode, struct file *file){ int i; for (i=0; i<6; i++) {if (button_irqs[i] < 0) {continue;}free_irq(button_irqs[i],NULL); } return 0;}static int s3c6410_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp){ unsigned long err; if (!ev_press) {//如果键没有被按下if (filp->f_flags & O_NONBLOCK)//如果是非阻塞模式,就直接返回return -EAGAIN;else//阻塞,直到按键按下wait_event_interruptible(button_waitq, ev_press); } ev_press = 0;//将键值送回到用户空间 err = copy_to_user(buff, &key_value, sizeof(key_value)); return sizeof(key_value);}static unsigned int s3c6410_buttons_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 ok6410_buttons_fops = { .owner = THIS_MODULE, .open = s3c6410_buttons_open,.release = s3c6410_buttons_close, .read = s3c6410_buttons_read,.poll = s3c6410_buttons_poll,};//声明一个混杂设备,设备名称为"buttons"static struct miscdevice ok6410_miscdev = { .minor = MISC_DYNAMIC_MINOR, .name ="buttons", .fops = &ok6410_buttons_fops,//操作集};/* device interface ,当发现匹配设备时会调用此函数*/static int ok6410_buttons_probe(struct platform_device *pdev){struct resource *res;struct device *dev;int ret;int size;int i;printk("probe:%s\n", __func__);dev = &pdev->dev;buttons_dev = &pdev->dev;/*平台资源获取*/ /*get irq number*/ for(i=0; i<6; i++){//获取中断号 buttons_irq = platform_get_resource(pdev,IORESOURCE_IRQ,i); if(buttons_irq == NULL){ dev_err(dev,"no irq resource specified\n"); ret = -ENOENT;return ret;}button_irqs[i] = buttons_irq->start;//printk("button_irqs[%d]=%d\n",i,button_irqs[i]); }//注册混杂设备ret = misc_register(&ok6410_miscdev);return ret;}static int ok6410_buttons_remove(struct platform_device *dev){misc_deregister(&ok6410_miscdev);return 0;}/*平台驱动定义*/static struct platform_driver ok6410_buttons_driver = {.probe= ok6410_buttons_probe,//探针函数.remove= ok6410_buttons_remove,.driver= {.owner= THIS_MODULE,.name= DRIVER_NAME,},};static char banner[] __initdata = "ok6410 Buttons Driver\n";static int __init buttons_init(void){printk(banner);/*平台驱动注册*/platform_driver_register(&ok6410_buttons_driver);/*初始化工作队列*/INIT_DELAYED_WORK(&dwork,buttons_work_func);return 0;}static void __exit buttons_exit(void){//平台驱动的注销platform_driver_unregister(&ok6410_buttons_driver);}module_init(buttons_init);module_exit(buttons_exit);MODULE_AUTHOR("Sola");MODULE_DESCRIPTION("ok6410 Buttons Driver");MODULE_LICENSE("GPL");
app-button.c
/* * Buttons Example for Matrix V * * Copyright (C) 2004 capbily - friendly-arm *capbily@hotmail.com */#include <stdio.h>#include <stdlib.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>int main(void){int buttons_fd;int key_value;buttons_fd = open("/dev/buttons", 0);if (buttons_fd < 0) {perror("open device buttons");exit(1);}for (;;) {fd_set rds;int ret;FD_ZERO(&rds);FD_SET(buttons_fd, &rds);ret = select(buttons_fd + 1, &rds, NULL, NULL, NULL);if (ret < 0) {perror("select");exit(1);}if (ret == 0) {printf("Timeout.\n");} else if (FD_ISSET(buttons_fd, &rds)) {int ret = read(buttons_fd, &key_value, sizeof key_value);if (ret != sizeof key_value) {if (errno != EAGAIN)perror("read buttons\n");continue;} else {printf("buttons_value: %d\n", key_value+1);}}}close(buttons_fd);return 0;}
实验现象:
- ok6410增加工作队列的platform按键驱动程序
- 基于platform的ok6410按键中断实验
- 基于platform的ok6410按键中断实验
- ok6410按键中断驱动程序
- OK6410的6个按键驱动程序(Linux),测试通过
- OK6410的单个按键驱动程序(Linux),测试通过
- OK6410的按键驱动
- OK6410按键驱动程序(改)亲测可以运行
- OK6410按键驱动程序(改)亲测可以运行
- OK6410按键驱动程序(Linux),测试通过后分享给大家
- OK6410按键驱动程序(Linux),测试通过后分享给大家
- 按键驱动程序设计---混杂设备、中断分层处理、工作队列、阻塞型驱动
- 基于platform总线的ok6410 LED 驱动
- platform下的按键驱动
- Linux下的led驱动程序,ok6410
- 异步通知的按键驱动程序
- TQ2440简单的按键驱动程序
- imx6 项目的按键驱动程序
- 网络端口大全
- eclipse遇到An error has occurred. See the log file
- 子线程阻塞的一个解决方案
- java中long,int,short与byte数组之间的转换
- LVS Tutorial
- ok6410增加工作队列的platform按键驱动程序
- 用CoreText 实现显示可点击 的URL
- vlc的应用之一:在命令行下的使用
- The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar
- windows bat .
- Java基本类型 和所占位数
- web.xml中load-on-startup标签的含义
- UIScrollView使用汇总
- javaweb项目中对于资源文件的读取