Linux input 子系统应用之按键驱动

硬件平台:s5pv210

软件平台:Linux2.6.35.7

应用程序:inputk2_app.c

#include <stdio.h>

#include <fcntl.h>

#include <linux/input.h>

#include <sys/types.h>

#include <unistd.h>

int main(int argc, char** argv)

{

int fd;

int count;

int i = 0;

int j = 0;

struct input_event key2;

//在根文件系统用cat /proc/bus/input/devices查看是event几

fd = open("/dev/event1", O_RDWR);

if (fd < 0)

{

perror("open");

return -1;

}

while (1)

{

lseek(fd, 0, SEEK_SET);

count = read(fd, &key2, sizeof(struct input_event));

if(count != sizeof(struct input_event))

{

perror("read");

}

if(EV_KEY == key2.type)

{

printf("\r\ni = %d, type:%d, code:%d, value:%d\r\n", i, key2.type, key2.code, key2.value);

if (key2.value)

{

i++;

printf("***********the k2 down %d times***********\r\n", i);

}

else

{

printf("****************the k2 up*****************\r\n");

}

}

if(EV_SYN == key2.type)

{

printf("syn event\r\n");

if (++j == 2)

{

j = 0;

printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\n");

}

}

}

close(fd);

return 0;

}

驱动程序:inputk2_drv.c

#include <linux/module.h>

#include <linux/init.h>

#include <linux/input.h>

#include <linux/interrupt.h>

#include <asm/gpio.h>

#include <linux/timer.h>

static struct input_dev *button_dev;//定义输入设备

struct timer_list my_timer;//定义定时器结构体timer_list

//定义定时器超时处理函数

void timer_func(unsigned long data)

{

int key_value = gpio_get_value(S5PV210_GPH2(0));

//上报事件给input核心层

input_report_key(button_dev, KEY_A, !key_value);//按下为1

//告诉input子系统上报已经完成

input_sync(button_dev);

//printk("[%d][%s], data=[%lu]\r\n", __LINE__, __FUNCTION__, data);

}

static irqreturn_t button_interrupt(int irq, void *dev_id)

{

//the value of timeout is decided by the n of "jiffies + n"

//timeout = n*(1000/HZ) ms(HZ=256 in this project)

//the empirical value of timeout ≈ 10~100ms

mod_timer(&my_timer, jiffies + 5);//timeout≈5*4=20ms

return IRQ_HANDLED;

}

static int __init button_init(void)

{

int ret;

ret = gpio_request(S5PV210_GPH2(0), "key2");

if (ret)

{

printk(KERN_ERR "gpio_request Failed to register device\r\n");

goto error1;

}

//为新输入设备分配内存并初始化

button_dev = input_allocate_device();

if (!button_dev)

{

printk(KERN_ERR "can‘t allocate input mem!\r\n");

goto error2;

}

button_dev->name = "gec_input";

button_dev->id.bustype = 0x1;

button_dev->id.product = 0x2;

button_dev->id.vendor  = 0x3;

button_dev->id.version = 0x4;

button_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);//set_bit(EV_KEY,button_dev->evbit[BIT_WORD(EV_KEY)])

button_dev->keybit[BIT_WORD(KEY_A)] = BIT_MASK(KEY_A);//set_bit(KEY_A, button_dev->keybit[BIT_WORD(KEY_A)])

//注册一个输入设备

ret = input_register_device(button_dev);

if (ret)

{

printk(KERN_ERR "Failed to register device\r\n");

goto error3;

}

//申请中断注册中断处理函数

ret = request_irq(IRQ_EINT(16), button_interrupt,\

IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING | IRQF_DISABLED, "button", NULL);

if (ret)

{

printk(KERN_ERR "Can‘t request irq %d\r\n", IRQ_EINT(16));

goto error4;

}

//定时器

init_timer(&my_timer);//初始化定时器

my_timer.function = timer_func;//注册定时器超时处理函数

return 0;

error4:

free_irq(IRQ_EINT(16), NULL);//释放分配给已定中断的内存

input_unregister_device(button_dev);

error3:

input_free_device(button_dev);

error2:

ret = -ENOMEM;

error1:

gpio_free(S5PV210_GPH2(0));

return ret;

}

static void __exit button_exit(void)

{

gpio_free(S5PV210_GPH2(0));

free_irq(IRQ_EINT(16), NULL);

input_unregister_device(button_dev);

del_timer(&my_timer);//删除内核定时器

}

module_init(button_init);

module_exit(button_exit);

MODULE_LICENSE("Dual BSD/GPL");

MODULE_LICENSE("GPL");

Makefile:

obj-m += inputk2_drv.o

PWD ?= shell pwd

KDIR := /opt/03.kernel_transplant/android-kernel-samsung-dev

all:

make -C $(KDIR) M=$(PWD) modules

cp ./inputk2_drv.ko /mini_rootfs/modules

cp ./inputk2_app    /mini_rootfs/modules

rm -rf ./*.o

rm -rf ./*.order

rm -rf ./*.symvers

rm -rf ./*.mod.c

rm -rf ./.*.cmd

rm -rf ./.*.tmp*

rm -rf ./.tmp_versions

时间: 2024-10-16 17:12:37

Linux input 子系统应用之按键驱动的相关文章

全网络对Linux input子系统最清晰、详尽的分析

Linux input分析之二:解构input_handler.input_core.input_device 输入输出是用户和产品交互的手段,因此输入驱动开发在Linux驱动开发中很常见.同时,input子系统的分层架构思想在Linux驱动设计中极具代表性和先进性,因此对Linux input子系统进行深入分析很有意义. 本文继续在<Linuxinput子系统分析之一:软件分层>的基础上继续深入研究Linux输入子系统的分层架构思想以及其实现.软件分层探讨的是输入消息从底层硬件到内核.应用层

Android驱动之 Linux Input子系统之TP——A/B(Slot)协议

utm_source=tuicool&utm_medium=referral">点击打开链接 将A/B协议这部分单独拿出来说一方面是由于这部分内容是比較easy忽视的.周围大多数用到input子系统的开发者也不甚理解.还有一方面是由于这部分知识一旦扩展到TP(触摸屏Touch Panel)的多点触摸就要与Middleware/Framework一起结合起来看才干全然掌握,复杂性所在. 这里的Middleware/Framework是针对android来说的,本人从事android这

Android驱动之 Linux Input子系统之TP——A/B(Slot)协议【转】

转自:http://www.thinksaas.cn/topics/0/646/646797.html 将A/B协议这部分单独拿出来说一方面是因为这部分内容是比较容易忽视的,周围大多数用到input子系统的开发人员也不甚理解:另一方面是由于这部分知识一旦扩展到TP(触摸屏Touch Panel)的多点触摸就要与Middleware/Framework一起结合起来看才能完全掌握,复杂性所在.这里的Middleware/Framework是针对android来说的,本人从事android这几个层次的

platform 总线input子系统上的按键中断

什么时候唤醒? 报告事件input_event(dev,x)  input_event(dev,y) input_event(dev,SYN) -------------------- Linux内核中的总线设备驱动 总线   include/device.h Struct bus_type { Name; Match;//(匹配规则,匹配设备和设备驱动) }: 注册:bus_register(....) 注销:bus_unregister(...): 设备 Struct device{ Str

Linux input子系统编程、分析与模板

输入设备都有共性:中断驱动+字符IO,基于分层的思想,Linux内核将这些设备的公有的部分提取出来,基于cdev提供接口,设计了输入子系统,所有使用输入子系统构建的设备都使用主设备号13,同时输入子系统也支持自动创建设备文件,这些文件采用阻塞的IO读写方式,被创建在"/dev/input/"下.如下图所示.内核中的输入子系统自底向上分为设备驱动层,输入核心层,事件处理层.由于每种输入的设备上报的事件都各有不同,所以为了应用层能够很好识别上报的事件,内核中也为应用层封装了标准的接口来描述

linux系统下标准GPIO按键驱动

前言: linux下platform平台驱动是为了方便隔离bsp与driver,利于移植.体现好代码的高内聚,低耦合.Linux设备驱动模型中,关心总线,设备和驱动三个实体.总线将设备和驱动绑定.在系统每注册一个设备的时候,都会寻找与之相匹配的驱动,相反的,每加载一个驱动的时候,也会寻找与之匹配的设备.匹配由总线完成.linux发明了一种虚拟的总线,称之为platform总线,相应的设备称之为platform_device,驱动为platform_driver. 基于这个模型,又根据面向对象的思

linux input子系统 — TP A/B(Slot)协议【转】

本文转载自:http://blog.csdn.net/u012719256/article/details/53609906 将A/B协议这部分单独拿出来说一方面是因为这部分内容是比较容易忽视的,周围大多数用到input子系统的开发人员也不甚理解:另一方面是由于这部分知识一旦扩展到TP(触摸屏Touch Panel)的多点触摸就要与Middleware/Framework一起结合起来看才能完全掌握,复杂性所在.这里的Middleware/Framework是针对android来说的,本人从事an

Linux Input子系统

先贴代码: //input.c int input_register_handler(struct input_handler *handler) { //此处省略很多代码 list_for_each_entry(dev, &input_dev_list, node) input_attach_handler(dev, handler); //此处省略很多代码 return 0; } EXPORT_SYMBOL(input_register_handler); int input_registe

Linux input子系统学习总结(二)----Input事件驱动

Input 事件驱动:  (主要文件 :drivers/input/evdev.c  .  drivers/input/input.h)基于kernel 4.0  一. 关键函数调用顺序: 1.input_register_handler(&evdev_handler); ///注册 evdev_handler 这个input事件驱evdev.c      2.input_attach_handler(dev, handler);////input 设备和 input 事件进行匹配   inpu