LInux_GPIO_DRV
作者:互联网
LInux_GPIO_DRV
/* * gpio_irq_test.c- Sigmastar * * Copyright (c) [2019~2020] SigmaStar Technology. * * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License version 2 for more details. * */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/rtc.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/types.h> #include <linux/sched.h> #include "cam_os_wrapper.h" #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/delay.h> int gpio_major; //主设备号 static struct class *gpio_class; static DECLARE_WAIT_QUEUE_HEAD(gpio_waitq); static volatile int ev_press = 0; //条件变量 int gpio_pin = 12; module_param(gpio_pin, int, 0); int level = 0; // 0:IRQF_TRIGGER_FALLING 1:IRQF_TRIGGER_RISING module_param(level, int, 0); s32 gpio_set_success = 0; u32 gpio_irq_num = 0; static unsigned char app_val; //返回给用户的键值 irqreturn_t gpio_irq_isr(int irq, void *dev_instance) { printk("gpio_irq_isr success!\r\n"); ev_press = 1; /* 表示中断发生了 */ wake_up_interruptible(&gpio_waitq); /* 唤醒休眠的进程 */ return IRQ_NONE; } static int gpio_open(struct inode *inode, struct file *file) { return 0; } ssize_t gpio_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) { if (size != 1) return -EINVAL; //判读open时,有没有设置flags为NONBLOCK if(file->f_flags & O_NONBLOCK && ev_press==0){ return -EAGAIN; } wait_event_interruptible(gpio_waitq, ev_press); //软件滤波 mdelay(40); if(gpio_get_value(gpio_pin)==0){ app_val =0x06; copy_to_user(buf, &app_val, 1); } app_val =0; ev_press = 0; return 1; } int gpio_drv_close(struct inode *inode, struct file *file) { return 0; } static struct file_operations tf_fops= { .owner = THIS_MODULE, .open = gpio_open, .read = gpio_read, .release = gpio_drv_close, }; static int __init Gpio_Irq_Init(void) { printk("Gpio_Irq_Init success!\n"); gpio_set_success = 0; gpio_major = register_chrdev(0, "tfirq", &tf_fops); //注册一个字符设备 gpio_class = class_create(THIS_MODULE, "tfirq"); //创建一个类 device_create(gpio_class, NULL, MKDEV(gpio_major,0), NULL, "tfirq"); //在类下面创建一个设备 if(gpio_request(gpio_pin, "gpio_irq_test") < 0){ printk("request gpio[%d] failed...\n", gpio_pin); return 0; } if (gpio_direction_input(gpio_pin) < 0) { printk("gpio_direction_input[%d] failed...\n", gpio_pin); return 0; } gpio_irq_num = gpio_to_irq(gpio_pin); if (request_irq(gpio_irq_num, gpio_irq_isr, (level==0)? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING, "PAD", NULL)){ printk(KERN_ERR"can't allocate irq\n"); return 0; } gpio_set_success = 1; return 0; } static void __exit Gpio_Irq_Exit(void) { if (gpio_set_success){ free_irq(gpio_irq_num, NULL); gpio_free(gpio_pin); } } module_init(Gpio_Irq_Init); module_exit(Gpio_Irq_Exit); MODULE_AUTHOR("WANGXY"); MODULE_DESCRIPTION("WANGXY GPIO IRQ"); MODULE_LICENSE("GPL");
笔记
1.
int gpio_request(unsigned gpio,constchar* label)
void gpio_free(unsigned gpio)
int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio,int value)
int gpio_get_value(unsigned gpio)
void gpio_set_value(unsigned gpio,int value)
标签:return,pin,int,irq,LInux,DRV,GPIO,gpio,include 来源: https://www.cnblogs.com/panda-w/p/16347942.html