嵌入式linux驱动-输入子系统笔记
来源:互联网 发布:霓虹灯效果图制作软件 编辑:程序博客网 时间:2024/04/30 21:40
一、开发环境
1、内核:Linux 2.6.22.6;
2、JZ2440
3、ubuntu 9.10
二、过程
1、分配input_dev结构体
使用input_allocate_device函数,如:
先定义一个input_dev 结构体类型变量:static struct input_dev *key_dev;
使用input_allocate_device函数分配:key_dev=input_allocate_device();
2、设置input_dev
input_dev结构体成员有:
struct input_dev {
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
unsigned long evbit[NBITS(EV_MAX)]; // 表示能产生哪类事件
unsigned long keybit[NBITS(KEY_MAX)]; // 表示能产生哪些按键
unsigned long relbit[NBITS(REL_MAX)]; // 表示能产生哪些相对位移事件, x,y,滚轮
unsigned long absbit[NBITS(ABS_MAX)]; // 表示能产生哪些绝对位移事件, x,y
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
...
}
先设置哪类操作,再设置这类操作的哪些事件,如
/* 2.1 设置按键能产生哪类事件 */
set_bit(EV_KEY,key_dev->evbit);//EV_KEY表示按键操作
set_bit(EV_REP,key_dev->evbit);//EV_REP表示按键重复操作
/* 2.2 设置能产生这类操作的哪些事件 */
set_bit(KEY_L,key_dev->keybit);//KEY_L表示按了L键
set_bit(KEY_S,key_dev->keybit);//KEY_S表示按了S键
set_bit(KEY_ENTER,key_dev->keybit);//ENTER表示按了ENTER键
set_bit(KEY_LEFTSHIFT,key_dev->keybit);//KEY_LEFTSHIFT表示按了左边的SHIFT键
另外:
input.h里有以下类
#define EV_SYN 0x00 //同步类
#define EV_KEY 0x01 //按键类
#define EV_REL 0x02 //相对位移类
#define EV_ABS 0x03 //绝对位移类
#define EV_MSC 0x04
#define EV_SW 0x05
#define EV_LED 0x11
#define EV_SND 0x12 //声音类
#define EV_REP 0x14 //重复类
#define EV_FF 0x15
#define EV_PWR 0x16
#define EV_FF_STATUS 0x17
#define EV_MAX 0x1f
#define EV_CNT (EV_MAX+1)
3、注册
使用input_register_device(struct input_dev *dev)函数来注册,如:input_register_device(key_dev);
4、硬件相关操作
具体应用具体写了。比如本实验中使用到定时器,初始化定时器,使用按键注册中断等。
5、程序
#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 <asm/gpio.h>#include <asm/io.h>#include <asm/arch/regs-gpio.h>struct key_desc{int irq;char *name;unsignedint pin;unsignedint key_val;};struct key_desc key_desc[4]={{IRQ_EINT0,"s2",S3C2410_GPF0,KEY_L},{IRQ_EINT2,"s3",S3C2410_GPF2,KEY_S},{IRQ_EINT11,"s4",S3C2410_GPG3,KEY_ENTER},{IRQ_EINT19,"s5",S3C2410_GPG11,KEY_LEFTSHIFT},};static struct input_dev *key_dev;static struct key_desc *irq_tmp;static struct timer_list key_timer;static irqreturn_t key_irq(int irq, void *dev_id){ // printk("key_irq!irq=%d \n",irq);irq_tmp=(struct key_desc*)dev_id;mod_timer(&key_timer, jiffies + HZ/100);return IRQ_RETVAL(IRQ_HANDLED);}static void key_timer_func(unsigned long __data){struct key_desc * keysdesc=irq_tmp;unsigned int keyval;//printk("key_timer_func! \n");if (!keysdesc){//printk("keysdesc\n");return;}keyval=s3c2410_gpio_getpin(keysdesc->pin);if(keyval){//松开input_event(key_dev,EV_KEY,keysdesc->key_val,0);input_sync(key_dev);//printk("input_event0! \n");}else{//按下input_event(key_dev,EV_KEY,keysdesc->key_val,1);input_sync(key_dev);//printk("input_event1! \n");}}static int key_init(void){int i;printk("key_init! \n");//分配一个input_dev结构体key_dev=input_allocate_device();//设置set_bit(EV_KEY,key_dev->evbit);set_bit(EV_REP,key_dev->evbit);set_bit(KEY_L,key_dev->keybit);set_bit(KEY_S,key_dev->keybit);set_bit(KEY_ENTER,key_dev->keybit);set_bit(KEY_LEFTSHIFT,key_dev->keybit);//注册input_register_device(key_dev);//硬件相关操作//定时器初始化init_timer(&key_timer);key_timer.function = key_timer_func;add_timer(&key_timer);for(i=0;i<4;i++){request_irq(key_desc[i].irq,key_irq ,IRQT_BOTHEDGE,key_desc[i].name,&key_desc[i]);}return 0;}static void key_exit(void){int i;printk("key_exit! \n");for(i=0;i<4;i++){free_irq(key_desc[i].irq,&key_desc[i]);}del_timer(&key_timer);input_unregister_device(key_dev);input_free_device(key_dev);}module_init(key_init);module_exit(key_exit);MODULE_LICENSE("GPL");
三、架构相关
1、驱动中按键松开、按下时调用input_event()函数把keysdesc->key_val即结构体
struct key_desc key_desc[4]={
{IRQ_EINT0,"s1",S3C2410_GPF0,KEY_L},
{IRQ_EINT2,"s2",S3C2410_GPF2,KEY_S},
{IRQ_EINT11,"s3",S3C2410_GPG3,KEY_ENTER},
{IRQ_EINT19,"s4",S3C2410_GPG11,KEY_LEFTSHIFT},
};
中的KEY_L,KEY_S,KEY_ENTER,KEY_LEFTSHIFT,传递给内核。
在input_event()函数中有:
list_for_each_entry(handle, &dev->h_list, d_node)
if (handle->open)
handle->handler->event(handle, type, code, value);
实现了从input_dev到input_handle到input_handler的调用。即从硬件层到两者的连接层到驱动层的调用。我们写的程序调用input_event()函数,input_event中通过dev->h_list找到input_handle,input_handle通过其成员handler找到event。
2、韦分层框架截图
四、命令
hexdump /dev/event1 hex显示/dev/event1
exec 0</dev/tty1 标准输入改为tty1
五、问题
1、加载模块后,没有event,如下
# ls -l /dev/event*
ls: /dev/event*: No such file or directory
解决:配置内核时选上Device Drivers->Input device support->Event interface && Event debugging。下载新内核到板子上。再重新make下编写的输入子系统。
加载子系统后,结果如下
六、结果
- 嵌入式linux驱动-输入子系统笔记
- 嵌入式Linux驱动笔记(六)------浅析input输入子系统框架
- 《Linux驱动》输入子系统
- 嵌入式linux之输入子系统
- linux驱动子系统之输入子系统(1)
- linux驱动子系统之输入子系统(2)
- linux驱动子系统之输入子系统(3)
- linux驱动子系统之输入子系统(4)
- linux驱动子系统之输入子系统(5)
- linux驱动子系统之输入子系统(5)
- Linux驱动子系统之输入子系统
- Linux驱动子系统之输入子系统
- linux驱动子系统之输入子系统(5)
- linux驱动子系统之输入子系统(1)
- linux驱动子系统之输入子系统(2)
- linux驱动子系统之输入子系统(3)
- linux驱动子系统之输入子系统(4)
- linux驱动子系统之输入子系统(5)
- Java关键字final、static使用总结
- c++第三次实验(基础班)-项目一
- Python语言基础及数据分析技术培训举行
- Giraph 内存测试
- R语言中包的操作
- 嵌入式linux驱动-输入子系统笔记
- jQuery的选择器中的通配符使用介绍
- js特效01动画效果及页面固定导航栏
- Spring配置 在xml和java代码中读取properties文件
- Android冷启动实现APP秒开
- hdu 4990 矩阵快速幂
- 利用Iterator接口输出Map集合的步骤
- C++ 实验3-2本月有几天?
- 单点登录的三种实现方式