驱动笔记 - platform中断程序
platform_device:
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/io.h> #define DEVICE_NAME "ok6410_plat_btn" /*平台资源的定义,按键中断*/
static struct resource s3c_buttons_resource[] = {
[0]={
.start = IRQ_EINT(0),
.end = IRQ_EINT(0),
.flags = IORESOURCE_IRQ,
},
[1]={
.start = IRQ_EINT(1),
.end = IRQ_EINT(1),
.flags = IORESOURCE_IRQ,
},
[2]={
.start = IRQ_EINT(2),
.end = IRQ_EINT(2),
.flags = IORESOURCE_IRQ,
},
[3]={
.start = IRQ_EINT(3),
.end = IRQ_EINT(3),
.flags = IORESOURCE_IRQ,
},
[4]={
.start = IRQ_EINT(4),
.end = IRQ_EINT(4),
.flags = IORESOURCE_IRQ,
},
[5]={
.start = IRQ_EINT(5),
.end = IRQ_EINT(5),
.flags = IORESOURCE_IRQ,
}
}; static struct platform_device *s3c_buttons; static int __init platform_init(void)
{ s3c_buttons = platform_device_alloc(DEVICE_NAME,-1); //为平台设备s3c_buttons添加平台资源
platform_device_add_resources(s3c_buttons,&s3c_buttons_resource,6); /*平台设备的注册*/
platform_device_add(s3c_buttons); } static void __exit platform_exit(void)
{
platform_device_unregister(s3c_buttons);
} module_init(platform_init);
module_exit(platform_exit); MODULE_AUTHOR("Sola");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ok6410_buttons");
platform_driver:
#include <linux/module.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <mach/map.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/unistd.h>
#include <linux/device.h> #define DRIVER_NAME "ok6410_plat_btn" //定义并初始化等待队列头
static DECLARE_WAIT_QUEUE_HEAD(button_waitq); static volatile int ev_press = 0; static int key_value;
static struct device *buttons_dev; /* platform device attached to */
static struct resource *buttons_irq; static int button_irqs[6];//中断号 /*按键中断处理函数*/
static irqreturn_t buttons_interrupt(int irq, void *dev_id)
{
int i;
for(i=0; i<6; i++){
if(irq == button_irqs[i]){
//printk("==>interrput number:%d\n",irq);
key_value = i;
ev_press =1;
wake_up_interruptible(&button_waitq);
}
} return IRQ_RETVAL(IRQ_HANDLED); } static int s3c6410_buttons_open(struct inode *inode, struct file *file)
{
int i;
int err = 0;
/*注册中断*/
for(i=0; i<6; i++){
if (button_irqs[i] < 0)
continue; /*中断触发方式:下降沿触发,中断接口函数*/
err = request_irq(button_irqs[i],buttons_interrupt,IRQF_TRIGGER_FALLING,NULL,NULL);
if(err)
break;
} if (err) {
i--;
for (; i >= 0; i--) {
if (button_irqs[i] < 0) {
continue;
}
disable_irq(button_irqs[i]);
free_irq(button_irqs[i], NULL);
}
return -EBUSY;
} ev_press = 0;
return 0;
} static int s3c6410_buttons_close(struct inode *inode, struct file *file)
{
int i;
for (i=0; i<6; i++) {
if (button_irqs[i] < 0) {
continue;
}
free_irq(button_irqs[i],NULL);
}
return 0;
} static int s3c6410_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
unsigned long err;
if (!ev_press) {//如果键没有被按下
if (filp->f_flags & O_NONBLOCK)//如果是非阻塞模式,就直接返回
return -EAGAIN;
else
//阻塞,直到按键按下
wait_event_interruptible(button_waitq, ev_press);
}
ev_press = 0; //将键值送回到用户空间
err = copy_to_user(buff, &key_value, sizeof(key_value));
return sizeof(key_value);
} static unsigned int s3c6410_buttons_poll( struct file *file, struct poll_table_struct *wait)
{
unsigned int mask = 0;
poll_wait(file, &button_waitq, wait);//添加等待队列头
if (ev_press){
mask |= POLLIN | POLLRDNORM;
} //返回掩码
return mask;
} static struct file_operations ok6410_buttons_fops = {
.owner = THIS_MODULE,
.open = s3c6410_buttons_open,
.release = s3c6410_buttons_close,
.read = s3c6410_buttons_read,
.poll = s3c6410_buttons_poll,
}; //声明一个混杂设备,设备名称为"buttons"
static struct miscdevice ok6410_miscdev = { .minor = MISC_DYNAMIC_MINOR,
.name ="buttons",
.fops = &ok6410_buttons_fops,//操作集
}; /* device interface ,当发现匹配设备时会调用此函数*/
static int ok6410_buttons_probe(struct platform_device *pdev)
{
struct resource *res;
struct device *dev;
int ret;
int size;
int i; printk("probe:%s\n", __func__);
dev = &pdev->dev;
buttons_dev = &pdev->dev; /*平台资源获取*/
/*get irq number*/
for(i=0; i<6; i++){
//获取中断号
buttons_irq = platform_get_resource(pdev,IORESOURCE_IRQ,i);
if(buttons_irq == NULL){
dev_err(dev,"no irq resource specified\n");
ret = -ENOENT;
return ret;
}
button_irqs[i] = buttons_irq->start;
//printk("button_irqs[%d]=%d\n",i,button_irqs[i]);
} //注册混杂设备
ret = misc_register(&ok6410_miscdev); return ret;
} static int ok6410_buttons_remove(struct platform_device *dev)
{ misc_deregister(&ok6410_miscdev);
return 0;
} /*平台驱动定义*/
static struct platform_driver ok6410_buttons_driver = {
.probe = ok6410_buttons_probe,//探针函数
.remove = ok6410_buttons_remove,
.driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
},
}; static char banner[] __initdata =
"ok6410 Buttons Driver\n"; static int __init buttons_init(void)
{
printk(banner);
/*平台驱动注册*/
platform_driver_register(&ok6410_buttons_driver);
return 0;
} static void __exit buttons_exit(void)
{
//平台驱动的注销
platform_driver_unregister(&ok6410_buttons_driver);
} module_init(buttons_init);
module_exit(buttons_exit);
MODULE_LICENSE("GPL");
驱动笔记 - platform中断程序的更多相关文章
- 《linux设备驱动开发详解》笔记——10中断与时钟
10.1 中断与定时器 中断一般有如下类型: 内部中断和外部中断:内部中断来自CPU,例如软件中断指令.溢出.除0错误等:外部中断有外部设备触发 可屏蔽中断和不可屏蔽中断 向量中断和非向量中断,ARM ...
- Linux 设备驱动开发 —— platform设备驱动应用实例解析
前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 —— platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...
- 入门级的按键驱动——按键驱动笔记之poll机制-异步通知-同步互斥阻塞-定时器防抖
文章对应视频的第12课,第5.6.7.8节. 在这之前还有查询方式的驱动编写,中断方式的驱动编写,这篇文章中暂时没有这些类容.但这篇文章是以这些为基础写的,前面的内容有空补上. 按键驱动——按下按键, ...
- linux 2.6 驱动笔记(一)
本文作为linux 2.6 驱动笔记,记录环境搭建及linux基本内核模块编译加载. 环境搭建: 硬件:OK6410开发板 目标板操作系统:linux 2.6 交叉编译环境:windows 7 + v ...
- stm32学习笔记——外部中断的使用
stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...
- Linux中断程序命令
在运行 python 脚本的时候想要中断程序,发现如下情况: ctrl+c 居然无法中断程序! 这时候尝试 ctrl+d 还是毫无效果,最后尝试 ctrl+\: 查看该程序是否还在运行 ps aux ...
- 嵌入式Linux驱动笔记(十八)------浅析V4L2框架之ioctl【转】
转自:https://blog.csdn.net/Guet_Kite/article/details/78574781 权声明:本文为 风筝 博主原创文章,未经博主允许不得转载!!!!!!谢谢合作 h ...
- c语言编写51单片机中断程序,执行过程是怎样的?
Q:c语言编写51单片机中断程序,执行过程是怎样的? 例如程序:#include<reg52.h> void main(void) { EA=1; //开放总中断 E ...
- 从串口驱动的移植看linux2.6内核中的驱动模型 platform device & platform driver【转】
转自:http://blog.csdn.net/bonnshore/article/details/7979705 写在前面的话: 博主新开了个人站点:你也可以在这里看到这篇文章,点击打开链接 本文是 ...
随机推荐
- csharp: sum columns or rows in a dataTable
DataTable dt = setData(); // Sum rows. //foreach (DataRow row in dt.Rows) //{ // int rowTotal = 0; / ...
- 关于python访问字典的方法
def stu( **kwargs): # 在函数体内对于kwargs的使用不用带星号 print("大家好,我为大家简单自我介绍以下:") print(type(kwargs)) ...
- Microsoft Dynamics CRM 9.0 OP 版本 移动端
本次OP 版本做了架调整,新的移动端基本可以满足客户需求,其内容自己可配置选择,满足了一般企业的应用处理. 具体操作如下: 1.登录APP选择应用(我使用手机浏览器) 2.打开默认应用,现在就一个木得 ...
- React JS和React-Native学习指南
自己在学习React-Native过程中整理的一份学习指南,包含 教程.开源app和资源网站等,还在不断更新中.欢迎pull requests! React-Native学习指南本指南汇集React- ...
- (后端)出现org.hibernate.NonUniqueResultException的原因即解决办法
百度出来的资料解决问题: 一个问题,事务处理完毕以后页面没有刷新.刚开始以为是前台js的问题,后来检查js没有任何问题,跟踪到后台发现后台报错了,错误信息如下:org.hibernate.NonUni ...
- maven管理项目的特点
Maven介绍 我们在开发项目的过程中,会使用一些开源框架.第三方的工具等等,这些都是以jar包的方式被项目所引用,并且有些jar包还会依赖其他的jar包,我们同样需要添加到项目中,所有这些相关的ja ...
- sass @function,@for,@mixin 的应用
项目前提: 不同的汽车显示不同的图片,一共9种汽车:每种汽车显示不同状态的图片,一共6种状态,所以一共会有54张图片 后台接口返回汽车种类分别为:1-9,汽车状态分别为:0-5 项目需求: 根据后台返 ...
- LeetCode题解之Insert into a Binary Search Tree
1.题目描述 2.分析 插入算法. 3.代码 TreeNode* insertIntoBST(TreeNode* root, int val) { insert(root, val); return ...
- 【PHP调试篇】PHP高性能日志组件SeasLog
简述 什么是SeasLog SeasLog是一个C语言编写的PHP扩展,提供一组规范标准的功能函数,在PHP项目中方便.规范.高效地写日志,以及快速地读取和查询日志. 为什么使用SeasLog 无论在 ...
- tkinter中lable标签控件(二)
lable控件 对于tkinter来说,学起来很简单,只要设置好相应的参数即可出结果,所以不用刻意去记住这些参数.学习一遍后理解每个参数的作用是什么即可. 当下次用到的时候来笔记上看一下就行. 内容很 ...