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. 关于 ul 嵌套 li 并且再嵌套 a 的 BUG

    在写网页的过程中,总是写完了这一套,样式出了问题又去找问题废了好长时间总结一下写法以下是结构 经常会出现 li 里面与文字不在一个高度上 <div class="indicators& ...

  2. 【读书笔记】iOS-访问iPod媒体库

    iOS设备内部都有一个iPod媒体库,在这个媒体库中包含了音频和视频文件,它的来源主要是苹果公司的iTunes Store,现在苹果公司的iTunes Store内容很多,但能够下载到iPod媒体库的 ...

  3. for each....in、for in、for of

    一.一般的遍历数组的方法: var array = [1,2,3,4,5,6,7]; for (var i = 0; i < array.length; i) { console.log(i,a ...

  4. web全栈架构师[笔记] — 03 html5新特性

    HTML5新特性 一.geolocation PC端 精度比较低 通过IP库定位 移动端 通过GPS window.navigator.geolocation 单次 getCurrentPositio ...

  5. loadrunner 场景设计-添加Unix、Linux Resources计数器

    场景设计-添加Unix.Linux Resources计数器 by:授客 QQ:1033553122 A.   目的 监控要测试的Unix.Linux服务器的资源使用情况 Linux CentOS为例 ...

  6. Mongodb的入门(8)mongodb事物分析

    老生常谈:<在前面博客中也介绍过> mongodb官网:https://docs.mongodb.com/manual/introduction/ mongodb:官网上是这样定义的Mon ...

  7. 根据id来大量删除数据between

    id的范围来删除数据 比如要删除 110到220的id信息:delete id from 表名 where id between 110 and 220;

  8. 基于Python的频谱分析(一)

    1.傅里叶变换  傅里叶变换是信号领域沟通时域和频域的桥梁,在频域里可以更方便的进行一些分析.傅里叶主要针对的是平稳信号的频率特性分析,简单说就是具有一定周期性的信号,因为傅里叶变换采取的是有限取样的 ...

  9. https://www.testingcircus.com/tell-me-about-yourself-6-sample-answers-software-testers/

    https://www.testingcircus.com/tell-me-about-yourself-6-sample-answers-software-testers/ Tell Me Abou ...

  10. myeclipce项目导入eclipse中报错

    1 找到新建页面所在的工程名字,然后左键选中,右键弹出功能菜单,选择Build Path,进入配置路径. 2 在java build path 页面的下选择Libraries栏目(默认选择),点击右侧 ...