Linux 驱动——Button8(输入子系统)
输入子系统由驱动层、输入子系统核心、事件处理层三部分组成。一个输入事件,如鼠标移动、键盘按下等通过Driver->Inputcore->Event handler->userspace的顺序到达用户控件的应用程序。
其中核心层提供一些设备层与事件层公用的函数,比如说注册函数、反注册函数、事件到来的处理函数等等;事件层其实在Linux内核里面已经帮我们写好了很多有关的事件;而设备层就跟我们新添加到输入系统的具体设备相关了。这里以JZ2440开发板上的4个按键作为输入子系统的按键:它定义的功能分别为:KEY_L、KEY_S、KEY_ENTER、KEY_LEFTSHIFT。这几个值是在include\linux\input.h中被定义的。
button_drv.c文件:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/device.h>/
#include <asm/arch/regs-gpio.h>
#include <linux/irq.h>
#include <asm-arm/irq.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <asm-generic/errno-base.h>
#include <linux/input.h>
struct pin_desc
{
char * name; //名称
unsigned int pin; //管脚定义
unsigned int irq; //中断号
unsigned int key_val; //按键值
};
static struct pin_desc pins_desc[4] =
{
{"S1",S3C2410_GPF0,IRQ_EINT0,KEY_L},
{"S2",S3C2410_GPF2,IRQ_EINT2,KEY_S},
{"S3",S3C2410_GPG3,IRQ_EINT11,KEY_ENTER},
{"S4",S3C2410_GPG11,IRQ_EINT19,KEY_LEFTSHIFT}
};
static struct pin_desc *pinss_desc=NULL;
static struct timer_list timer_button; //新建一个定时器
static struct input_dev *buttons_input; //新建一个输入子系统的设备层结构
static irqreturn_t buttons_irq(int irq, void *dev_id)
{
pinss_desc = (struct pin_desc *)dev_id; //取得哪个按键被按下的状态
mod_timer(&inputbuttons_timer, jiffies+HZ/100); //10ms之后调用定时器处理函数
return IRQ_HANDLED;
}
static void timer_button_timeout(unsigned long a)
{
unsigned int pin_val;
if(pinss_desc==NULL)
return;
else
{
pin_val = s3c2410_gpio_getpin(pinss_desc->pin);
if(pin_val)
{
input_event(buttons_input,EV_KEY, pinss_desc->key_val, 0);
}
else
{
input_event(buttons_input,EV_KEY, pinss_desc->key_val, 1);
}
}
}
static int button_drv_init(void)
{
unsigned char i;
int ret;
buttons_input = input_allocate_device(); //分配input_dev结构体
if (!buttons_input)
return -ENOMEM;
set_bit(EV_KEY, buttons_input->evbit); //按键事件
set_bit(EV_REP, buttons_input->evbit); //重复事件类型
set_bit(KEY_L, buttons_input->keybit);
set_bit(KEY_S, buttons_input->keybit);
set_bit(KEY_ENTER, buttons_input->keybit);
set_bit(KEY_LEFTSHIFT, buttons_input->keybit);
input_register_device(buttons_input); //注册设备驱动
init_timer(&timer_button);
inputbuttons_timer.expires = 0;
inputbuttons_timer.function = timer_button_timeout;
add_timer(&timer_button);
//注意这里没有创建设备类和设备文件(设备节点)
//因为输入子系统的设备文件本来就存在为/dev/event0
for(i=0;i<4;i++)
{
ret = request_irq(pins_desc[i].irq, buttons_irq, IRQT_BOTHEDGE, pins_desc[i].name, (void * )&pins_desc[i]);
if(ret)
{
printk("open failed %d\n",i);
return -(i+1);
}
}
return 0;
}
static void button_drv_exit(void)
{
unsigned char i;
input_unregister_device(buttons_input);
input_free_device(buttons_input);
del_timer(&timer_button);
for(i=0;i<4;i++)
{
free_irq(pins_desc[i].irq, (void * )&pins_desc[i]);
}
}
module_init(seven_drv_init);
module_exit(seven_drv_exit);
MODULE_LICENSE("GPL");
Makefile文件:
obj-m += button_drv.o
KERN_DIR = /work/system/linux-2.6.22.6
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
rm -rf *.o *.ko *.order *.symvers *.mod.c
button_app.c文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
static int fd;
int main(int argc, char **argv)
{
char* filename = argv[1];
int oflags, ret=0;
unsigned char key_val[16];
fd = open(filename, O_RDWR);//打开设备文件,阻塞方式打开
if (fd < 0)
{
printf("error, can't open %s\n", filename);
return 0;
}
while(1)
{
ret = read(fd, key_val, 16);
printf("ret: %d, code: %02d, value: %d \n", ret, key_val[10], key_val[12]);
}
return 0;
}
app_read->evdev_read->kbtab_irq->input_report_key->input_event->evdev_event->evdev_read
应用层 事件层 设备层 核心层 核心层 事件层 事件层
应用函数最终会通过事件层的evdev_event调用evdev_read
而在linux中evdev_event结构体共16字节,所以app中的read函数也应该读取16字节
编译生成button_drv.ko和button_app文件,运行./button_app /dev/event0
Linux 驱动——Button8(输入子系统)的更多相关文章
- linux驱动模型<输入子系统>
在linux中提供一种输入子系统的驱动模型,其主要是实现在input.c中. 在输入子系统这套模型中,他把驱动分层分类.首先分为上下两层,上层为input.c .下层为驱动的实现,下层分为两部分,一部 ...
- Linux驱动之输入子系统简析
输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如鼠标移动.键盘按下等通过Driver->Inputcore->Event handler->userspac ...
- Linux 驱动框架---input子系统框架
前面从具体(Linux 驱动框架---input子系统)的工作过程学习了Linux的input子系统相关的架构知识,但是前面的学习比较实际缺少总结,所以今天就来总结一下输入子系统的架构分层,站到远处来 ...
- Linux 驱动框架---input子系统
input 子系统也是作为内核的一个字符设备模块存在的,所以他也是字符设备自然也会有字符设备的文件接口.input子系统的注册过程主要分为两步,先注册了一个input class然后再注册一个字符设备 ...
- ARM Linux内核Input输入子系统浅解
--以触摸屏驱动为例 第一章.了解linux input子系统 Linux输入设备总类繁杂,常见的包括有按键.键盘.触摸屏.鼠标.摇杆等等,他们本身就是字符设备,而linux内核将这些 ...
- Linux驱动之一个简单的输入子系统程序编写
的在Linux驱动之输入子系统简析已经分析过了输入子系统的构成,它是由设备层.核心层.事件层共同组成的.其中核心层提供一些设备层与事件层公用的函数,比如说注册函数.反注册函数.事件到来的处理函数等等: ...
- Linux输入子系统 转载
NQian 记录成长~ 首页 新随笔 联系 订阅 管理 随笔 - 305 文章 - 0 评论 - 254 12.Linux之输入子系统分析(详解) 在此节之前,我们学的都是简单的字符驱动,涉及 ...
- Linux驱动之触摸屏程序编写
本篇博客分以下几部分讲解 1.介绍电阻式触摸屏的原理 2.介绍触摸屏驱动的框架(输入子系统) 3.介绍程序用到的结构体 4.介绍程序用到的函数 5.编写程序 6.测试程序 1.介绍电阻式触摸屏的原理 ...
- linux 输入子系统之电阻式触摸屏驱动
一.输入子系统情景回忆ING...... 在Linux中,输入子系统是由输入子系统设备驱动层.输入子系统核心层(Input Core)和输入子系统事件处理层(Event Handler)组成.其中设备 ...
随机推荐
- Web的Flex弹性盒模型
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【差分约束系统】 note
[差分约束系统] note >>>>题目 [题目描述] 最近有一款很火的游戏,叫做八分音符酱,它和马里奥很相似,不过它的跳跃距离是由你的声音大小来控制的.不过我们现在对玩法就行 ...
- [转]axios的兼容性处理
来源: https://www.cnblogs.com/leaf930814/p/6807318.html ---------------------------------------------- ...
- 【转】IIS请求筛选模块被配置为拒绝超过请求内容长度的请求
HTTP错误404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求,原因是Web服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值(IIS 7 默认文件上传大 ...
- 从码农到技术总监分享Leader经验
从一个毕业的IT小伙或者一个码农成长为一个管理者,有很多需要转变的思想,那么当你遇到了瓶颈,或许我的经验能帮到你,感谢. 系统的掌握了.NET,JAVA技术,能够熟练的使用springcloud + ...
- ArrayList与LinkList
1.ArrayList 1)继承结构 2)ArrayList是数组存储结果,初始容量为0,添加第一个元素后容器为10,后面每次超过容量时,容量递增50%,每次扩容都需要产生新的数组,再把老的数据复制过 ...
- 分析Linux内核5.0系统调用处理过程
学号: 363 本实验来源 https://github.com/mengning/linuxkernel/ 一.实验要求 1.编译内核5.02.qemu -kernel linux-5.0.1/ar ...
- 框架-thrift-zookeeper-kafka
Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架. 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 ...
- Ubuntu开机启动roscore服务的设置
1.在/etc/init.d中添加启停脚本ros_daemon.bash: #!/bin/bash ### BEGIN INIT INFO # Provides: ros_daemon.bash # ...
- Linux c使用gumbo库解析页面表单信息(三)
前面说了那么多,终于说到如何解析html表单信息了. 什么是表单信息呢,这里我们先要有一些概念: 如上图,这是一个QQ注册页面,注册页面当中需要我们填的空其实就是一个表单信息. 具体到html代码当中 ...