Linux设备驱动之按键设备驱动
作者:网络转载 发布时间:[ 2016/5/5 11:17:34 ] 推荐标签:操作系统 Linux
3.3 中断申请函数
/*申请系统中断,中断方式为下降沿触发*/
static int request irqs(void)
{
struct key info *k;
int i;
for (i= 0; i < sizeof(key info tab) / sizeof(key info tab [1]); i++)
{
k = key info tab + i;
set external irq (k->irq no, EXT LOWLEVEL, GPIO PULLUP DIS);
//设置低电平触发
if (request irq (k->irq no, &buttons irq, SA INTERRUPT,
DEVICE NAME,
i)) //申请中断,将 键序号作为参数传入中断服务程序
{
return - 1;
}
}
return 0;
}
3.4 中断释放函数
/*释放中断*/
static void free irqs(void)
{
struct key info *k;
int i;
for (i= 0; i < sizeof(key info tab) / sizeof(key info tab [1]); i++)
{
k = key info tab + i;
free irq (k->irq no, buttons irq); //释放中断
}
}
4 按键设备驱动中断和定时器处理程序
在按键按下之后,将发生中断,在中断处理程序中,应该先关闭中断进去查询模式,延时以消抖如下中断处理过程只有顶半部,没有底半部。
4.1 中断处理程序
static void s3c2410 eint key (int irq, void *dev id, struct pt regs
*reg)
{
int key = dev id;
disable irq (key info tab [key].irq no); //关中断,转入查询 式
keydev.keyStatus[key] = KEYSTATUS DOWNX;//状态为按下
_
key timer [key].expires == jiffies + KEY TIMER DELAY1;//延迟
add timer (&key timer[key]); //启动定时器
}
4.2 定时器处理流程
按键按下时,该按键将记录字啊缓冲区,同时定时器启动延时,每次记录新的键值时,等待队列被唤醒,其代码如下。
//按键设备驱动的定时器处理函数
static void key timer handler (unsigned long data)
{
int key = data;
if (ISKEY DOWN (key))
{
if (keydev.keyStatus[key] == KEYSTATUS DOWNX)
//从中断进入
{
keydev .keyStatus[key] = KEYSTATUS DOWN;
key timer[key].expires == jiffies + KEY TIMER DELAY; //延迟
keyEvent (); //记录键值,唤醒等待队列
add timer(&key timer [key]);
}
else
{
key timer[key].expires == jiffies + KEY TIMER DELAY; //延迟
add timer(&key timer [key]);
}
}
else //键已抬起
{
keydev.keyStatus[key] = KEYSTATUS UP;
enable irq (key info tab [key].irq no);
}
5 打开和释放函数
这里主要是设置keydev.head和keydev.tail还有按键事件函数指针keyEvent的值,按键设备驱动的打开、释放函数如下:
static int s3c2410 key open (struct inode *inode, struct file *filp)
{
keydev .head = keydev .tail = 0; //清空 键动作缓冲区
keyEvent = keyEvent raw; //函数指针指向 键处理函数keyEvent raw
return 0;
}
static int s3c2410 key release (struct inode *inode, struct file *filp)
{
keyEvent = keyEvent dummy; //函数指针指向空函数
return 0;
}
6 读函数
读函数主要是提供对按键设备结构体缓冲区的读并复制到用户空间,当keydev.head != keydev.tail时,说明缓冲区有数据,使用copy_to_user()函数拷贝到用户空间,反之根据用户空间是阻塞还是非阻塞读分为以下两种情况:
非阻塞读:没有按键缓存,直接返回- EAGAIN;
阻塞读:在keydev.wq等待队列上睡眠,直到有按键记录 到缓冲区后被唤醒。
//按键设备驱动的读函数
static ssize t s3c2410 key read (struct file *filp,char *buf,ssize tcount, loff t*ppos)
{
retry: if (keydev.head != keydev .tail)
//当前循环队列中有数据
{
key ret = keyRead (); //读取按键
copy to user(..); //把数据从内核空间传送到用户空间
}
else
{
if (filp->f flags &O NONBLOCK)
//若用户采用非阻塞方式读取
{
return - EAGAIN;
}
interruptible sleep on (&(keydev .wq));
//用户采用阻塞方式读取,调用该函数使进程睡眠
goto retry;
}
return 0;
}
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Linux下开源的DDR压力测试工具曝Linux恶意软件:让树莓派设备挖掘数字货币linux系统中不同颜色的文件夹及根目录介绍软件测试工程师必知必会Linux命令Linux下DNS服务器配置如何成为不可替代的Linux运维工程师?详解Linux进程(作业)的查看和杀死Linux 日志定时轮询流程详解比特币勒索病毒不只Windows系统有,Linux版的来了Linux日志定时轮询流程详解Linux iommu和vfio概念空间解构Linux系统如何低于TCP洪水攻击Linux无损调整分区大小Linux下防火墙配置实例Linux使用Jexus托管Asp.Net Core应用程序Linux中引号的那些事
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南