内核和外设的交互方式有两种:轮询和中断
拿取快递来举例子
1、轮询:轮流查看某个引脚或者某些信号
假设你和快递员都没有手机,预定中午十二点左右来取快递
你从十一点四十分开始,每隔五分钟前往小区门口。
快递员没到就立即掉头回去。
最抽象的一种情况,你刚回头,快递到。五分钟后你来,快递员等了你四分多钟
不能长时间做一件事,响应速度慢。
2、中断:具备应对突发事件的能力
现在你和快递员都有电话,你在干你自己的事情,快递员一个电话过来,告诉你下来拿快递。中断你干那件事。响应速度快。
每一个中断源都有一个对应的固定入口地址(中断向量)
几个中断源就有几个中断向量
PC指针:
PC指针是个变量,这个变量里面放着地址,这个地址就是程序下一个代码所要执行的地址。
代码的存放:
代码都是放在我们的程序存储空间里面,存储空间里就是一个一个内存单元,每一个单元都有固定的地址。
我们要执行相应的代码,就要知道单元的地址是什么,这个地址就会放到PC指针里面。这个程序怎么样执行,执行的是什么样的单元代码由PC指针(重要)决定,PC指针保存下一个代码要执行的单元地址,因此我们要改变程序的执行方向,就要改变PC指针的地址。所以要实现中断,就从改变PC指针的地址下手
程序执行过程,中断响应过程
内核复位之后,从0000开始执行。0000不一定是main函数的代码。单片机或者微处理器运行main之前,会做一些铺垫,会做一些初始化操作。很多时候你会看到这个程序有个汇编的代码叫start out。执行完这个之后才会跳转到main函数取执行响应的代码
假设在0x0000处放了一个跳转语句,跳转到0x00f0处,将PC指针的地址换成0x00f0,去执行0x00f0的代码。如果这里面放得是main函数的第一行代码,那就执行main函数的代码
每执行完一条指令后,PC指针的值会自动增加。中断要是不来PC指针就会一直增加下去。
中断要是出现了,就去执行中断服务函数所在的位置,就是中断源所对应的中断向量(中断入口地址),中断1对应的是0x0004 中断3对应的是0x0008这些是他的中断入口地址
现在产生了中断是中断1的,那么我现在就要执行他的中断向量0x0004这个单元所存放的代码,在执行中断向量代码之前要进行“现场保护”,为什么呢?因为我这个主函数执行到某一个位置,需要暂停下来,目的是为了执行中断服务函数之后需要回到中断之前的位置。为了完成这样的操作,程序需要将当前这个代码执行的位置的地址给保存下来。保存到堆栈里面,保存好地址之后,切换PC指针的地址,切换到中断向量的位置。
一般情况下中断向量的入口地址都不是很大,一般是4个字节或者8个字节。在这里面你写不了多少行代码,这时候需要一个跳转代码跳转到一个更大的内存空间。在更大的内存空间内些再写响应的中断服务函数的代码。跳转语句就是将PC指针的地址换成你需要跳转的语句的地址
执行完中断服务的代码之后,会进行现场恢复,将中断服务函数开始前的保存的代码地址放到PC指针中完成现场回复,接着刚刚中断的位置继续往下执行。
中断的重要概念
中断源
引起中断的原因,一个中断怎么产生,就是由中断源产生。一个内核里会有多个中断源,有些内核会给他们的中断源一个编号,例如一号中断、二号中断、三号中断等 例如51单片机
中断向量(中断入口地址)
每个中断源都对应的一个中断向量,一号中断的一号中断向量,二号中断的二号中断向量
中断服务函数
每个中断要处理响应的请求,就要有响应的代码。一号中断的一号中断服务函数,二号中断的二号中断服务函数
相互联系
中断服务函数要和中断向量进行关联,中断方式:1.中断号(51单片机)、中断向量(CC2530)
二号中断产生中断请求了,被内核响应之后找到二号中断向量,中断向量跳转到中断服务函数执行相应的代码。
产生中断>PC指针地址变为中断向量(中断入口地址)>跳转到中断服务函数
中断使能控制位
每个中断源都是自由产生的,不是由内核来控制的是根据它的触发条件不同或者外部环境不同会产生相应的中断请求。但是这个请求能不能被响应,就要取决于内核的配置。如果允许请求进入内核,那么请求就会被响应,被响应之后就会执行响应的中断服务函数。能不能被响应由中断使能控制位来决定。
中断没有使能,这个线就是断的,内核收不到中断请求。
中中断使能,这个线就连上,内核收到中断请求。中断信号能够通道内核中。
中断使能控制位控制中断请求能否被内核响应。
中断标志位
每个中断产生后,都会对每个中断做一个标记,通过标志的形式告诉中断源是什么样的中断发送的请求。
例子:打电话
电话线(中断使能控制位)都通了,内核通过手机号码(中断标志位)知道是谁打电话竟来了。
知道是什么中断发送的请求,进而去执行响应的中断服务函数。
有些中断标志位可以自动清除,有些需要手动清除。如果不清除中断标志位,因为这些中断标志位都还在,可能会产生一些误操作。
不同芯片的中断概念都是差不多的,只有一些对中断源的操作有些区别。