• Linux嵌入式学习-烟雾传感器驱动-字符设备驱动-按键驱动


    MQ-2烟雾气敏传感器模块在X210v3开发板上的驱动。

    现在需要一个MQ-2烟雾气敏传感器模块的驱动。其检测烟雾超过一定的标准后,会返回一个不同的电平,和按键驱动差不多。

    但是在编写驱动的时候,需要用GPH2_3号引脚。但是在内核中先ioremap地址然后配置,发现无法控制gpio,也无法进入中断。

    后来发现,如果需要使用gpio,需要先申请,然后才能使用。

    具体程序如下:

    #include <linux/module.h>
    
    #include <linux/init.h>
    
    #include <linux/miscdevice.h>
    
    #include <linux/interrupt.h>
    
    #include <linux/io.h>
    
    #include <linux/fs.h>
    
    #include <linux/slab.h>
    
    #include <asm/irq.h>
    
    #include <linux/random.h>
    
    #include <linux/uaccess.h>
    
    #include <linux/device.h>
    
    #include <mach/gpio.h>
    
    
    
    #define GPH2CON 0xE0200c60
    
    #define GPH2DAT 0xE0200c64
    
    
    static struct class *fog_class;     //创建类
    
    static struct class_device *fog_class_devs;   //创建类对应的设备
    
    
    struct work_struct *work1;
    
    
    struct timer_list fogs_timer;
    
    
    unsigned int *gpio_data;
    
    
    unsigned int fog_num = 0;
    
    
    wait_queue_head_t  fog_q;
    
    
    void work1_func(struct work_struct *work)
    {
    
        mod_timer(&fogs_timer, jiffies + (HZ /10));
    
    }
    
    
    void fogs_timer_function(unsigned long data)
    {
    
        unsigned int fog_val;
    
    
        fog_val = readw(gpio_data)&0x08;
        if (fog_val == 0)
        {
    
           fog_num = 1;
    
           printk("press down
    ");
    
        }
    
        wake_up(&fog_q);
    
    }
    
    
    
    irqreturn_t fog_int(int irq, void *dev_id)
    {
    
        schedule_work(work1);
    
    
    
        //return 0;
    
        return IRQ_HANDLED;
    
    }
    
    
    void fog_hw_init()
    {
    
        unsigned int *gpio_config;
    
        unsigned short data;
    
    
    
        gpio_request(S5PV210_GPH2(3),"my_fog");
    
        gpio_config = ioremap(GPH2CON,4);
    
        data = readw(gpio_config);
    
        data &= ~(0b1111<<12);
    
        data |= 0b1111<<12;
        writew(data,gpio_config);
    
        gpio_data = ioremap(GPH2DAT,1);
    
    
    
    }
    
    
    int fog_open(struct inode *node,struct file *filp)
    {
        return 0;
    }
    
    
    ssize_t fog_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)
    
    {
    
        wait_event(fog_q,fog_num);
    
       // printk("in kernel :fog num is %d
    ",fog_num);
    
        copy_to_user(buf, &fog_num, 4);
    
        fog_num = 0;
    
        return 4;
    
    }
    
    
    
    struct file_operations fog_fops =
    
    {
    
        .open = fog_open,
    
        .read = fog_read,
    
    };
    
    
    
    struct miscdevice fog_miscdev = {
    
        .minor = 200,
    
        .name = "fog",
    
        .fops = &fog_fops,
    
    };
    
    
    
    int major;
    
    static int fog_init()
    
    {
    
        int ret;
    
        major = register_chrdev( 0,"fog_drv", &fog_fops );
    
        fog_class = class_create(THIS_MODULE,"fog_class");
    
        fog_class_devs = device_create(fog_class,NULL,MKDEV(major,0),NULL,"my_fog");
    
        if (ret !=0)
    
            printk("register fail!
    ");
    
        //×¢²áÖжώŠÀí³ÌÐò
    
        request_irq(IRQ_EINT(27),fog_int,IRQF_TRIGGER_FALLING,"fog",0);
    
    
        //°ŽŒü³õÊŒ»¯
    
        fog_hw_init();
    
        //. ŽŽœš¹€×÷
    
        work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);
    
        INIT_WORK(work1, work1_func);
    
        /* ³õÊŒ»¯¶šÊ±Æ÷ */
    
        init_timer(&fogs_timer);
    
        fogs_timer.function  = fogs_timer_function;
    
    
        /* ÏòÄÚºË×¢²áÒ»žö¶šÊ±Æ÷ */
    
        add_timer(&fogs_timer);
    
    
        /*³õÊŒ»¯µÈŽý¶ÓÁÐ*/
    
        init_waitqueue_head(&fog_q);
        return 0;
    
    }
    
    
    static void fog_exit()
    
    {
    
        del_timer(&fogs_timer);
    
        unregister_chrdev( major, "fog_drv" );
    
        device_unregister(fog_class_devs);
    
        class_destroy(fog_class);
    
    
    }
    
    
    module_init(fog_init);
    
    module_exit(fog_exit);
    
    MODULE_LICENSE("GPL");
  • 相关阅读:
    浏览器HTML5支持程度测试
    Unit testing Cmockery 简单使用
    Linux likely unlikely
    Android development tools line_endings hacking
    Linux C enum
    Android 系统内置App JNI
    Android Broadcast Receiver
    Android获取SharedPreferences失败,且App无法启动
    Sublime-text markdown with Vim mode and auto preview
    遍历Map key-value的两种方法
  • 原文地址:https://www.cnblogs.com/ynxf/p/6519376.html
Copyright © 2020-2023  润新知