点击打开链接

最近在工作中使用irq时遇到如下问题,根据log显示应该是什么所谓的不平横问题,先前也没有仔细研究这个问题,只是定位到是enable_irq函数调用所致。
因为在项目中使用的中断是gpio中断,该中断在项目中的实现方式为多个gpio中断共享一个真实的物理中断,因此当这个真实的物理中断发生后由系统(就是另一个哥们写的irq驱动)查询到底是连接到这个物理中断上的哪一个具体的gpio产生的了中断(通过gpio的寄存器位)。这个过程可以认为是一次底层的中断回调过程。在这次回调过程中,这哥们的驱动会首先屏蔽掉(disable)这个实际的物理中断,然后开始查询共享这个物理中断的所有gpio,当找到后便会调用在这个虚拟的gpio中断上用户注册的中断回调函数,这个回调函数可以理解为上层回调,当这个回调函数完毕后便返回到底层回调函数中,然后重新enable那个唯一的实际物理中断。
至此针对这个gpio的中断回调处理过程全部完成。由此我们也可以发现,对于某个使用gpio中断的驱动而言,在进出中断回调函数过程中完全可以不去关心中断的屏蔽和打开,因为驱动的回调函数(相对认为是上层的)是由底层的那个物理中断的回调函数调用的,而这个底层的中断回调函数在进出的过程中关闭和打开这个物理中断。所以我在使用过程中没有在中断处理函数的开始调用disable_irq,也没有在中断退出时调用enable_irq相关函数。程序完全可以正确执行。
测试中一个偶然的错误让我发现了一个新的知识,一次调试一个电容屏的驱动时,由于移植中没有仔细检查,发现该驱动的probe调用后总是出现如下警告,但是并不影响使用。后来检查过程中发现,是因为在probe的最后调用了一次enable_irq所致。由于我很清楚上述gpio中断的实现原理,所以放心删掉那个enable_irq动作解决了问题。
------------[ cut here ]------------
WARNING: at kernel/irq/manage.c:225 __enable_irq+0x3b/0x57()
Unbalanced enable for IRQ 4
Modules linked in: svsknfdrvr [last unloaded: osal_linux]
Pid: 634, comm: ash Tainted: G W 2.6.28 #1
Call Trace:
[<c011a7f9>] warn_slowpath+0x76/0x8d
[<c012fac8>] profile_tick+0x2d/0x57
[<c011ed72>] irq_exit+0x32/0x34
[<c010f22c>] smp_apic_timer_interrupt+0x41/0x71
[<c01039ec>] apic_timer_interrupt+0x28/0x30
[<c011b2b4>] vprintk+0x1d3/0x300
[<c013a2af>] __setup_irq+0x11c/0x1f2
[<c013a177>] __enable_irq+0x3b/0x57
[<c013a506>] enable_irq+0x37/0x54
[<c68c9156>] svsknfdrvr_open+0x5e/0x65 [svsknfdrvr]
[<c016440a>] chrdev_open+0xce/0x1a4
[<c016433c>] chrdev_open+0x0/0x1a4
[<c01602f7>] __dentry_open+0xcc/0x23a
[<c016049a>] nameidata_to_filp+0x35/0x3f
[<c016b3c5>] do_filp_open+0x16f/0x6ef
[<c0278fd5>] tty_write+0x1a2/0x1c9
[<c0160128>] do_sys_open+0x42/0xcb
[<c0160201>] sys_open+0x23/0x2a
[<c0102e71>] sysenter_do_call+0x12/0x25
---[ end trace 4eaa2a86a8e2da22 ]---

最近针对这个问题我仔细研究了以下,又学到了新东西!
中断的enable和disable一定要成对使用,否则机会被kernel检测到unbalance而发出上述警告!
也就是调用一个enable之前一定曾经调用过至少一次disable!
可以想象在disable调用后会有一个计数器被加1,而在enable调用后这个计数器会减1.从而当计数器为0的时候若调用那个enable时就会导致上述警告发生。测试中我针对某个中断连续调用相关的disable函数数次,然后再开始调用enable函数,发现当调用到大于diable次数时上述警告便会出现。这说明我的想法是对的。

由于太相信这个gpio中断在使用中可以不去主动disable和enable。也导致我犯了一个严重错误,而且费了很大劲才解决。还是要多思考啊。。。
在设计这个电容屏的驱动时,我的设计为在其suspend函数中直接切断电容屏的电源以省电,然后在resume函数中再从新上电。中断触发方式为下降沿触发方式。测试发现,当在suspend中调用断电操作后总会导致一个I2C读取动作发生,而这个读取动作是我在中断处理函数的底半部中实现的动作。仅仅是电容屏的一个断电动作怎么会导致这个动作发生呢?
想了好久,我笑了。。。。
下降沿触发嘛~~  当电容屏断电后当然没有谁去保持那个中断引脚为高电平了,它当然会恢复为默认的低电平了(该平台的中断默认为电平)。显然这个过程会导致一个下降沿发生,这便会引起中断处理函数被调用,从而引起底半部的工作队列被执行,然后I2C读取动作便发生了。可是这时候电容屏都断电了,读取当然要出错了!
好了,问题已经找到,现在的问题就是如何让这个下降沿不要发生,我靠这怎么可能?????
那就只能想办法让系统不要理会这个下降沿。咋办?
简单,断电前先disable中断,resume完成后重新enable这个中断就好了。。。哈哈
问题解决。
看来无论中断的底层怎么做,我们尽量不要图省事而减少一些必要的动作才对!
当然了,我们在自己的代码中屏掉某个gpio中断后,如果这个对应的gpio中断再次产生,底层的那个实际物理中断所注册的中断处理函数依然会运行,也依然会查询所有的gpio中断来判断到底是哪个gpio发出的中断,但是在找到这个具体的gpio后到底要不要执行这个gpio中断上注册的中断回调函数,这还要看这个gpio中断有没有被用户屏蔽掉,如果被用户屏蔽了,那么,这个底层的物理中断的回调函数就会直接返回而不会调用对应的gpio中断上注册的回调函数。基于这个原因,我在上面提到的思路才得以正确验证。

disable_irq_nosync(irq_num);
enable_irq(irq_num);

我的I2C驱动可能还有些问题,比如当用i2c_transfer函数进行传输时,如果mesgs参数包含多个消息组,而第一组消息发送时如果发生no slaver responed时,我应该放弃本次传输,并且释放总线,但是现在看来似乎没有释放总线,而且后续的传输也没有结束。这会引起一些错误,并引起延时。这个还需要进一步优化,或者找出真正的问题。

unbalanced enable irq 问题的解决 以及共享的gpio中断引起的问题相关推荐

  1. 在分布式环境中解决session共享问题

    一.什么是session session在计算机中,尤其是在网络应用中,称为"会话控制".Session对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的web页面 ...

  2. 解决局域网共享问题,提示:无法访问,你可能没有权限使用网络资源

    解决局域网共享问题,提示:无法访问,你可能没有权限使用网络资源 参考文章: (1)解决局域网共享问题,提示:无法访问,你可能没有权限使用网络资源 (2)https://www.cnblogs.com/ ...

  3. 计算机无法发现网络打印机共享,打印机共享无法打印怎么办,详细教您解决电脑打印机共享无法打印...

    办公室由于办公需要,经常要连接网络打印机,平时打印账单,表格之类的东西,但是用户在使用电脑时可能会经常碰到共享打印机和电脑连接不上,导致打印机共享无法打印的情况,那么我们该怎么办呢?下面,小编就来跟大 ...

  4. 设计模式(四)注册模式 解决:解决全局共享和交换对象

    1.注册模式: 注册模式,解决全局共享和交换对象.已经创建好的对象,挂在到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可.将对象注册到全局的树上.任何地方直接去访问. <?p ...

  5. 本文主要讲述如何开通自己的博客。若读者不想或已经知道如何开通使用博客,那么就可以跳过。 一直以来,想把自己在学习过程中遇到的问题及解决办法共享给志同道合的人,那么如何分享自己的见解呢?有如下方法

    本 本文主要讲述如何开通自己的博客.若读者不想或已经知道如何开通使用博客,那么就可以跳过. 一直以来,想把自己在学习过程中遇到的问题及解决办法共享给志同道合的人,那么如何分享自己的见解呢?有如下方法, ...

  6. 计算机管理内默认共享,善用“默认共享”便于管理。解决“这个共享是为管理而创建的。服务器服务停止并重新启动后或计算机重新...

    解决"这个共享是为管理而创建的.服务器服务停止并重新启动后或计算机重新启动后,共享会重新出现.善用"默认共享"便于管理. 今天对其中一台服务器做清理的时候发现一个问题,具 ...

  7. Enable密码丢失的解决方法

    Enable密码丢失的解决方法 一.       实验目的 1.  了解交换机enable密码丢失后重新进入交换机的方法: 2.  了解交换机Bootrom下的配置命令. 二.       应用环境 ...

  8. 张尧学院士:云计算仍未根本解决服务共享问题

    本文讲的是张尧学院士:云计算仍未根本解决服务共享问题,[IT168 资讯]中国工程院院士.教育部高等教育司司长.清华大学教授张尧学在由谷歌主办的"云计算时代的合作与创新"学术论坛上 ...

  9. 如何解决matlab共享中独立桌面app选项为灰色的问题

    如何解决matlab共享中独立桌面app选项为灰色的问题 今天在学习matlab的appdesigner功能时发现独立桌面app选项为灰色 如图Standalone Desktop App选项为灰色 ...

最新文章

  1. Spring Security and Shiro
  2. HDU2035人见人爱A^B(快速幂求余)
  3. 2cocos2dx别踩白块游戏案例
  4. 网易的企业免费邮箱和腾讯的企业邮箱
  5. 了解传销系列之三 : 开心门
  6. 【接口测试实战(三)】接口测试用例的编写
  7. Android推送技术总结
  8. 配置、账户-Windows 8学习总结 -by小雨
  9. 在线制作SprinBoot的banner
  10. Android使用libjpeg实现图片压缩
  11. python数据导入与清洗_Python学习之 数据清洗之增删改查
  12. 程序和进程和线程的区别是什么?
  13. C、C++数组初始化,数组赋值
  14. c语言中函数floor用法,C 库函数
  15. FZU2109 数位dp 含前导零
  16. 30K~65K,春节前最后一批热门技术岗位,快到碗里来
  17. 【python3】文件夹文件遍历文档内容追加
  18. matlab simulink_解密矩阵实验室 | 山东大学MATLABamp;Simulink下载指南
  19. A fatal error has been detected by the Java Runtime Environment, C [VCRUNTIME140.dll+0x1989]
  20. win10上py37安装kivy

热门文章

  1. java8 stream中的惰性求值
  2. 生产者发送消息的过程?
  3. application context not configured for this file?
  4. 002_JavaScript的历史
  5. 027_html框架
  6. java jackson json_使用Java和Jackson将Json序列化为通用结构而无...
  7. webstorm配置环境变量_webstorm中配置nodejs环境及npm步骤详细解说
  8. Windows 系统电脑开机速度加快
  9. 小白学python,零基础学Python难不难?
  10. 计算机知识浩瀚,计算机视觉基础