中断中处理延时及一些函数的调用规则(中断调i2c驱动有感)--中断中的延迟delay与printk函数的冲突【转】

简介: 转自:http://blog.csdn.net/psvoldemort/article/details/8222371 1,中断处理程序中不能使用有睡眠功能的函数,如ioremap,kmalloc,msleep等,理由是中断程序并不是进程,没有进程的概念,因此就没有休眠的概念; 2,中断处理程序中的延时可以用忙等待函数来代替,如ndelay,udelay,mdelay等,这些函数在实现上本质是根据CPU频率进行一定次数的循环;最好不要使用mdelay,因为毫秒延时对内核来说已经是非常大了。

转自:http://blog.csdn.net/psvoldemort/article/details/8222371

1,中断处理程序中不能使用有睡眠功能的函数,如ioremap,kmalloc,msleep等,理由是中断程序并不是进程,没有进程的概念,因此就没有休眠的概念;

2,中断处理程序中的延时可以用忙等待函数来代替,如ndelay,udelay,mdelay等,这些函数在实现上本质是根据CPU频率进行一定次数的循环;最好不要使用mdelay,因为毫秒延时对内核来说已经是非常大了。但是在中断处理程序中使用msleep却不行。(见linux设备驱动开发详解第二版p210页)

3,printk函数在中断处理函数中可以使用,但是会占用较多时间,降低效率。在调IIC驱动的时候,由于IIC读取写入处理时必须进行一定延时,在我没有使用udelay的时候,竟然用printk就使IIC中断正常运行,当时在调试的时候,发现有些printk加上程序就正常,去掉就不正常,当时真是匪夷所思,但现在明白了,因此printk占用时间比较大,正好充当了IIC延时的功能。最后我把printk全部去掉,在需要延时的地方加入udelay,才使程序正常运行。

4,使用for和while等的空循环在中断处理函数中进行延时操作,在实际测试中发现并不能起到延时的功能,linux内核处理这种循环速度很快,并没有延时的效果。这跟裸板程序使用循环来延时的用法不相同。

 

其他:

1、中断是一种电信号,由硬件设备生成,并直接送入中断控制器的输入引脚上。然后再由中断控制器向处理器发送相应的信号。处理器一经检测到此信号,便中断自己的当前工作转而处理中断。此后,处理器会通知操作系统已经产生中断,这样,操作系统就可以对这个中断进行适当的处理了。

   

   2、不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识。中断值通常被称为中断请求(IRQ)线。有些中断值是指定的,有些是动态分配的。特定的中断总与特定的设备相关联。

 

   3、异常与中断不同,它在产生时必须考虑与处理器时钟同步。异常也常常称为同步中断。许多处理器体系结构处理异常与中断的方式类似,因此内核对它们的处理也很类似。

  

   4、在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序或中断服务例程。产生中断的每个设备都有一个相应的中断处理程序,如果一个设备可以产生多种不同的中断,那么该设备就可以对应多个中断处理程序。一个设备的中断处理程序是它设备驱动程序的一部分。

   5、中断处理程序与其他内核函数的真正区别在于:中断处理程序是被内核调用来响应中断的,而它们运行于我们称之为中断上下文的特殊上下文中。

 

   6、中断处理一般分为两个部分,中断处理程序是上半部-接收到一个中断就立即执行,但只做有严格时限的工作,这些工作都是在所有中断被禁止的情况下完成的。能够被允许稍后完成的工作被推迟到下半部去。通常情况下,下半部会在中断处理程序返回时立即执行。

 

   7、Linux中的中断处理程序是无需重入的。当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽掉,以防止在同一中断线上接收另一个新的中断。通常情况下,所有其他的中断都是打开的,所以这些不同中断线上的其它中断都能被处理,但当前中断线总是被禁止的。由此可以看出,同一个中断处理程序绝对不会被同时调用以处理嵌套的中断。

   8、共享的中断处理程序与非共享的在注册和运行方式上比较类似,但差异主要有以下三处:

 

  •    注册中断处理程序函数request_irq()的参数flags必须设置SA_SHIRQ标志。
  •    对每个注册的中断处理程序来说,dev_id参数必须唯一。不能给共享的处理程序传递NULL值。
  •    中断处理程序必须能够区分它的设备是否真的产生了中断。否则它根本无法知道是它对应的设备发出了这个中断还是共享这条中断线的其它设备发出了这个中断。

 

   9、当执行一个中断处理程序或下半部时,内核处于中断上下文中。中断上下文和进程并没有什么瓜葛。因为没有进程的背景,所以中断上下文不可以睡眠。因此,不能从中断上下文中调用某些函数。如果一个函数睡眠,就不能在中断处理函数中使用它。中断上下文具有较为严格的时间限制,因为它打断了其他代码。中断上下文中的代码应当迅速简洁,尽量不要使用循环去处理繁重的工作。尽量把工作从中断处理程序中分离出来,放在下半部执行。中断处理程序并不具有自己的栈。相反,它共享被中断进程的内核栈。如果没有正在运行的进程,就使用idle进程的栈。中断处理程序共享别人的堆栈,所以它在栈中获取空间时必须非常节省。内核栈本就很有限,所有的内核代码都应该谨慎利用它。

   10、Linux内核提供了一组接口用于操作机器上的中断状态。这些接口为我们提供了能够禁止当前处理器的中断系统,或屏蔽掉整个机器的一条中断线的能力,这些例程都是与体系结构相关的,可以在<asm/system.h>和<asm/irq.h>中找到。

   11、控制中断系统的原因归根结底是需要提供同步。通过禁止中断,可以确保某个中断处理程序不会抢占当前代码,还可以禁止内核抢占。但它们都没有提供任何保护机制来防止来自其他处理器的并发访问。锁提供保护机制来防止来自其他处理器的并发访问。禁止中断提供保护机制来防止来自其他中断处理程序的并发访问。

【作者】 张昺华
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
目录
相关文章
|
Linux 异构计算 Windows
Windows操作系统:指定网卡ping连通性
某些时候,板卡上留有两个及以上万兆网口,在没有其他FPGA板卡或者只是想测一下网口或者万兆光模块的通路时,可以通过回环互ping来验证下连通性
4138 0
|
Linux 编译器 C++
C/C++性能优化:从根本上消除拷贝操作的浪费
C/C++性能优化:从根本上消除拷贝操作的浪费
1641 1
|
Ubuntu Linux
几种Linux系统切换内核启动顺序方法
几种Linux系统切换内核启动顺序方法
|
11月前
|
机器学习/深度学习 人工智能 编解码
【AI系统】GhostNet 系列
本文介绍了GhostNet系列网络,重点讲解了GhostNet V1和V2的改进。V1提出了Ghost Module,通过廉价操作生成更多特征图,构建轻量级网络。V2在此基础上引入了解耦全连接注意力(DFC)机制,增强了模型捕捉长距离依赖的能力,同时保持了高效的计算性能,特别适合移动设备。文章详细对比了V2与V1的区别,包括结构改进和性能提升。
494 4
【AI系统】GhostNet 系列
|
12月前
|
运维 监控 网络协议
网络诊断必备:Ping、Traceroute、Wireshark的实用技巧详解
网络诊断必备:Ping、Traceroute、Wireshark的实用技巧详解
2702 0
|
弹性计算 监控 负载均衡
slb健康检查注意事项
slb健康检查注意事项
208 1
|
自然语言处理 NoSQL 关系型数据库
CodeGeeX支持哪些语言?
【8月更文挑战第29天】CodeGeeX支持哪些语言?
336 4
|
机器学习/深度学习 人工智能 算法
人工智能伦理框架:构建AI的道德指南针
【7月更文挑战第16天】随着人工智能技术的快速发展,其对社会的深远影响引起了广泛关注。本文探讨了构建人工智能伦理框架的必要性,并提出了一套基于四大原则的伦理指导方针:透明度、公正性、责任归属和隐私保护。文章旨在为AI系统的设计与部署提供道德指南,确保技术进步与人类价值观相协调。
986 3
|
算法 程序员 数据处理
SSE - 多媒体编程中的利器 - SSE指令集简介和C代码示例
本文介绍了SSE(Stream SIMD Extensions)指令集在多媒体处理中的应用,它能提升浮点运算性能,尤其适合处理大量数据。SSE允许一次处理4个32位浮点数,提高效率。文中通过示例展示了如何在C++中集成SSE,比如使用`__m128`数据类型和`_mm_set_ps1()`等函数优化浮点数放大算法。测试结果显示,使用SSE优化后的算法比未优化版本快约3倍,强调了SSE在高效处理多媒体数据中的价值。