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. canvas-2rect.html

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 文件夹生成zip

    package com.leoodata.utils; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.Zi ...

  3. 10个最佳 Javascript+HTML5 演示文稿框架

    JavaScript 与 HTML5 框架在创建基于现代浏览器的演示文稿时发挥了重要作用.他们把展示插入网页,为演示信息提供了一个有效方式.一般来说,手工插入花费大量事件和精力,它很复杂,以至于新手们 ...

  4. 【读书笔记】iOS-分类与协议

    分类与协议是Object-C特有概念,分类(Category)可以认为是一种继承性的扩展,而协议(Protocol)可以理解为Java中的Interface(接口)或者C++的纯虚类. 参考资料:&l ...

  5. 安卓开发_关于WebView加载页面空白问题

    依据我自己的测试,发现有时候用APP打开网页的时候,有的网页加载成功之前需要很久,有的一下就出来了(比如百度) 当加载时间过长的情况下,这时候显示的是空白界面,其实不是代码问题,只是要打开的这个网页太 ...

  6. 你不可不知的Java引用类型之——弱引用

    定义 弱引用是使用WeakReference创建的引用,弱引用也是用来描述非必需对象的,它是比软引用更弱的引用类型.在发生GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收. 说明 弱 ...

  7. js replace替换 忽略大小写问题

    实现就是控制台的内容“abc”,但是后台返回的是“ABC”,这个时候在前台遍历,需要将后台返回的在控制台标红. 当然控制台可以是 abc Abc等大小写混合,以下代码都可替换. var flagnew ...

  8. 12、多线程:Threading、守护线程

    线程与进程: 线程对于进程来说,就好似工厂里的工人,分配资源是分配到工厂,工人再去处理. 线程是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属 ...

  9. django静态文件

    django静态文件(js脚本.CSS.图片等) 默认统一放在每一个app的static文件夹下, 通过收集静态文件命令,自动将每一个app下static文件夹下的文件复制到根目录的static文件夹 ...

  10. 探索哪个进程使磁盘I/O升高

    如果生产环境中磁盘使用率突然升高,却不知道因为哪个应用程序导致的,这个时候我们可以使用pidstat命令来查看,比如 Linux .el7.x86_64 (ip.ec2.internal) _x86_ ...