您的位置:首页 > 运维架构 > Linux

[arm驱动]input system 子系统的驱动编写

2014-05-04 13:46 453 查看
更多可参考

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






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息