热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

(linux自学笔记)linux按键中断

通常开发板自带按键中断的驱动,中断已被注册至内核。重新编译linux内核去掉自带驱动才能使用自己编写的驱动。驱动程序#include#include#include#inclu

通常开发板自带按键中断的驱动,中断已被注册至内核。重新编译linux内核去掉自带驱动才能使用自己编写的驱动。

bubuko.com,布布扣

驱动程序



#include
#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define DEVICE_NAME "key_device"
#define DEVICE_MAJOR 240
struct key_irq_desc
{
int irq;
int pin;
int pin_setting;
int number;
char *name;
};
static struct key_irq_desc key_irqs [] =
{
{IRQ_EINT(
0), S3C64XX_GPN(0) , S3C64XX_GPN0_EINT0 , 0, "KEY0"},
{IRQ_EINT(
1), S3C64XX_GPN(1) , S3C64XX_GPN1_EINT1 , 1, "KEY1"},
{IRQ_EINT(
2), S3C64XX_GPN(2) , S3C64XX_GPN2_EINT2 , 2, "KEY2"},
{IRQ_EINT(
3), S3C64XX_GPN(3) , S3C64XX_GPN3_EINT3 , 3, "KEY3"},
{IRQ_EINT(
4), S3C64XX_GPN(4) , S3C64XX_GPN4_EINT4 , 4, "KEY4"},
{IRQ_EINT(
5), S3C64XX_GPN(5), S3C64XX_GPN5_EINT5 , 5, "KEY5"},
};
static volatile int key_values [] = {1, 1, 1, 1, 1, 1};
//初始化等待列对
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
static volatile int event_flag = 0;
static irqreturn_t buttons_interrupt(int irq, void *dev_id)
{
struct key_irq_desc *dev_irqs = (struct key_irq_desc *)dev_id;
int down;
down
= gpio_get_value(dev_irqs->pin);
//按键发生了变化
if (down != (key_values[dev_irqs->number] & 1))
{
// Changed

key_values[dev_irqs
->number] = 0 + down;
event_flag
= 1;
//唤醒列对
wake_up_interruptible(&button_waitq);
}
return IRQ_RETVAL(IRQ_HANDLED);
}
static int s3c6410_key_open(struct inode *inode, struct file *file)
{
int i;
int err = 0;
//注册中断 结构体未注册完
for (i = 0; i <sizeof(key_irqs)/sizeof(key_irqs[0]); i++)
{
if (key_irqs[i].irq <0)
{
continue;
}
// 中断号 中断处理寒酸 中断处理属性
err = request_irq(key_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,
key_irqs[i].name, (
void *)&key_irqs[i]);
if (err)
break;
}
//如果注册中断过程中出错,则注销注册成功的中断
if (err)
{
i
--;
for (; i >= 0; i--)
{
if (key_irqs[i].irq <0)
{
continue;
}
disable_irq(key_irqs[i].irq);
free_irq(key_irqs[i].irq, (
void *)&key_irqs[i]);
}
return -EBUSY;
}
//显示一次主界面而已
event_flag = 1;
return 0;
}
static int s3c6410_keys_close(struct inode *inode, struct file *file)
{
int i;
//注销中断
for (i = 0; i <sizeof(key_irqs)/sizeof(key_irqs[0]); i++)
{
if (key_irqs[i].irq <0)
{
continue;
}
free_irq(key_irqs[i].irq, (
void *)&key_irqs[i]);
}
return 0;
}
static int s3c6410_keys_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
unsigned
long err;
if (!event_flag)
{
//没有新按键事件处理,如果用户要求不阻塞就直接返回,否则阻塞在button_waitq队列上。
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
else
wait_event_interruptible(button_waitq, event_flag);
}
event_flag
= 0;
err
= copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));
return err ? -EFAULT : min(sizeof(key_values), count);
}
static struct file_operations key_device_fops =
{
.owner
= THIS_MODULE,
.open
= s3c6410_key_open,
.release
= s3c6410_keys_close,
.read
= s3c6410_keys_read,
};
static int __init key_device_init(void)
{
int ret;
printk (
"<0>key init\n");
//注册字符设备
ret = register_chrdev(DEVICE_MAJOR,DEVICE_NAME,&key_device_fops);
if (ret <0)
{
printk (
"<0>register %s char dev error\n","key");
return -1;
}
printk (
"<0>success\n");
return 0;
}
static void __exit key_device_exit(void)
{
//注销设备
unregister_chrdev(DEVICE_MAJOR,DEVICE_NAME);
printk (
"<0>module exit\n");
}
module_init(key_device_init);
module_exit(key_device_exit);
MODULE_LICENSE(
"GPL");
MODULE_AUTHOR(
"hebaichuan");

测试程序,按6键退出死循环。



#include
#include

#include

#include

#define key_exit 5
int main(int argc, char **argv)
{
int fd,ret,i,key_value[6];

fd
= open("/dev/key_device",0);
if(fd<0)
{
printf(
"open devie error\n");
return -1;
}
while(1)
{
ret
= read(fd,key_value, sizeof(key_value));
if(ret<0)
{
printf(
"read error\n");
continue;
}
else if(!key_value[key_exit])
exit(
0);
for(i=0;i<5;i++)
{
if(key_value[i])
{
printf(
"KEY%d released\n",(i+1),key_value[i]);
}
else
{
printf(
"KEY%d pressed \n",(i+1),key_value[i]);
}
}
printf(
"----------------key event----------------\n");
}
close(fd);
return 0;
}

 运行结果:

bubuko.com,布布扣


推荐阅读
  • 在基于.NET框架的分层架构实践中,为了实现各层之间的松散耦合,本文详细探讨了依赖注入(DI)和控制反转(IoC)容器的设计与实现。通过合理的依赖管理和对象创建,确保了各层之间的单向调用关系,从而提高了系统的可维护性和扩展性。此外,文章还介绍了几种常见的IoC容器实现方式及其应用场景,为开发者提供了实用的参考。 ... [详细]
  • 题目链接:http://poj.org/problem?id=3083。题目描述:给定一个迷宫,其中 'S' 表示起点,'E' 表示终点,'#' 表示墙壁,'.' 表示可通行的道路。起点和终点均位于迷宫的边界上,并且保证存在唯一路径。任务是求从起点 'S' 到终点 'E' 的最短路径步数,且优先考虑向左转弯。通过深度优先搜索(DFS)和广度优先搜索(BFS)算法进行路径探索,分析两种方法的优劣及适用场景。 ... [详细]
  • 在BZOJ 2563中,阿狸与桃子进行了一场策略博弈游戏。该问题的时间限制为3秒,内存限制为128MB,目前已有97次提交记录。通过对游戏规则和策略的深入分析,本文探讨了双方在不同情况下的最优决策路径,并提出了高效的算法解决方案。 ... [详细]
  • 在多堆石子游戏中,通过分析Nim博弈策略,探讨了如何在限定时间和内存条件下实现最优解。本文详细研究了石子游戏中的数学原理和算法优化方法,旨在为参与者提供有效的策略指导。具体而言,文章讨论了不同堆数下的Nim值计算及其应用,帮助玩家在复杂的博弈环境中取得优势。 ... [详细]
  • 在Python编程中,探讨了并发与并行的概念及其区别。并发指的是系统同时处理多个任务的能力,而并行则指在同一时间点上并行执行多个任务。文章详细解析了阻塞与非阻塞操作、同步与异步编程模型,以及IO多路复用技术的应用。通过模拟socket发送HTTP请求的过程,展示了如何创建连接、发送数据和接收响应,并强调了默认情况下socket的阻塞特性。此外,还介绍了如何利用这些技术优化网络通信性能和提高程序效率。 ... [详细]
  • ASP11:深入解析与应用展望本文详细探讨了 ASP11 中的 `AppRelativeTemplateSourceDirectory` 属性,该属性用于获取或设置包含控件的 Page 或 UserControl 对象的应用程序相对虚拟目录。此外,文章还介绍了 1.0 版本中的 Binding 机制,分析了其在实际开发中的应用和优化方法,为开发者提供了全面的技术指导。 ... [详细]
  • C#中实现高效UDP数据传输技术
    C#中实现高效UDP数据传输技术 ... [详细]
  • Spring Security 认证模块的项目构建与初始化
    本文详细介绍了如何构建和初始化Spring Security认证模块的项目。首先,通过创建一个分布式Maven聚合工程,该工程包含四个模块,分别为core、browser(用于演示)、app等,以构成完整的SeehopeSecurity项目。在项目构建过程中,还涉及日志生成机制,确保能够输出关键信息,便于调试和监控。 ... [详细]
  • 如何在IDEA中安装和配置反编译插件以提高代码审查效率
    在 IntelliJ IDEA 中提升代码审查效率的一种方法是安装和配置反编译插件。首先,进入 IDEA 的设置界面,然后导航到插件管理部分。接下来,搜索 "ideaJad" 插件并进行安装。安装完成后,重启 IDEA 以确保插件生效。这将帮助你在审查二进制文件时更加高效地查看源代码。 ... [详细]
  • 深入解析 OpenCV 2 中 Mat 对象的类型、深度与步长属性
    在OpenCV 2中,`Mat`类作为核心组件,对于图像处理至关重要。本文将深入探讨`Mat`对象的类型、深度与步长属性,这些属性是理解和优化图像操作的基础。通过具体示例,我们将展示如何利用这些属性实现高效的图像缩小功能。此外,还将讨论这些属性在实际应用中的重要性和常见误区,帮助读者更好地掌握`Mat`类的使用方法。 ... [详细]
  • 通过优化模板消息机制,本研究提出了一种高效的信息化推送方案。该方案利用获取的访问令牌(access token)和指定的模板ID,实现了精准且快速的信息推送,显著提升了用户体验和信息传递效率。具体实现中,通过调用相关API接口,确保了消息的准确性和及时性,为用户提供更加便捷的服务。 ... [详细]
  • 在ASP.NET MVC项目中,通过实战解决了Ajax请求500错误及多表数据查询的问题。具体而言,将页面分为两个部分,用户点击右侧导航栏时,通过Ajax请求动态加载数据,并在右侧显示相应的页面内容。最初尝试使用Partial Action方法,但遇到了500错误。通过详细排查和调试,最终成功解决了这一问题,并实现了预期功能。此外,还优化了多表数据查询的性能,确保系统的高效运行。 ... [详细]
  • Spring Batch 异常处理与任务限制优化策略 ... [详细]
  • 优化后的标题:数据网格视图(DataGridView)在应用程序中的高效应用与优化策略
    在应用程序中,数据网格视图(DataGridView)的高效应用与优化策略至关重要。本文探讨了多种优化方法,包括但不限于:1)通过合理的数据绑定提升性能;2)利用虚拟模式处理大量数据,减少内存占用;3)在格式化单元格内容时,推荐使用CellParsing事件,以确保数据的准确性和一致性。此外,还介绍了如何通过自定义列类型和优化渲染过程,进一步提升用户体验和系统响应速度。 ... [详细]
  • 我正在使用 Ruby on Rails 构建个人网站。总体而言,RoR 是一个非常出色的工具,它提供了丰富的功能和灵活性,使得创建自定义页面变得既高效又便捷。通过利用其强大的框架和模块化设计,我可以轻松实现复杂的功能,同时保持代码的整洁和可维护性。此外,Rails 的社区支持也非常强大,为开发过程中遇到的问题提供了丰富的资源和解决方案。 ... [详细]
author-avatar
zhaobo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有