驱动笔记 - 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 写在前面的话: 博主新开了个人站点:你也可以在这里看到这篇文章,点击打开链接 本文是 ...
随机推荐
- mac 上运行httpserver的问题
如果你的系统是window 我建议你安装http-server 非常好用, 如果是mac,系统自带的就有httpserver 服务,没有必要在安装 按照我说的来操作 首先 sudo apachectl ...
- canvas-tangram.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- blfs(systemv版本)学习笔记-编译安装ligtdm显示管理器
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! ligtdm带有显示管理器和登录器,参照我的笔记安装xorg和i3后安装lightdm,就可以组成一个简易的桌面环境了 下面是l ...
- linux基础学习之软件安装以及常用命令
linux基础学习之软件安装以及常用命令 调用中央仓库: yum install wget 然后下载nodejs: wget https://nodejs.org/dist/v10.14.2/node ...
- 在线客服兼容谷歌Chrome、苹果Safari、Opera浏览器的修改
纵览全网提供的众多号称兼容多浏览器的自动收缩在线客服,其实只兼容了IE和FF两种,当遇到谷歌Chrome.苹果Safari.Opera浏览器时鼠标还没点到客服按钮就会自动缩回,实用效果完全打折 以下代 ...
- element-ui中table表头表格错误问题解决
我用的是element-ui v1.4.3 在iframe关闭和切换导航会引起有table的表格错位,解决办法: handleAdminNavTab: function(tab) { var admi ...
- 探讨PHP页面跳转几种实现技巧 转自# 作者:佚名 来源:百度博客 #
Web系统中,从一个网页跳转到另一个网页,是LAMP项目中最常用的技术之一.页面跳转可能是由于用户单击链接.按钮等引发的,也可能是系统自动产生的. 此处介绍PHP中常用的实现页面自动跳转的方法. PH ...
- JS性能优化 之 文档片段 createDocumentFragment
我们用原生JS进行开发时,经常会用到两种更新DOM节点的方法:innerHTML 和 appendChild() .其中 innerHTML 会完全替换掉原先的节点内容,如果我们是想向元素追加子节点的 ...
- CentOS7系列--安装Chrome浏览器
CentOS7系列--安装Chrome浏览器 1. 创建yum源文件 [root@server20 ~]# cd /etc/yum.repos.d/ [root@server20 yum.repos. ...
- Windows下使用Rtools编译R语言包
使用devtools安装github中的R源代码时,经常会出各种错误,索性搜了一下怎么在Windows下直接打包,网上的资料也是参差不齐,以下是自己验证通过的. 一.下载Rtools 下载地址:htt ...