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. 微博开放平台api使用

    前言:微博开放平台提供了微博数据的api接口,不仅可以直接通过api调用微博服务发布微博查询微博,更重要的是,可以在自己的网站上获得新浪微博api的授权,调用微博的某些内容,就好像我们再网站中看到好文 ...

  2. OC中的那些String

    /--------操作字符串--NSString(静态字符串)--------------------- NSString * a = @"a+b+c+a+b+d"; NSArra ...

  3. spring 另开线程时的注入问题

    spring web项目在启动的时候,就会完成各种组件的注入.在工作的过程中,遇到了这样一个问题: 一个serviceA中要新开一个线程来执行一项任务(假定这个任务是ClassA).ClassA中要用 ...

  4. 7. ensemble learning & AdaBoost

    1. ensemble learning 集成学习 集成学习是通过构建并结合多个学习器来完成学习任务,如下图: 集成学习通过将多个学习学习器进行结合,常可以获得比单一学习器更优秀的泛化性能 从理论上来 ...

  5. Instsrv.exe和Srvany.exe的使用方法

    要把应用程序添加为服务,你需要两个小软件:Instsrv.exe和Srvany.exe.Instsrv.exe可以给系统安装和删除服务,Srvany.exe可以让程序以服务的方式运行.这两个软件都包含 ...

  6. 关于CLR、CIL、CTS、CLS、CLI、BCL和FCL

    如果要想深入学习.NET平台,那么标题中的这些关键字对你来说并不陌生,这些名词构成了.NET庞大的生态系统,为了宏观认识.NET平台,学些.NET架构体系,针对一些常用常用名词的理解是很有必要的,未必 ...

  7. devexpress treelist 过滤

    FilterMode.Smart 问题:dev 的treelist加过滤条件后,如果根节点不符合条件,则不显示数据 处理方法:把filterMode设置为smart即可. 备忘.

  8. js 简易的分页器插件

    1.自己引入jquery插件,我的demo是引入的自己本地的query <!DOCTYPE html> <html> <head> <meta charset ...

  9. LoadRunner连接Genymotion

  10. hp-pa安装oracle和bash

    一.安装oracle数据库 安装之前先进行环境检查: 1.检查系统版本 #uname -a 2.查看内存大小 #/usr/contrib/bin/machinfo | grep -i Memory 3 ...