RT-thread内核之异常与中断
一、什么是中断?
中断有两种,一种是CPU本身在执行程序的过程中产生的,一种是由CPU外部产生的。 cpu外部中断,就是通常所讲的“中断”(interrupt)。对于执行程序来说,这种“中断”的发生完全是异步的,因为不知道什么时候会发生。CPU对其的响应也完全是被动的, 可以通过“关中断”指令关闭对其的响应。 然而由软件产生的中断一般是由专设的指令,如X86中的“INT n”在程序中有意产生的, 是主动的,同步的。只要CPU执行一条INT指令,在开始执行下一条指令之前一定会进入中 断服务程序。这种主动的中断称为“陷阱”(trap)
从物理学的角度看,中断是一种电信号,由硬件设备产生,并直接送入中断控制器的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断。此后,处理器会通知 OS 已经产生中断。这样,OS 就可以对这个中断进行适当的处理。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识,这些值通常被称为中断请求线(IRQ)。
中断可分为同步(synchronous)中断和异步(asynchronous)中断:
1. 同步中断是当指令执行时由 CPU 控制单元产生,之所以称为同步,是因为只有在一条指令执行完毕后 CPU 才会发出中断,而不是发生在代码指令执行期间,比如系统调用。
2. 异步中断是指由其他硬件设备依照 CPU 时钟信号随机产生,即意味着中断能够在指令之间发生,例如键盘中断。
二、什么是异常?
同步中断又称为异常(exception);异步中断则被称为中断(interrupt)。我们通常讲的中断指的都是异步中断,即cpu外部中断。
1.中断可分为可屏蔽中断(Maskable interrupt)和非屏蔽中断(Nomaskable interrupt)。
2.异常可分为故障(fault)、陷阱(trap)、终止(abort)三类。
这些类别之间的异同点如下:
类别 原因 异步/同步 返回行为
中断 来自I/O设备的信号 异步 总是返回到下一条指令
陷阱 有意的异常 同步 总是返回到下一条指令
故障 潜在可恢复的错误 同步 返回到当前指令
终止 不可恢复的错误 同步 不会返回
三、中断处理过程
当中断产生时,处理器将按如下的顺序执行:
• 保存当前处理机状态信息
• 载入异常或中断处理函数到PC寄存器
• 把控制权转交给处理函数并开始执行
• 当处理函数执行完成时,恢复处理器状态信息
• 从异常或中断中返回到前一个程序执行点
中断使得CPU可以在事件发生时才予以处理,而不必让CPU连续不断地查询是否有相应的事件发生。通过两条特殊指令:关中断和开中断可以让处理器不响应或响应中断(在关闭中断期间,通常处理器会把新产生的中断挂起,当中断打开时立刻进行响应)。在执行中断服务例程的过程中,如果有更高优先级别的中断源触发中断,由于当前处于中断处理上下文环境中,根据不同的处理器构架可能有不同的处理方式:比如新的中断等待挂起直到当前中断处理离开后再行响应,但这在硬实时环境中不允许发生;或者新的高优先级中断打断当前中断处理过程,而去直接响应这个更高优先级的新中断源,这称为中断嵌套,而中断是否能够嵌套,一般由MCU处理器的中断机制决定,如stm32中只有新中断的抢占优先级比当前中断高时,才能打断当前中断进入新的中断服务函数。
在系统响应中断前,软件代码(或处理器)需要把当前线程的上下文保存下来(通常保存在当前线程的线程栈中),再调用中断服务例程进行中断响应、处理。在进行中断处理时(实质是调用用户的中断服务例程函数),中断处理函数中很可能会有自己的局部变量,这些都需要相应的栈空间来保存,所以中断响应依然需要一个栈空间来做为上下文运行中断处理函数。中断栈可以保存在打断的线程栈中,当从中断中退出时,返回相应的线程继续执行。中断栈也可以与打断线程栈完全分离开来,即每次进入中断时,在保存完被打断的线程上下文后,切换到新的中断栈中独立运行;在中断退出时,再做相应的上下文恢复。
使用独立中断栈相对来说更容易实现,并且对于线程栈使用情况也比较容易了解掌握(否则必须要为中断栈预留空间,如果系统支持中断嵌套,还需要考虑应该为嵌套中断预留多大的空间)。RT-Thread采用的方式是提供独立的中断栈,即中断发生时,中断的前期处理程序会将用户的栈指针更换到系统事先留出的中断栈空间中,等中断退出时再恢复用户的栈指针。这样中断就不会占用线程的栈空间,从而提高了内存空间的利用率,且随着任务的增加,这种减少内存占用的的效果也越明显。以stm32的cotex-M3/M4为例,cotex-M3/M4中拥有两个堆栈指针,然而它们是banked,因此任一时刻只能使用其中的一个:
主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核,以及异常与中断处理。
进程堆栈指针(PSP):由用户的应用程序代码(如线程切换)使用。堆栈指针的最低两位永远是0,这意味着堆栈总是4 字节对齐的。
由此可以看出,在一个实际运行系统里有两大部分:一是操作系统和中断,一是用户应用程序。它们使用的资源是不一样的,从中断(线程调度时产生的中断)返回到用户应用程序线程时,系统使用的堆栈指针也从MSP变成PSP。
四、与操作系统相关的中断接口:在src/irq.c中
void rt_interrupt_enter(void);
void rt_interrupt_leave(void);
当整个系统被中断打断,进入中断处理函数时,OS需要知道当前已经进入到中断状态。
rt_interrupt_enter函数用于通知OS,当前已经进入了中断状态;rt_interrupt_leave函数用于通知OS,已经离开中断状态。通常来说,OS需要知道这样的运行状态,这样在中断服务例程中,如果调用了OS相关的调用,OS好及时调整相应的行为,例如进行任务切换时应该采取中断中任务切换的策略,而不是立即进行切换。但是如果中断服务例程很显然、很必然地不会去调用OS相关的函数,此时也可以不调用rt_interrupt_enter/leave函数。 rt_uint8_t rt_interrupt_get_nest(void);
获取当前中断嵌套计数值,大于0说明处于中断服务中,大于1说明存在中断嵌套
五、与MCU相关的中断接口:以stm32f4为例
关闭中断:在libcpu/arm/cotex-m4/context_rvds.S中用汇编语言实现
rt_base_t rt_hw_interrupt_disable(void);
函数返回中断前的系统中断状态。
当系统关闭了中断时,就意味着当前线程/代码不会被其他事件所打断(因为整个系统已经不再对外部事件响应),也就是当前线程不会被抢占(因为线程切换时用到了PendSV_Handler),除非这个线程主动让出处理器。 打开中断:在libcpu/arm/cotex-m4/context_rvds.S中用汇编语言实现
void rt_hw_interrupt_enable(rt_base_t level);
调用这个函数接口将恢复调用rt_hw_interrupt_disable前的中断状态,level是上一次关闭中断时返回的值。打开中断往往是和关闭中断成对使用的,用于恢复关闭中断前的状态。
注意:调用这个接口并不代表着肯定打开中断,而是恢复关闭中断前的状态,如果调用rt_hw_interrupt_disable()前是关中断状态,那么调用此函数后依然是关中断状态。
RT-thread内核之异常与中断的更多相关文章
- Linux内核--异常和中断的区别
相信大家都知道非常著名的两个名词:异常和中断,不过,你真的理解这两个名词在说什么吗?它们之间有什么区别呢? 1.中断 大家都知道,当我们在敲击键盘的同时就会产生中断 ...
- Linux内核实现透视---硬中断
Linux的中断处理是驱动中比较重要的一部分内容,要清楚具体的实现才能更好的理解而不是靠记住别人理解后总结的规律,所以今天就打算从从源码来学习一下Linux内核对于中断处理过程,设计中断子系统的初始化 ...
- 向linux内核中添加外部中断驱动模块
本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...
- Java thread中对异常的处理策略
转载:http://shmilyaw-hotmail-com.iteye.com/blog/1881302 前言 想讨论这个话题有一段时间了.记得几年前的时候去面试,有人就问过我一个类似的问题.就是j ...
- Linux内核设计笔记7——中断
中断与中断处理 何为中断? 一种由设备发向处理器的电信号 中断不与处理器时钟同步,随时可以发生,内核随时可能因为中断到来而被打断. 每一个中断都有唯一一个数字标志,称之为中断线(IRQ) 异常是由软件 ...
- 鸿蒙内核源码分析(中断管理篇) | 江湖从此不再怕中断 | 百篇博客分析OpenHarmony源码 | v44.02
百篇博客系列篇.本篇为: v44.xx 鸿蒙内核源码分析(中断管理篇) | 江湖从此不再怕中断 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪 ...
- 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 百篇博客分析OpenHarmony源码 | v43.02
百篇博客系列篇.本篇为: v43.xx 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪里 ...
- 鸿蒙内核源码分析(中断切换篇) | 系统因中断活力四射 | 百篇博客分析OpenHarmony源码 | v42.02
百篇博客系列篇.本篇为: v42.xx 鸿蒙内核源码分析(中断切换篇) | 系统因中断活力四射 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪 ...
- 浅析arm的异常、中断和arm工作模式的联系
说到异常向量,会让人联想到中断向量.其实,中断是属于异常的子集的,也就是说中断其实是异常其中的一种. 回到异常向量,他其实是一张表格,每个格子里存放的是一个地址,或者是一个跳转命令,不管是哪个,其目的 ...
随机推荐
- tensorflow 教程 文本分类 IMDB电影评论
昨天配置了tensorflow的gpu版本,今天开始简单的使用一下 主要是看了一下tensorflow的tutorial 里面的 IMDB 电影评论二分类这个教程 教程里面主要包括了一下几个内容:下载 ...
- TensorFlow之tf.nn.dropout():防止模型训练过程中的过拟合问题
一:适用范围: tf.nn.dropout是TensorFlow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层 二:原理: dropout就是在不同的训练过程中随机扔掉一部分神经元.也就是让 ...
- javascript sorting/ v8 sorting
https://github.com/mgechev/v8-sorting-test/tree/master/src/algorithms
- 20145226夏艺华 逆向及Bof基础实践
逆向及Bof基础实践 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串,如图所示: 该程序同时 ...
- 成都Uber优步司机奖励政策(3月3日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 解决Entity Framework查询匿名对象后的跨域访问的一种方式
在Entity Framework中,可以使用lambda表达式进行对数据的查询,而且可以将查询结果直接映射为对象或者对象列表,这极大的提高的开发速度,并且使数据层的数据更加方便处理和传递.但是很多时 ...
- 「日常训练&知识学习」树的分块(王室联邦,HYSBZ-1086)
题意与分析 这题的题意就是树分块,更具体的看题目(中文题). 学习这一题是为了树的分块,为树上莫队做铺垫. 参考1:https://blog.csdn.net/LJH_KOQI/article/det ...
- 「国庆训练」Kingdom of Obsession(HDU-5943)
题意 给定\(s,n\),把\(s+1,s+2,...,s+n\)这\(n\)个数填到\(1,2,...,n\)里,要求\(x\)只能填到\(x\)的因子的位置(即题目中\(x\%y=0\)那么x才能 ...
- VIN码识别/车架号OCR识别:快速占领汽车后市场数据入口
大数据时代,企业在数据入口方面的竞争越来越激烈,这种对于入口级的大数据“争夺战”,让很多企业在数据挖掘和收集的技术方面开始加快更新速度. 在当前IT行业激烈竞争环境之下,对于入口产品的控制成为了大数据 ...
- selenide 自动化测试进阶一: 查找元素和相关操作
基础环境配置和举例请移步:https://www.cnblogs.com/davice/p/9298742.html 提到自动化有些测试同学就会问,我会使用工具录制做自动化,我会用工具或插件识别元素. ...