系统相关
首页 > 系统相关> > LInux_GPIO_DRV

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