[arm驱动]input system 子系统的驱动编写
2014-05-04 13:46
453 查看
更多可参考
static struct input_dev *mybutton_dev;
2、初始化时分配input_dev结构体
mybutton_dev = input_allocate_device();//分配 input_dev
set_bit(EV_REP, mybutton_dev->evbit);
//设置支持的按键值
set_bit(KEY_L, mybutton_dev->keybit);
set_bit(KEY_S, mybutton_dev->keybit);
set_bit(KEY_ENTER, mybutton_dev->keybit);
error = input_register_device(mybutton_dev);//注册驱动
3、//输入子系统的事件handle函数
static void inputsystemtimer_handle(unsigned long data){
struct pin_desc * pino_desc = irq_pd;
unsigned int pinval;
if (!pino_desc)
return;
pinval = s3c2410_gpio_getpin(pino_desc->pin);
if (pinval)
{
/* 松开 : 最后一个参数: 0-松开, 1-按下 */
input_report_key(mybutton_dev, pino_desc->key_val, 0);
//貌似必须这样,如果val填pinval会一直报告事件
//貌似必须这样,如果val填inb(pino_desc->pin) & 1会一直报告事件有延迟
input_sync(mybutton_dev);
}
else
{
/* 按下 */
input_report_key(mybutton_dev, pino_desc->key_val, 1);//必须填1
input_sync(mybutton_dev);
}
printk("press button is %s\n", pino_desc->name);
}
4、//注销驱动
input_unregister_device(mybutton_dev);//注销驱动
input_free_device(mybutton_dev);
完整实例:按键的输入子系统
测试程序
Linux输入子系统分析
input 子系统架构总结
1、定义一个static struct input_dev结构体static struct input_dev *mybutton_dev;
2、初始化时分配input_dev结构体
mybutton_dev = input_allocate_device();//分配 input_dev
/*能产生的事件类型 1. #define EV_SYN 0x00 /*表示设备支持所有的事件*/ 2. #define EV_KEY 0x01 /*键盘或者按键,表示一个键码*/ 3. #define EV_REL 0x02 /*鼠标设备,表示一个相对的光标位置结果*/ 4. #define EV_ABS 0x03 /*手写板产生的值,其是一个绝对整数值*/ 5. #define EV_MSC 0x04 /*其他类型*/ 6. #define EV_LED 0x11 /*LED 灯设备*/ 7. #define EV_SND 0x12 /*蜂鸣器,输入声音*/ 8. #define EV_REP 0x14 /*允许重复按键类型*/ 9. #define EV_PWR 0x16 /*电源管理事件*/ */set_bit(EV_KEY, mybutton_dev->evbit);
set_bit(EV_REP, mybutton_dev->evbit);
//设置支持的按键值
set_bit(KEY_L, mybutton_dev->keybit);
set_bit(KEY_S, mybutton_dev->keybit);
set_bit(KEY_ENTER, mybutton_dev->keybit);
error = input_register_device(mybutton_dev);//注册驱动
3、//输入子系统的事件handle函数
static void inputsystemtimer_handle(unsigned long data){
struct pin_desc * pino_desc = irq_pd;
unsigned int pinval;
if (!pino_desc)
return;
pinval = s3c2410_gpio_getpin(pino_desc->pin);
if (pinval)
{
/* 松开 : 最后一个参数: 0-松开, 1-按下 */
input_report_key(mybutton_dev, pino_desc->key_val, 0);
//貌似必须这样,如果val填pinval会一直报告事件
//貌似必须这样,如果val填inb(pino_desc->pin) & 1会一直报告事件有延迟
input_sync(mybutton_dev);
}
else
{
/* 按下 */
input_report_key(mybutton_dev, pino_desc->key_val, 1);//必须填1
input_sync(mybutton_dev);
}
printk("press button is %s\n", pino_desc->name);
}
4、//注销驱动
input_unregister_device(mybutton_dev);//注销驱动
input_free_device(mybutton_dev);
完整实例:按键的输入子系统
#include <linux/module.h> #include <linux/version.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/sched.h> #include <linux/pm.h> #include <linux/sysctl.h> #include <linux/proc_fs.h> #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/input.h> #include <linux/irq.h> #include <linux/gpio_keys.h> #include <asm/gpio.h> #include <asm/irq.h> #include <asm/io.h> static struct input_dev *mybutton_dev; static struct timer_list mybutton_timer; struct pin_desc *irq_pd; struct pin_desc{ int irq; char *name; unsigned int pin; unsigned int key_val; }; struct pin_desc pins_desc[3] = { {IRQ_EINT0, "S2", S3C2410_GPF0, KEY_L}, {IRQ_EINT2, "S3", S3C2410_GPF2, KEY_S}, {IRQ_EINT11, "S4", S3C2410_GPG3, KEY_ENTER}, }; static irqreturn_t irq_handle(int irq, void *dev__id){ irq_pd = (struct pin_desc *)dev__id; mod_timer(&mybutton_timer, jiffies+HZ/100); return IRQ_HANDLED;//返回IRQ_HANDLED表示中断已经处理 } static void inputsystemtimer_handle(unsigned long data){ struct pin_desc * pino_desc = irq_pd; unsigned int pinval; if (!pino_desc) return; pinval = s3c2410_gpio_getpin(pino_desc->pin); if (pinval) { /* 松开 : 最后一个参数: 0-松开, 1-按下 */ input_report_key(mybutton_dev, pino_desc->key_val, 0); input_sync(mybutton_dev); } else { /* 按下 */ input_report_key(mybutton_dev, pino_desc->key_val, 1); input_sync(mybutton_dev); } printk("press button is %s\n", pino_desc->name); } static int inputsystem_init(void){ int i = 0; int error; init_timer(&mybutton_timer); mybutton_timer.function = inputsystemtimer_handle; add_timer(&mybutton_timer); mybutton_dev = input_allocate_device(); if(! mybutton_dev){ printk(KERN_ERR "allocate failed!\n"); error = -ENOMEM; goto err_free_irq; } mybutton_dev->name = "buttonKeyboard"; mybutton_dev->phys = "gpio-keys/input0"; mybutton_dev->id.version = 0x0100; set_bit(EV_KEY, mybutton_dev->evbit); set_bit(EV_REP, mybutton_dev->evbit); set_bit(KEY_L, mybutton_dev->keybit); set_bit(KEY_S, mybutton_dev->keybit); set_bit(KEY_ENTER, mybutton_dev->keybit); error = input_register_device(mybutton_dev); if(error){ printk(KERN_ERR"input regsiter error\n"); goto err_free_dev; } for(i = 0; i < 3; i ++) request_irq(pins_desc[i].irq, irq_handle, IRQT_BOTHEDGE, pins_desc[i].name, &pins_desc[i]); return 0; err_free_irq: for(i = 0; i < 3; i ++)free_irq(pins_desc[i].irq, &pins_desc[i]); err_free_dev: input_free_device(mybutton_dev); return error; } static void inputsystem_exit(void){ int i = 0; input_unregister_device(mybutton_dev);//注销驱动 input_free_device(mybutton_dev); del_timer(&mybutton_timer); for(i = 0; i < 3; i ++)free_irq(pins_desc[i].irq, &pins_desc[i]); } module_init(inputsystem_init); module_exit(inputsystem_exit); MODULE_LICENSE("GPL");
测试程序
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <poll.h> #include <signal.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <sys/stat.h> #include <errno.h> #include <linux/input.h> int main(void) { int fd; int key_value,i=0,count; struct input_event ev_key; fd = open("/dev/event1", 666); if (fd < 0) { printf("can't open device buttons!\n"); exit(1); } for (;;) { count = read(fd,&ev_key,sizeof(struct input_event)); for(i=0; i<(int)count/sizeof(struct input_event); i++){ printf("%d\n", ev_key.type); if(EV_KEY==ev_key.type) printf("type:%d,code:%d,value:%d\n", ev_key.type,ev_key.code,ev_key.value); } if(EV_SYN==ev_key.type) printf("syn event\n\n"); } printf("app close fd\n"); close(fd); return 0; }
相关文章推荐
- arm 驱动进阶:编写输入子系统的驱动程序
- led子系统驱动,以及此类驱动(sysfs访问方式)应用程序编写
- 利用linux 内核所提供的input子系统编写字符设备驱动的步骤
- ARM-linux驱动学习:led驱动程序编写练习(2014-8-22)
- led驱动编写并非使用led 子系统(实际led驱动编写)
- 编写基于ARM的uClinux下自设备驱动
- Linux时间子系统之(十七):ARM generic timer驱动代码分析
- 6、输入子系统驱动编写
- ARM+LINUX字符型设备驱动编写框架
- ARM开发之杂项设备的编写----以LED驱动为例
- 基于I2C子系统的I2C驱动编写
- Linux i2c子系统(四) _从i2c-s3c24xx.c看i2c控制器驱动的编写
- linux驱动之input子系统之按键驱动编写流程(三)
- linux驱动由浅入深系列:输入子系统之二(编写一个gpio_key驱动)
- ARM开发之linux字符型驱动的编写----LED驱动为例
- arm 驱动进阶:输入子系统概念及架构
- 手把手教你写Linux设备驱动---input子系统(四)--电容屏驱动ft5x06编写(一)(基于友善之臂4412开发板)
- Documentation\input\input-programming.txt(输入子系统驱动编写)
- Linux时间子系统(十七) ARM generic timer驱动代码分析
- led子系统之实战篇(实际led驱动编写)