在linux中提供一种输入子系统的驱动模型,其主要是实现在input.c中。

在输入子系统这套模型中,他把驱动分层分类。首先分为上下两层,上层为input.c 。下层为驱动的实现,下层分为两部分,一部分为drive部分,主要实现和硬件无关的代码,一本分为device部分,这部分就是与硬件相关的代码。

在内核代码中drive部分已经为我们写好了,你也可以自己写,我一般用的是evdev.c这个文件里面的代码。我们所要做的就是编写device里面的代码。这样就可以减轻程序员的编写负担。免得每次写驱动程序都要编写与硬件无关的程序。

下面看我写的device部分的代码:

 #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> //////////////这里声明了一个结构体指针 为构建整套系统所必须的
static struct input_dev *buttons_dev; //////////////定义了一个时钟的结构体,程序里面关键是为了防抖
static struct timer_list buttons_timer;
24
//////////////////////////
static struct pin_desc *irq_pd;

/////////////////这个结构体存储了一些必要的数据
struct pin_desc{
int irq;
char *name;
unsigned int pin;
unsigned int key_val;
}; struct pin_desc pins_desc[] = {
{IRQ_EINT8, "K1", S3C2410_GPG0, KEY_L},
{IRQ_EINT11, "K2", S3C2410_GPG3, KEY_S},
{IRQ_EINT13, "K3", S3C2410_GPG5, KEY_ENTER},
{IRQ_EINT14, "K4", S3C2410_GPG6, KEY_LEFTSHIFT},
}; /////////中断处理函数 里面主要是设置定时器的时钟 用来防抖
static irqreturn_t buttons_irq(int irq, void *dev_id)
{
irq_pd = (struct pin_desc *) dev_id;
mod_timer(&buttons_timer, jiffies+HZ/);
return IRQ_RETVAL(IRQ_HANDLED);
} //////////此函数为定时器函数 定时的时间到了后这个函数被执行 主要用于检测按键被按下 然后上报事件
static void buttons_timer_function(unsigned long data)
{
struct pin_desc * pindesc = irq_pd; unsigned int pinval; if (!pindesc)
return; pinval = s3c2410_gpio_getpin(pindesc->pin); if (pinval)
{
/* 松开 : 最后一个参数: 0-松开, 1-按下 */
input_event(buttons_dev, EV_KEY, pindesc->key_val, );
input_sync(buttons_dev);
}
else
{
/* 按下 */
input_event(buttons_dev, EV_KEY, pindesc->key_val, );
input_sync(buttons_dev);
} return ;
} //////////各种初始化 关于input_dev结构体的分配 和赋值什么的 这个关键是要看input.c里面的内容
static int buttons_init(void)
{
int i;
/* 1.分配一个imput_dev结构体*/
buttons_dev = input_allocate_device(); /*2. 设置*/ /*2.1 能产生哪类事件*/
set_bit(EV_KEY, buttons_dev->evbit);
set_bit(EV_REP, buttons_dev->evbit); /*2.2 能够产生哪些事件*/
set_bit(KEY_L, buttons_dev->keybit);
set_bit(KEY_S, buttons_dev->keybit);
set_bit(KEY_ENTER, buttons_dev->keybit);
set_bit(KEY_LEFTSHIFT, buttons_dev->keybit); /*3. 注册*/
input_register_device(buttons_dev); /*4. 硬件相关的操作*/
init_timer(&buttons_timer);
buttons_timer.function = buttons_timer_function;
add_timer(&buttons_timer); for(i = ; i < ; i++)
{
request_irq(pins_desc[i].irq, buttons_irq, IRQT_BOTHEDGE, pins_desc[i].name, &pins_desc[i]);
} return ; } ///////////这个函数就是各种卸载啦
static void buttons_exit(void)
{
int i;
for (i = ; i < ; i++)
{
free_irq(pins_desc[i].irq, &pins_desc[i]);
} del_timer(&buttons_timer);
input_unregister_device(buttons_dev);
input_free_device(buttons_dev); return ;
} module_init(buttons_init);
module_exit(buttons_exit);
MODULE_LICENSE("GPL");

以上的程序没有什么太大的难点,但是细细研究还是有很多东西值得我们去研究的。

我们研究的只是device这部分的代码,要深入的理解还是要看内核源码啊。

linux驱动模型<输入子系统>的更多相关文章

  1. Linux驱动之输入子系统简析

    输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如鼠标移动.键盘按下等通过Driver->Inputcore->Event handler->userspac ...

  2. Linux 驱动框架---input子系统框架

    前面从具体(Linux 驱动框架---input子系统)的工作过程学习了Linux的input子系统相关的架构知识,但是前面的学习比较实际缺少总结,所以今天就来总结一下输入子系统的架构分层,站到远处来 ...

  3. Linux 驱动框架---input子系统

    input 子系统也是作为内核的一个字符设备模块存在的,所以他也是字符设备自然也会有字符设备的文件接口.input子系统的注册过程主要分为两步,先注册了一个input class然后再注册一个字符设备 ...

  4. ARM Linux内核Input输入子系统浅解

    --以触摸屏驱动为例 第一章.了解linux input子系统         Linux输入设备总类繁杂,常见的包括有按键.键盘.触摸屏.鼠标.摇杆等等,他们本身就是字符设备,而linux内核将这些 ...

  5. linux驱动模型——platform(1)

    一.驱动模型包含什么? 1.1. 类class 1.1.2. 它能够自动创建/dev下的设备节点,不需要mknod /dev/xxx c x x创建.当然class还有其另外的作用,且自动创建设备节点 ...

  6. Linux驱动模型解析bus之platform bus

    这是内核启动之后要调用的驱动模型的开始代码: drivers/base/init.c/** * driver_init - initialize driver model. * * Call the ...

  7. linux驱动模型——platform(2)

    一. platform 组织架构 1.1. platform工作体系都定义在drivers/base/platform.c中 1.2. platform相关函数声明在include/linux/pla ...

  8. Linux驱动之一个简单的输入子系统程序编写

    的在Linux驱动之输入子系统简析已经分析过了输入子系统的构成,它是由设备层.核心层.事件层共同组成的.其中核心层提供一些设备层与事件层公用的函数,比如说注册函数.反注册函数.事件到来的处理函数等等: ...

  9. Linux输入子系统 转载

    NQian 记录成长~ 首页 新随笔 联系 订阅 管理 随笔 - 305  文章 - 0  评论 - 254 12.Linux之输入子系统分析(详解)   在此节之前,我们学的都是简单的字符驱动,涉及 ...

随机推荐

  1. heap size eclipse 堆内存

    可以根据eclipse 或 myeclipse heapstats 使用情况调整堆内存大小,heap size 设置,-vmargs-Xms256-Xmx1024 ,其中Xms表示初始值,Xmx表示最 ...

  2. JS中的forEach、$.each、map方法

    forEach是ECMA5中Array新方法中最基本的一个,就是遍历,循环.例如下面这个例子: [1, 2 ,3, 4].forEach(alert); 等同于下面这个for循环 var array ...

  3. Careercup - Google面试题 - 5727310284062720

    2014-05-06 14:04 题目链接 原题: given an 2D matrix M, is filled either using X or O, you need to find the ...

  4. javascript_04 数据类型

    ECMAScript 数据类型  标准  核心   数据类型 typeof  判断数据类型 数字型 布尔型 对象类型 函数 字符串 undefined 未定义 数字型  字符型 var s='1233 ...

  5. c++ 缺少动态库

    http://www.cnblogs.com/smartvessel/archive/2011/01/21/1940868.html 总结下来主要有3种方法: . 用ln将需要的so文件链接到/usr ...

  6. 深入分析windows下配置wamp环境各模块的版本兼容性

    版本相关概念说明: ts/nts: thread safety 线程安全 TS refers to multithread capable builds. NTS refers to single t ...

  7. Hdu 1506 Largest Rectangle in a Histogram 分类: Brush Mode 2014-10-28 19:16 93人阅读 评论(0) 收藏

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  8. 快速幂取模 分类: ACM TYPE 2014-08-29 22:01 95人阅读 评论(0) 收藏

    #include<stdio.h> #include<stdlib.h> //快速幂算法,数论二分 long long powermod(int a,int b, int c) ...

  9. iOS开发如何实现消息推送机制

    一.关于推送通知 推送通知,也被叫做远程通知,是在iOS 3.0以后被引入的功能.是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径,是从外部服务器发送到应用程序上的.一般说来,当要显示消息 ...

  10. 在JavaScript中判断整型的N种方法

    原文:http://www.cnblogs.com/YcYYcY/p/3759184.html 整数类型(Integer)在JavaScript经常会导致一些奇怪的问题.在ECMAScript的规范中 ...