disable_irq与disable_irq_nosync使用场景
    Linux设备驱动,关于中断屏蔽有两个接口:disable_irq和disable_irq_nosync,该两接口使用场景如下:
 
    1、disable_irq:在非中断处理函数中使用,会阻塞;
    2、disable_irq_nosync:在中断处理函数中使用,不会阻塞;用于屏蔽相应中断;
 
 一、为什么要屏蔽中断?  
    使能中断后,一旦触发中断,系统会进入中断处理函数;如果下一个中断触发的时候,前一个中断处理函数已经完成,这是理想状态,不会发生异常;如果前一个中断处理函数还未完成,那么就会导致中断嵌套。为了不出现中断嵌套,必须在中断处理函数中屏蔽中断,待中断处理完成后,再主动使能中断
 
 
二、disable_irq不能放在中断处理函数中
    如果在中断处理函数中使用disable_irq屏蔽相应中断,系统将会出现死锁状态,最后死机,然后重启。(已验证)
 
三、enable_irq配套使用
    当中断处理函数已经完成所有工作,在返回之前需要主动调用接口enable_irq使能中断,否则该中断将一直被屏蔽。(已验证)
 
 
四、附上距离传感器中断处理处理函数
 
//PS中断处理
static irqreturn_t ltr559_irq_handler(int irq, void *arg)
{
struct ltr559_data *data = (struct ltr559_data *)arg;

//printk("%s\n",__func__);

if (NULL == data)
return IRQ_HANDLED;

//后面必须有使能中断
disable_irq_nosync(data->irq);
//屏蔽中断,不会造成死锁
schedule_delayed_work(&data->ps_work, 0);
//调用延时工作队列
return IRQ_HANDLED;
}
 
 

//PS工作任务
//重要接口
static void ltr559_ps_work_func(struct work_struct *work)
{
struct ltr559_data *data = container_of(work, struct ltr559_data, ps_work.work);
struct i2c_client *client=data->client;
int als_ps_status;
int psval_lo, psval_hi, psdata;
static u32 ps_state_last = 2;
//Far as default.

mutex_lock(&data->op_lock);

als_ps_status = i2c_smbus_read_byte_data(client, LTR559_ALS_PS_STATUS);
//printk("%s ps_open_state=%d, als_ps_status=0x%x\n",__func__,data->ps_open_state,als_ps_status);
if (als_ps_status < 0)
goto workout;
/* Here should check data status,ignore interrupt status. */
/* Bit 0: PS Data
* Bit 1: PS interrupt
* Bit 2: ASL Data
* Bit 3: ASL interrupt
* Bit 4: ASL Gain 0: ALS measurement data is in dynamic range 2 (2 to 64k lux)
*                 1: ALS measurement data is in dynamic range 1 (0.01 to 320 lux)
*/

//使能情况
if ((data->ps_open_state == 1) && (als_ps_status & 0x02)) {
psval_lo = i2c_smbus_read_byte_data(client, LTR559_PS_DATA_0);
if (psval_lo < 0) {
psdata = psval_lo;
goto workout;
}
psval_hi = i2c_smbus_read_byte_data(client, LTR559_PS_DATA_1);
if (psval_hi < 0) {
psdata = psval_hi;
goto workout;
}
psdata = ((psval_hi & 7) << 8) | psval_lo;
printk("%s: psdata=%d(0x%x), near_thrd=%u, far_thrd=%u, dynamic_noise=%u\n",
  __func__, psdata, (u32)psdata, data->platform_data->prox_threshold,
  data->platform_data->prox_hsyteresis_threshold, data->dynamic_noise);

if(psdata >= data->platform_data->prox_threshold){

data->ps_state = 0; //near
ltr559_set_ps_threshold(client, LTR559_PS_THRES_LOW_0, data->platform_data->prox_hsyteresis_threshold);
ltr559_set_ps_threshold(client, LTR559_PS_THRES_UP_0, 0x07ff);
printk("%s: near, update near_thrd=%u, far_thrd=%u\n",
  __func__, 0x7ff, data->platform_data->prox_hsyteresis_threshold);
} else if (psdata <= data->platform_data->prox_hsyteresis_threshold){
data->ps_state = 1; //far

//该宏已经定义
#if defined(CONFIG_PICCOLO_COMMON)
  if (data->dynamic_noise > 20 && psdata < (data->dynamic_noise - 50) ) {
 data->dynamic_noise = psdata;
 if(psdata < 100) {
 }else if(psdata < 200){
 data->platform_data->prox_threshold = psdata+230;
 data->platform_data->prox_hsyteresis_threshold = psdata+180;
 }else if(psdata < 500){
 data->platform_data->prox_threshold = psdata+280;
 data->platform_data->prox_hsyteresis_threshold = psdata+230;
 }else if(psdata < 1500){
 data->platform_data->prox_threshold = psdata+420;
 data->platform_data->prox_hsyteresis_threshold = psdata+350;
 }else{  
 data->platform_data->prox_threshold= 1800;
 data->platform_data->prox_hsyteresis_threshold= 1700;
 pr_err("ltr559 the proximity sensor rubber or structure is error!\n");
 }
 printk("%s: NEW prox_threshold=%u, prox_hsyteresis_threshold=%u !!!\n",
__func__, data->platform_data->prox_threshold,
    data->platform_data->prox_hsyteresis_threshold);
  }
#endif

ltr559_set_ps_threshold(client, LTR559_PS_THRES_LOW_0, 0);
ltr559_set_ps_threshold(client, LTR559_PS_THRES_UP_0, data->platform_data->prox_threshold);
printk("%s: far, update near_thrd=%u, far_thrd=0\n",
  __func__, data->platform_data->prox_threshold);
} else {
data->ps_state = ps_state_last;
}

printk("%s: ps_state_last = %u, ps_state = %u\n", __func__, ps_state_last, data->ps_state);
if((ps_state_last != data->ps_state) || (data->ps_state == 0)) //need report the input event constant when near 
{
//上报数据
input_report_abs(data->input_dev_ps, ABS_DISTANCE, data->ps_state);
input_sync(data->input_dev_ps);
printk("%s: report ABS_DISTANCE=%s\n",__func__, data->ps_state ? "far" : "near");

ps_state_last = data->ps_state; 
//Report ABS value only if the state changed.
}
else
printk("%s: ps_state still %s\n", __func__, data->ps_state ? "far" : "near");
}
workout:
enable_irq(data->irq);
//使能
irq
mutex_unlock(&data->op_lock);
//解锁
}

disable_irq与disable_irq_nosync使用场景的更多相关文章

  1. disable_irq()与disable_irq_nosync()区别

    disable_irq关闭中断并等待中断处理完后返回, 而disable_irq_nosync立即返回.

  2. 【转】中断处理函数中不用disable_irq而用disable_irq_nosync原因

    原文网址:http://blog.csdn.net/skyflying2012/article/details/8265869 今天在写触摸屏驱动时在中断处理函数中使用disable_irq关中断发现 ...

  3. 中断处理函数中不用disable_irq而用disable_irq_nosync原因【转】

    转自:http://blog.csdn.net/beyondioi/article/details/9201695 今天在写触摸屏驱动时在中断处理函数中使用disable_irq关中断发现在进入中断处 ...

  4. Linux内核设计与实现 读书笔记

    第三章 进程管理 1. fork系统调用从内核返回两次: 一次返回到子进程,一次返回到父进程 2. task_struct结构是用slab分配器分配的,2.6以前的是放在内核栈的栈底的:所有进程的ta ...

  5. kernel笔记——中断

    cpu与磁盘.网卡.键盘等外围设备(相对于cpu和内存而言)交互时,cpu下发I/O请求到这些设备后,相对cpu的处理能力而言,磁盘.网卡等设备需要较长时间完成请求处理. 那么在请求发出到处理完成这段 ...

  6. Linux设备驱动 之 中断处理程序

    注册中断处理程序 中断处理程序是管理硬件驱动程序的组成部分:如果设备使用中断,那么相应的驱动程序就注册一个中断处理程序: 驱动程序通过request_irq()函数注册,并且激活给定的中断线,以处理中 ...

  7. local_irq_disable和disable_irq的区别

    local_irq_disable: local_irq_disable的功能是屏蔽当前CPU上的所有中断,通过操作arm核心中的寄存器来屏蔽到达CPU上的中断,此时中断控制器中所有送往该CPU上的中 ...

  8. 拨开迷雾,找回自我:DDD 应对具体业务场景,Domain Model 到底如何设计?

    写在前面 除了博文内容之外,和 netfocus 兄的讨论,也可以让你学到很多(至少我是这样),不要错过哦. 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领 ...

  9. [NodeJS] 优缺点及适用场景讨论

    概述: NodeJS宣称其目标是“旨在提供一种简单的构建可伸缩网络程序的方法”,那么它的出现是为了解决什么问题呢,它有什么优缺点以及它适用于什么场景呢? 本文就个人使用经验对这些问题进行探讨. 一. ...

随机推荐

  1. IO复用三种方式

    简介 IO复用技术,简单来说就是同时监听多个描述符.在没有用到IO复用以前,只能是一个线程或一个 线程去监听,服务端同时有多个连接的时候,需要创建多个线程或者进程.而且,并不是所有的连 接是一直在传输 ...

  2. bootstrap 部分css样式

    clip: rect(0, 0, 0, 0);剪裁绝对定位元素.outline: 0; cursor: not-allowed;

  3. goprotocbuf的安装和使用

    首先得到 protobuf 相应的包文件 ,在终端上输入如下 wget http://protobuf.googlecode.com/files/protobuf-2.5.0.tar.gz 下载完毕后 ...

  4. Quartz2D 编程指南(三)渐变、透明层 、数据管理

    概览 图形上下文 路径 颜色与颜色空间 变换 图案 阴影 渐变 透明层 Quartz 2D 中的数据管理 位图与图像遮罩 CoreGraphics 绘制 Layer 渐变 简介 渐变是从一个颜色到另外 ...

  5. laravel5.1学习(2)-- artisan tinker命令

    例如:为users表创建20条测试输入 G:\wamp\www\hcmf>php artisan tinker >>> namespace App; => null &g ...

  6. 20145320GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 在这里首先感谢卢肖明的分析博客,为后面的同学减少了很多分析的负担. 分析过程 使用gcc - g example.c -o example -m32指令在64位的机器上产生 ...

  7. Sprint

    Sprint冲刺 1.选题 <寿司点餐系统> 2.app名 <Sushi> 3.团名 ZEG 4.目标 制作一个成型的人性化的寿司点餐系统,介绍各种寿司的材料做法吃法以及价格, ...

  8. 记得初学JS时候练个九九乘法表都写的要死要活

    还记得当初刚接触JS时候,看到视频中老师写了个九九乘法表,觉得好神奇,可是自己在下面动手写了半天还是有各种问题,甚是懊恼啊.今又看到园子里有关于乘法表的博文,出于对过去的不舍与缅怀,遂重写一遍. &l ...

  9. 基础编程-java之股神

    买了一支股票,他知道从他买股票的那天开始,股票会有以下变化:第一天不变,以后涨一天,跌一天,涨两天,跌一天,涨三天,跌一天...依此类推. 为方便计算,假设每次涨和跌皆为1,股票初始单价也为1,请计算 ...

  10. 使用Cobbler无人值守安装CentOS6.5(一)

    Cobbler是一个快速网络安装linux的服务,而且在经过调整也可以支持网络安装windows.该工具使用python开发,小巧轻便(才15k行代码),使用简单的命令即可完成PXE网络安装环境的配置 ...