从零开始之驱动发开、linux驱动(八、字符驱动之查询式按键处理)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_16777851/article/details/82470429

这一小节很简单,在读函数中返回两个gpio的状态就可以

#include <linux/fs.h>       /* 包含file_operation结构体 */
#include <linux/init.h>     /* 包含module_init module_exit */
#include <linux/module.h>   /* 包含LICENSE的宏 */
#include <asm/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <asm/gpio.h>
#include <linux/gfp.h>


#define GPH0_BASE   0xe0200c00

static unsigned int major;
static struct class *button_class;
static struct device *button_dev;

struct gpio_reg {
    unsigned int con;
    unsigned int dat;
};

static struct gpio_reg *gph0 = NULL;


/* open函数 */
static int button_drv_open(struct inode *inode, struct file *file)
{
    /* 输入口是gph0 2.3, 配置成输入模式 */
    gph0->con &= ~((0xf << 2*4)|(0xf << 3*4));  

    return 0;
}


ssize_t button_drv_read(struct file *file, char __user *array, size_t size, loff_t *ppos)
{
    char buf[2];
    int len;

    if(size < 2)
    {
        return -EINVAL;
    }

    /* 读gpio的状态 */
    buf[0] = (gph0->dat & (1 << 2)) ? 1 : 0;
    buf[1] = (gph0->dat & (1 << 3)) ? 1 : 0;

    /* 赋值只是为了消除告警 */
    len = copy_to_user(array ,buf, 2);

    return 2;
}

static const struct file_operations button_drv_file_operation = {
    .owner = THIS_MODULE,
    .open  = button_drv_open,
    .read = button_drv_read,
};

static int __init button_drv_init(void)
{
    /* 获取一个自动的主设备号 */
    major =  register_chrdev(0,"button_drv",&button_drv_file_operation);
    if(major < 0)
    {
        printk("register_chrdev button_drv fail \n");
        goto err_register_chrdev;
    }

    /* 创建一个类 */
    button_class = class_create(THIS_MODULE, "button_class");
    if(!button_class)
    {
        goto err_class_create;
    }

    /* 创建从属这个类的设备 */
    button_dev = device_create(button_class,NULL,MKDEV(major, 0), NULL, "button");
    if(!button_dev)
    {
        goto err_device_create;
    }

    gph0 = ioremap(GPH0_BASE, 8);
    if(!gph0)
    {
        goto err_ioremap;
    }


    return 0;


/* 倒影式错误处理机制 */
err_ioremap:
    device_unregister(button_dev);
err_device_create:
    class_destroy(button_class);
err_class_create:
    unregister_chrdev(major,"button_drv");
err_register_chrdev:

    return -EIO;
}



static void __exit button_drv_exit(void)
{
    /* 取消映射 */
    iounmap(gph0);
    /* 注销类里面的设备 */
    device_unregister(button_dev);
    /* 注销类 */
    class_destroy(button_class);
    /* 注销字符设备 */
    unregister_chrdev(major,"button_drv");
}

module_init(button_drv_init);
module_exit(button_drv_exit);
MODULE_LICENSE("GPL");               

应用程序重直接读按键值。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>



int main(int argc,char *argv[])
{
    char buf[2];
    int fd = open("/dev/button", O_RDWR);

    if(fd < 0)
    {   
        printf("open /dev/%s fail\n",argv[1]);
        return -1; 
    }   

    while(1)
    {   
        read(fd, buf, 2); 
        if((buf[0] == 0)||(0 == buf[1]))
        {   
            printf("buf = %d, %d \n", buf[0],buf[1]);
        }   
    }   

    return 0;
}

按键效果

因为是在应用程序中直接循环读取,一次按键会返回产生大量的重复。

查看cpu使用率

发现直接这样使用按键,极大程度的消耗cpu资源。

猜你喜欢

转载自blog.csdn.net/qq_16777851/article/details/82470429
今日推荐