input子系统
input子系统:
像按键、键盘、鼠标、触摸屏、游戏摇杆等设备只有输入没有输出,而且在编程实现其对应的驱动程序时会有很多重复性的代码,内核的设计者将该部分代码抽象出来,驱动工程师只需要复用该部分代码,并且实现硬件相关的代码(中断号,中断触发条件),就可以可以很容易实现对应硬件的驱动程序 如何用复用input子系统中提供的通用函数功能模块, 要遵循以下步骤:
核心数据结构
struct input_dev
{
evbit//记录该设备将来会报告哪些事件
}
1)分配一个输入设备//定义一个input_dev类型变量
input_allocate_device()
2)设置input_dev
3)注册input_dev
input_register_device
4)硬件操作
注册中断服务程序
延时去抖
//保存按键值
5)向input核心模块报告事件
input_event(...)
6)注销input_dev
input_unregister_device
7)释放输入设备
input_free_device(...)
代码实例:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/gpio.h>
#include <plat/gpio-cfg.h>
//定义按键硬件私有数据结构
struct btn_resource {
char *name; //名称
int irq; //中断号
int gpio; //GPIO编号
int code; //键值
}; //初始化开发板按键信息
static struct btn_resource btn_info[] = {
[] = {
.name = "KEY_L",
.irq = IRQ_EINT(),
.gpio = S5PV210_GPH0(),
.code = KEY_L
},
[] = {
.name = "KEY_S",
.irq = IRQ_EINT(),
.gpio = S5PV210_GPH0(),
.code = KEY_S
},
[] = {
.name = "KEY_ENTER",
.irq = IRQ_EINT(),
.gpio = S5PV210_GPH0(),
.code = KEY_ENTER
},
}; //定义input_dev指针
static struct input_dev *btn_dev; //分配定时器
static struct timer_list btn_timer;
static struct btn_resource *pdata; //定时器的处理函数
static void btn_timer_func(unsigned long data)
{
unsigned int pinstate; //2.获取按键的状态
pinstate = gpio_get_value(pdata->gpio); //3.上报按键信息给核心层然后唤醒休眠的进程
if (pinstate == ) { //松开
//EV_KEY:上报按键类事件
//pdata->code:具体键值
//0:松开
input_event(btn_dev, EV_KEY, pdata->code, );
input_sync(btn_dev); //上报同步类事件
} else { //按下
//EV_KEY:上报按键类事件
//pdata->code:具体键值
//1:按下
input_event(btn_dev, EV_KEY, pdata->code, );
input_sync(btn_dev);//上报同步类事件
}
} //中断处理函数
static irqreturn_t button_isr(int irq, void *dev_id)
{
//1.获取按键对应的数据项
pdata = (struct btn_resource *)dev_id; //2.启动定时器,设置定时器的超时时间为10ms
mod_timer(&btn_timer, jiffies + msecs_to_jiffies());
return IRQ_HANDLED;
} static int btn_init(void)
{
int i; //1.分配input_dev
btn_dev = input_allocate_device(); //2.初始化input_dev
btn_dev->name = "wf_button";
//2.1设置上报按键类事件
set_bit(EV_KEY, btn_dev->evbit);
//2.2设置上报重复类事件
set_bit(EV_REP, btn_dev->evbit);
//2.3设置上报按键类事件中的哪些键值
for(i = ; i < ARRAY_SIZE(btn_info); i++)
set_bit(btn_info[i].code, btn_dev->keybit); //3.注册input_dev
input_register_device(btn_dev); //4.申请GPIO资源
//5.注册中断处理函数
for (i = ; i < ARRAY_SIZE(btn_info); i++) {
gpio_request(btn_info[i].gpio, btn_info[i].name);
request_irq(btn_info[i].irq, button_isr/*中断处理函数*/,
IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,/*下降沿和上升沿触发*/
btn_info[i].name, &btn_info[i]/*给中断处理函数传递的参数*/);
} //6.初始化定时器 处理按键的毛刺
init_timer(&btn_timer); //6.1指定定时器的处理函数
btn_timer.function = btn_timer_func;
add_timer(&btn_timer);//将定时器添加到内核中
return ;
} static void btn_exit(void)
{
int i; //1.释放中断,释放GPIO资源
for (i = ; i < ARRAY_SIZE(btn_info); i++) {
gpio_free(btn_info[i].gpio);
free_irq(btn_info[i].irq, &btn_info[i]);
} //2.卸载input_dev
input_unregister_device(btn_dev); //3.释放input_dev内存
input_free_device(btn_dev); //4.删除定时器
del_timer(&btn_timer);
} module_init(btn_init);
module_exit(btn_exit);
MODULE_LICENSE("GPL");
测试代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h> //input_event,标准键值等 int main(int argc, char *argv[])
{
int fd;
struct input_event button; fd = open(argv[], O_RDWR); //./btn_test /dev/input/event3
if (fd < ) {
printf("open button failed.\n");
return -;
} while() {
read(fd, &button, sizeof(button));
printf("type = %#x, code = %#x, value = %#x\n",
button.type, button.code, button.value);
} close(fd);
return ;
}
input子系统的更多相关文章
- linux kernel input 子系统分析
Linux 内核为了处理各种不同类型的的输入设备 , 比如说鼠标 , 键盘 , 操纵杆 , 触摸屏 , 设计并实现了一个对上层应用统一的试图的抽象层 , 即是Linux 输入子系统 . 输入子系统的层 ...
- input子系统详解
一.初识linux输入子系统 linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(Inpu ...
- 鼠标驱动之-sys节点-input子系统
首先需要了解sys节点和linux驱动编程的知识,在linux内核<linux/>下有着对应的实现.本例实现创建sys节点,外围程序通过input子系统控制鼠标位置. 第一步编写驱动代码, ...
- linux 输入子系统(4)---- input子系统的初始化
Input子系统的初始化函数为input_init(),如下: static int __init input_init(void) { int err; input_init_abs_bypass( ...
- input子系统 KeyPad-Touch上报数据格式与机制
-----------------------------------------------------------------------本文系本站原创,欢迎转载!转载请注明出处:http://b ...
- input子系统分析
------------------------------------------ 本文系本站原创,欢迎转载! 转载请注明出处:http://ericxiao.cublog.cn/ -------- ...
- Android驱动之 Linux Input子系统之TP——A/B(Slot)协议
将A/B协议这部分单独拿出来说一方面是因为这部分内容是比较容易忽视的,周围大多数用到input子系统的开发人员也不甚理解:另一方面是由于这部分知识一旦扩展到TP(触摸屏Touch Panel)的多点触 ...
- 基于input子系统的sensor驱动调试(一)
要想弄明白世界的本质,就要追根溯源:代码也是一样的道理: 最近调试几个sensor驱动,alps sensor驱动.compass sensor驱动.G-sensor驱动都是一样的架构: 一.基于in ...
- 基于input子系统的sensor驱动调试(二)
继上一篇:http://www.cnblogs.com/linhaostudy/p/8303628.html#_label1_1 一.驱动流程解析: 1.模块加载: static struct of_ ...
随机推荐
- No.013:Roman to Integer
问题: Given a roman numeral, convert it to an integer.Input is guaranteed to be within the range from ...
- 通过angularJS官方案例快速入门
官方案例-angular-phonecat angularJS官方提供了一个官方案例给大家进行循序渐进的学习,但是如果之前没有接触过node.js以及git的同学这个案例拿着也无从下手-这里就介绍一下 ...
- Jconsole远程监控tomcat 的JVM内存(linux、windows)
Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到.它用于连接正在运行的本地或者远程的JVM,对运行在java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界 ...
- Hibernate(五)__hql语句
hql(hibernate query language)功能强大. 首先回忆下之前我们接触的对数据对象的操作: ①删除session.delete(对象) ②保存session.save(对象) ...
- SQLSERVER 2012计算上一条,下一条数据的函数
实际需求很普遍,比如求销售数据的每天与头一天的销售增长量.这里用一个汽车行驶数据来做例子: 先初始化数据: CREATE TABLE [dbo].[CarData]( [CarID] [int] NU ...
- Sequence.js 实现带有视差滚动特效的图片滑块
Sequence.js 功能齐全,除了能实现之前分享过的现代的图片滑动效果,还可以融合当前非常流行的视差滚动(Parallax Scrolling)效果.让多层背景以不同的速度移动,形成立体的运动效果 ...
- 性能更好的js动画实现方式——requestAnimationFrame
用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升.但是css3动画还是 ...
- SAP/SD - 做SD你要知道的透明表
一.客户主数据基本数据放在KNA1里:公司代码放在KNB1里:销售视图放在KNVV里:合作伙伴放在KNVP里:二.信用主数据KNKK里有信贷限额.应收总额.特别往来:S066里是未清订单值:S067里 ...
- Hadoop 2.5.1编译
1.环境安装 gcc.gcc-c++.make.cmake.svn yum install lzo-devel zlib-devel gcc gcc-c++ make cmake autoconf a ...
- Navicat Premium11.0.20破解版快速安装配置(附文件)
Navicat Premium是当下非常好用的数据库管理软件,但是价格非常昂贵,并且还有某些小bug,感觉3000+的人民币 与软件本身的价值还是不相称.下面是破解安装流程安装过程是在MAC 10.1 ...