linux poll 机制获取按键值

(1)通过insmod 加载驱动程序,然后运行测序程序。

    测试程序会通过poll 机制休眠,当有按键值可读取时会立刻读取按键值

1、驱动

/*************************************************************************
    > File Name: poll_eint.c
    > Author: Bond
    > Mail: 1325081677@qq.com 
    > Created Time: 2021年04月01日 星期四 21时30分06秒
 ************************************************************************/

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/poll.h>

#define DBUG true
#define DEBUG(x...) if(DBUG){printk(x);}

#define DEV_MAJOR      230
#define DEVICE_NUM     1
//GPIO7_B5
#define GPIO_KEY1      229
static int dev_major = DEV_MAJOR;
module_param(dev_major,int,S_IRUGO);

struct device *dev_devcie;
struct class *dev_class;
struct cdev c_dev;

static volatile int ev_press = 0;
static unsigned char key_value = 0;
static DECLARE_WAIT_QUEUE_HEAD(btn_waitq);

static irqreturn_t buttons_irq(int irq,void *dev_id){
    int *id = dev_id;
    int value;
    value = gpio_get_value(GPIO_KEY1);
    DEBUG("Bond inter enter %d,value %d\n",*id,value);
    if(value){
        value |=0x80;
    }else{
            
    }
    key_value = value;
    ev_press = 1;

    wake_up_interruptible(&btn_waitq);
    return IRQ_RETVAL(IRQ_HANDLED);
}

static int chr_dev_open(struct inode *inode, struct file *filp){
    int ret = 0;
    int irq ;

    ret = gpio_request(GPIO_KEY1,"KEY1");
    if(ret<0){
        DEBUG("Bond can not request GPIO KEY %d\n",GPIO_KEY1);
        return -EINVAL;
    }
    irq = gpio_to_irq(GPIO_KEY1);
    if(irq < 0 ){
        gpio_free(GPIO_KEY1);
        DEBUG("Bond can not get irq num %d\n",GPIO_KEY1);
        return -EINVAL;
    }
    ret = request_irq(irq,buttons_irq,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"keys",&dev_major);
    return 0;
}
static int chr_dev_release(struct inode *inode,struct file* filp){
    gpio_free(GPIO_KEY1);
    return 0;
}

static long chr_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){
    return 0;
}

static unsigned int chr_dev_poll (struct file *flip, struct poll_table_struct *wait){
    unsigned int mask = 0;
    
    poll_wait(flip,&btn_waitq,wait);
    if(ev_press){
        mask |= POLLIN | POLLRDNORM; 
    }
    return mask;
}
static ssize_t chr_dev_read(struct file *filp, char __user *buffer, size_t size, loff_t *f_pos){
    int ret=0;    
    if(size != 1){
        return -EINVAL;    
    }
    wait_event_interruptible(btn_waitq,ev_press);
    ret = copy_to_user(buffer,&key_value,1);
    ev_press = 0;
    return ret;
}

static ssize_t chr_dev_write(struct file *filp, 
                                    const char __user *buffer,  
                                    size_t size, 
                                loff_t *f_pos) 

    return size;
}
static loff_t chr_dev_llseek(struct file *filp, loff_t offset, int orignal){

    loff_t ret = 0;
    

    return ret;
}
static const struct file_operations chr_dev_fops = {
    .owner        = THIS_MODULE,
    .open        = chr_dev_open,
    .read        = chr_dev_read,
    .write      = chr_dev_write,
    .llseek        = chr_dev_llseek,
    .release    = chr_dev_release,
    .unlocked_ioctl = chr_dev_ioctl,
    .poll       = chr_dev_poll,
};
static __init int chr_dev_init(void){
    int ret;
    dev_t devno = MKDEV(dev_major,0);
    if(dev_major){
        ret = register_chrdev_region(devno,DEVICE_NUM,"chrdev");
    }else{
        alloc_chrdev_region(&devno,0,DEVICE_NUM,"chrdev");
        dev_major= MAJOR(devno);
    }
    cdev_init(&c_dev,&chr_dev_fops);
    c_dev.owner = THIS_MODULE;
    cdev_add(&c_dev,devno,1);
    dev_class  = class_create(THIS_MODULE,"poll_eint");
    dev_devcie = device_create(dev_class,NULL,devno,NULL,"poll_eint");
    return 0;
}

static __exit void chr_dev_exit(void){

    unregister_chrdev_region(MKDEV(dev_major,0),DEVICE_NUM);
    device_destroy(dev_class,MKDEV(dev_major,0));
    class_destroy(dev_class);

}

module_init(chr_dev_init);
module_exit(chr_dev_exit);


MODULE_AUTHOR("Bond <xxxx@163.com>");  
MODULE_DESCRIPTION("char dev driver");  
MODULE_LICENSE("GPL"); 

 

2、测试程序 

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)


LOCAL_MODULE:=poll_einit
LOCAL_SRC_FILES := poll_einit.c 
LOCAL_SHARED_LIBRARIES :=liblog \
                        libcutils
LOCAL_MODULE_PATH += $(LOCAL_PATH)

include $(BUILD_EXECUTABLE)
 

poll_einit.c

/*************************************************************************
    > File Name: external/test_drv/poll_einit.c
    > Author: Bond
    > Mail: 1325081677@qq.com 
    > Created Time: 2021年04月05日 星期一 21时13分48秒
 ************************************************************************/

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

#include <utils/Log.h>
#include <cutils/android_reboot.h>
#include <cutils/klog.h>
#include <cutils/list.h>
#include <cutils/properties.h>
#include <sys/time.h>
#include <time.h>


#define TAG "Bond"


#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
static int fd;

int read_poll_eint(){
    int key_val;
    int ret;
    struct pollfd fds[1];
    fd = open("/dev/poll_eint",O_RDWR);
    if(fd < 0){
        LOGI("Bond open /dev/poll_eint fail\n");
        return -1;
    }
    fds[0].fd = fd;
    fds[0].events = POLLIN;
    while(1){
        ret = poll(fds,1,5000);
        if(ret == 0){
            LOGI("Bond time out");
        }else{
            ret = read(fd,&key_val,1);
            LOGI("Bond App read key value %d ret %d\n",key_val,ret);
            if(ret<0){
                break;
            }    
        }
    
    }

    
    close(fd);
    return 0;
}
int main(int argc,const char** argv){
    
    read_poll_eint();
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值