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中断程序的更多相关文章

  1. 《linux设备驱动开发详解》笔记——10中断与时钟

    10.1 中断与定时器 中断一般有如下类型: 内部中断和外部中断:内部中断来自CPU,例如软件中断指令.溢出.除0错误等:外部中断有外部设备触发 可屏蔽中断和不可屏蔽中断 向量中断和非向量中断,ARM ...

  2. Linux 设备驱动开发 —— platform设备驱动应用实例解析

    前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 —— platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...

  3. 入门级的按键驱动——按键驱动笔记之poll机制-异步通知-同步互斥阻塞-定时器防抖

    文章对应视频的第12课,第5.6.7.8节. 在这之前还有查询方式的驱动编写,中断方式的驱动编写,这篇文章中暂时没有这些类容.但这篇文章是以这些为基础写的,前面的内容有空补上. 按键驱动——按下按键, ...

  4. linux 2.6 驱动笔记(一)

    本文作为linux 2.6 驱动笔记,记录环境搭建及linux基本内核模块编译加载. 环境搭建: 硬件:OK6410开发板 目标板操作系统:linux 2.6 交叉编译环境:windows 7 + v ...

  5. stm32学习笔记——外部中断的使用

    stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...

  6. Linux中断程序命令

    在运行 python 脚本的时候想要中断程序,发现如下情况: ctrl+c 居然无法中断程序! 这时候尝试 ctrl+d 还是毫无效果,最后尝试 ctrl+\: 查看该程序是否还在运行 ps aux ...

  7. 嵌入式Linux驱动笔记(十八)------浅析V4L2框架之ioctl【转】

    转自:https://blog.csdn.net/Guet_Kite/article/details/78574781 权声明:本文为 风筝 博主原创文章,未经博主允许不得转载!!!!!!谢谢合作 h ...

  8. c语言编写51单片机中断程序,执行过程是怎样的?

    Q:c语言编写51单片机中断程序,执行过程是怎样的? 例如程序:#include<reg52.h>  void main(void)  {   EA=1;      //开放总中断   E ...

  9. 从串口驱动的移植看linux2.6内核中的驱动模型 platform device & platform driver【转】

    转自:http://blog.csdn.net/bonnshore/article/details/7979705 写在前面的话: 博主新开了个人站点:你也可以在这里看到这篇文章,点击打开链接 本文是 ...

随机推荐

  1. vue中使用axios(异步请求)和mock.js 模拟虚假数据

    一.使用axios 1.安装 npm install --save axios 2.引用 import Axios from 'axios' Vue.prototype.Axios = Axios 二 ...

  2. python之初始面向对象

    1. 初识面向对象  面向过程: 一切以事务的发展流程为中心. 面向对象: 一切以对象为中心. 一切皆为对象. 具体的某一个事务就是对象 2. 类. 对象 类: 就是图纸. 创建对象的第一步. 先画图 ...

  3. Oracle 启动实例(instance)、打开数据库

    Oracle启动实例(instance).打开数据库   by:授客 QQ:1033553122 启动实例(instance).打开数据库 1.开启sqlplus [laiyu@localhost ~ ...

  4. Android之ProgressDialog的使用

    ProgressDialog 继承自AlertDialog,AlertDialog继承自Dialog,实现DialogInterface接口. ProgressDialog的创建方式有两种,一种是ne ...

  5. 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解

    今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...

  6. 简单易懂的程序语言入门小册子(1):基于文本替换的解释器,lambda演算

    最近比较闲,打算整理一下之前学习的关于程序语言的知识.主要的内容其实就是一边设计程序语言一边写解释器实现它.这些知识基本上来自Programming Languages and Lambda Calc ...

  7. MySql数据库基础笔记(一)

    一.表与库的概念 数据库管理数据,它是以什么样的形式组成的? 生活中的表---->表 table多行多列,传统的数据库都是这样的;声明了表头,一个表创建好了,剩下的就是往表中添加数据 多张表放在 ...

  8. ECstore后台报表显示空白问题解决办法

    执行如下sql语句: INSERT INTO `sdb_ectools_analysis` (`id`, `service`, `interval`, `modify`) VALUES (1, 'b2 ...

  9. 【学习笔记】cache/buffer

    cache 是为了弥补高速设备和低速设备的鸿沟而引入的中间层,最终起到**加快访问速度**的作用.buffer 的主要目的进行流量整形,把突发的大数量较小规模的 I/O 整理成平稳的小数量较大规模的 ...

  10. HTML5原生拖拽事件的值传递(三dataTransfer对象)

    引用一篇博客,讲解的比较详细:http://www.tuicool.com/articles/j6Zbam