linux外部割り込み例

6330 ワード

code:
#include <linux/kernel.h>  
#include <linux/module.h>  
#include <linux/cdev.h>  
#include <linux/fs.h>  
#include <linux/device.h>  
#include <linux/syscalls.h>
#include <linux/interrupt.h> 
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/uaccess.h>  
#include <linux/string.h> 

#include <mach/gpio.h>
#include <mach/irqs.h>

#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))


struct fpga_key_dev  
{  
    struct cdev cdev;  
    dev_t devno;  
    char test[20];
    struct class *fpga_key_class; 
	struct fasync_struct *async_queue;

	int message_cdev_open;
};  

irqreturn_t irq_handler(int irqno, void *dev_id)

{
	printk("fpga key down
"); return IRQ_HANDLED; } static int fpga_key_open(struct inode *node, struct file *fd) { struct fpga_key_dev *dev; printk("fpga_key_open()++
"); printk("node->i_cdev = %x
", (unsigned int)node->i_cdev); dev = container_of(node->i_cdev, struct fpga_key_dev, cdev); printk("dev->cdev = %x
", (unsigned int)&dev->cdev); printk("dev = %x
", (unsigned int)dev); if (!dev->message_cdev_open) { dev->message_cdev_open = 1; fd->private_data = dev; } else{ return -EFAULT; } printk("test[20] = %s
",dev->test); printk("fpga_key_open()--
"); return 0; } static ssize_t fpga_key_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) { char temp_buffer [20]; int print_size = 0; struct fpga_key_dev *dev = fd->private_data; printk("fpga_key_wirte()++
"); if(len > 20) print_size = 20; else print_size = len; printk("print_size = %d; len = %d
", print_size, len); if(copy_from_user(temp_buffer, buf, print_size)) return -EFAULT; if (dev->async_queue) kill_fasync(&dev->async_queue, SIGIO, POLL_IN); printk("writing data:%s", temp_buffer); printk("fpga_key_wirte()--
"); return print_size; } static ssize_t fpga_key_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) { char *temp_buffer = "Hello fpga_key_read !
"; int print_size = 0; printk("fpga_key_read()++
"); if(len > strnlen(temp_buffer,20)) print_size = strnlen(temp_buffer,20); else print_size = len; printk("print_size = %d; len = %d
", print_size, len); if(copy_to_user(buf, temp_buffer, print_size)) return -EFAULT; printk("%s", temp_buffer); printk("fpga_key_read()--
"); return print_size; } static int fpga_key_fasync(int fd, struct file *filp, int mode) { struct fpga_key_dev *dev = filp->private_data; printk("fpga_key_fasync()++
"); fasync_helper(fd, filp, mode, &dev->async_queue); printk("fpga_key_fasync()--
"); return 0; } static int fpga_key_release(struct inode *node, struct file *fd) { struct fpga_key_dev *dev = fd->private_data; printk("fpga_key_release()++
"); dev->message_cdev_open = 0; fpga_key_fasync(-1, fd, 0); printk("fpga_key_release()--
"); return 0; } struct file_operations meassage_operatons = { .owner = THIS_MODULE, .open = fpga_key_open, .write = fpga_key_write, .read = fpga_key_read, .fasync = fpga_key_fasync, .release = fpga_key_release, }; struct fpga_key_dev fpga_key_dev; static int __init fpga_key_init(void) { struct fpga_key_dev * dev; char * temp_char = "hello world
"; int ret = 0; int inter = 0; printk("fpga_key_to_app_init(void)++
"); dev = &fpga_key_dev; strcpy(dev->test, temp_char);; alloc_chrdev_region(&dev->devno, 0, 1, "fpga_key_to_app"); cdev_init(&dev->cdev, &meassage_operatons); cdev_add(&dev->cdev, dev->devno, 1); dev->fpga_key_class = class_create(THIS_MODULE, "fpga_key_class"); if(IS_ERR(dev->fpga_key_class)) { printk("Err: failed in creating class./n"); goto fail1; } device_create(dev->fpga_key_class, NULL, dev->devno, NULL, "fpga_key"); //init irq ret = gpio_request(GPIO_TO_PIN(1, 27), "fpga_key_inter"); if(ret){ printk("gpio_request() failed !
"); goto fail1; } ret = gpio_direction_input(GPIO_TO_PIN(1, 27)); if(ret){ printk("gpio_direction_input() failed !
"); goto fail2; } inter = gpio_to_irq(GPIO_TO_PIN(1, 27)); if(inter < 0){ printk("gpio_to_irq() failed !
"); ret = inter; goto fail2; } printk("inter = %d", inter); ret = request_irq(inter, irq_handler, IRQF_TRIGGER_FALLING | IRQF_SHARED, "fpga_key_inter", &dev->devno); if(ret){ printk("request_irq() failed ! %d
", ret); goto fail2; } printk("fpga_key_to_app_init(void)--
"); return 0; fail2: gpio_free(GPIO_TO_PIN(1, 27)); fail1: device_destroy(dev->fpga_key_class, dev->devno); class_destroy(dev->fpga_key_class); cdev_del(&dev->cdev); unregister_chrdev_region(dev->devno, 1); return ret; } static void __exit fpga_key_exit(void) { struct fpga_key_dev *dev = &fpga_key_dev; printk("fpga_key_to_app_exit(void)++
"); free_irq(AM33XX_IRQ_GPIO1_1, NULL); gpio_free(GPIO_TO_PIN(1, 27)); device_destroy(dev->fpga_key_class, dev->devno); class_destroy(dev->fpga_key_class); cdev_del(&dev->cdev); unregister_chrdev_region(dev->devno, 1); printk("fpga_key_to_app_exit(void)--
"); } module_init(fpga_key_init); module_exit(fpga_key_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Driver Monkey"); MODULE_DESCRIPTION("Test fpga_key to App");