linux驱动模型<输入子系统>
在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驱动模型<输入子系统>的更多相关文章
- 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驱动模型——platform(1)
一.驱动模型包含什么? 1.1. 类class 1.1.2. 它能够自动创建/dev下的设备节点,不需要mknod /dev/xxx c x x创建.当然class还有其另外的作用,且自动创建设备节点 ...
- Linux驱动模型解析bus之platform bus
这是内核启动之后要调用的驱动模型的开始代码: drivers/base/init.c/** * driver_init - initialize driver model. * * Call the ...
- linux驱动模型——platform(2)
一. platform 组织架构 1.1. platform工作体系都定义在drivers/base/platform.c中 1.2. platform相关函数声明在include/linux/pla ...
- Linux驱动之一个简单的输入子系统程序编写
的在Linux驱动之输入子系统简析已经分析过了输入子系统的构成,它是由设备层.核心层.事件层共同组成的.其中核心层提供一些设备层与事件层公用的函数,比如说注册函数.反注册函数.事件到来的处理函数等等: ...
- Linux输入子系统 转载
NQian 记录成长~ 首页 新随笔 联系 订阅 管理 随笔 - 305 文章 - 0 评论 - 254 12.Linux之输入子系统分析(详解) 在此节之前,我们学的都是简单的字符驱动,涉及 ...
随机推荐
- [shell基础]——find命令
find命令选项 -name 按照文件名查找 -type 查找某一类型的文件(b 代表设备块:d 目录:c 字符设备文件:l 符号(软)链接文件:f 普通文件) -size 查找文件长度或者大小 -p ...
- Android开发随笔4
昨天: 今天: 编写代码
- 用 Android-X86 和 VirtualBox 玩安卓游戏
目前的系统是 Ubuntu 14.04,近日玩了玩 flash 版的<皇家禁卫军:前线>塔防游戏,还是想试试原生安卓游戏的表现.发现大概有两个选择: 各类安卓模拟器:官方SDK模拟器,bl ...
- Netsharp FAQ
1.启动服务器时候不能监听端口,出现如下错误: 回答: 这种问题应该是在win7环境下才有,是没有权限,要以管理员身份运行Netsharp.Elephant.Q.exe. 2.启动服务器的时候,服务端 ...
- sql中having的使用
where 和having有什么区别? where 是group by之前进行筛选,having是group by 之后进行统计的筛选,一般having会和group by一起使用,结合聚合函数,统计 ...
- memcached使用说明
1.在服务器上注册服务 2.启动服务:services.msc 3.客户端创建服务接口 object Get(string key); List<string> GetKeys ...
- 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
// test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- GDI+的常用类
VisualStyleRenderer 提供用于绘制和获取有关 System.Windows.Forms.VisualStyles.VisualStyleElement 的信息的方法. VisualS ...
- NYOJ-235 zb的生日 AC 分类: NYOJ 2013-12-30 23:10 183人阅读 评论(0) 收藏
DFS算法: #include<stdio.h> #include<math.h> void find(int k,int w); int num[23]={0}; int m ...
- [ActionScript 3] 本地安全沙箱问题最快解决方法
使用FLex4.0时, Chrome等浏览器会报 安全水箱问题..... 解决方案: 打开flash全局安全配置面板并在页面中的配置面板中添加可信任的swf文件或者文件夹: 若是记不住全局安全配置 ...