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 ;
}

最新文章

  1. OriDomi – 像折叠纸张一样折叠 DOM 元素
  2. extJs学习基础4 Ext.each的用法
  3. eclipse几个注意的地方
  4. [WinAPI] API 13 [遍历指定目录 打印文件和其他属性]
  5. HDU 5025
  6. css布局学习笔记之max-width
  7. Spring+TaskExecutor实例
  8. Chrome 无法自动填充密码
  9. Python每日练习汇总
  10. Tensorflow卷积神经网络[转]
  11. python之函数联系
  12. ansible的管理与剧本
  13. 安装MySQL Connector/C++并将其配置到VS2015中
  14. Failed to load resource: the server responded with a status of 404 (Not Found) favicon.ico文件找不到
  15. mysql 导出sql结果成csv文件
  16. luoguP5105 不强制在线的动态快速排序
  17. python操作上级子文件
  18. Js如何动态声明变量名
  19. 软件测试面试题-适合零基础和工作多年的re
  20. Python基础(10)_内置函数、匿名函数、递归

热门文章

  1. 矩阵乘法&amp;矩阵快速幂&amp;矩阵快速幂解决线性递推式
  2. ReportingServies——SQLServer报表开发综合实例
  3. Linux IO函数的使用和区别
  4. web性能优化——代理(nginx)
  5. 基于NXBRE规则引擎实现的柔性折扣策略
  6. 基于jPlayer的三分屏制作
  7. sublime安装
  8. Linux学习心得之 双显卡、中文输入法及svn初步使用
  9. [Android]使用RecyclerView替代ListView(一)
  10. Android-Using DDMS