TMS320C6748开发视频教程笔记 第9章 中断与异常

9 中断与异常

在这里插入图片描述
通过标题可以知道,在这一部分视频教程主要讲解两方面内容,第一方面是中断,另一方面是异常
中断:主要作用是改变程序的主要流程,如果我们的程序没有运行操作系统的话,一般情况下在嵌入式CPU程序开发都是采用一个无限循环的方式,如果我们的CPU没有中断来处理的话,我们的程序会一直处于无限循环当中,而中断的作用就是改变了这个程序的执行流程,这样的好处是提高了CPU对内部以及外部事件的实时处理能力。
异常:最常见的异常状况就是程序跑飞,所谓的程序跑飞就是我们的程序并没有像我们想象中的那样按照一定的顺序来运行。对于编写一个程序而言,我们需要做得就是让这个程序的运行结果要按我们编写的目的来执行,而发生异常就是程序的执行顺序没有按照我们预定的计划来执行。在我们使用单片机或其他处理器进行编程的时候,如果我们的程序发生了异常,比如说最常见的异常是程序跑飞,在通常情况下的做法是我们使能CPU内部的看门狗计数器,如果程序跑飞,就没有执行看门狗计数器的清0操作,这样的话CPU就会自动复位,从而使CPU程序的执行返回到正常的顺序。这样虽然是一种很好的解决办法,但是它同样有一个问题,就是虽然在这个时候解决了跑飞的异常情况,但是我们仍然不知道这个异常情况发生的原因到底是什么,如果程序下一次发生异常的时候,依然会复位,如果这个问题比较严重,我们找到这个原因可能就比较困难。而在DSP C6748中有一个异常的处理模块,它可以帮助我们找出在CPU内部或外部在运行过程中所发生的异常状况,这样的话我们就可以很清楚的分析并且找到程序发生异常的原因。当然,异常状况不仅仅是程序跑飞这一种状况,比如说在DSP C6748的使用当中,我们要使用外部的存储器,比如说DDR2内存,就必须先对DDR2的控制器做初始化,如果我们没有初始化DDR2控制器,但是却对DDR2内存空间进行访问的话,这样的话也会出现异常状况。当然,在程序运行中,发生异常的状况有很多,在视频的后面会为大家讲解。
在这里插入图片描述
在讲解中断之前,举一个例子,或者设想一个情景来帮助大家理解DSP C6748中的这些中断。比如说你现在在家里和家人看着电影,手里吃着瓜子或者薯片,而在厨房水壶里烧着开水,电饭锅里煮着粥,如果什么都不发生的话,你就一直跟着家人在电视机前看着电视吃着零食,这时厨房里的水烧开了,通常情况你只好放弃看电影然后去厨房把相应的插座的电关了,当走到厨房的时候,除了水烧开了,这时粥好像也煮好了,但是不巧的是去看煮在锅里的粥发现一个问题,就是煮粥的时候忘记放米了,这样的话等于花了这段时间只煮了一锅开水而已,这时就不得不重新淘米再准备重新煮一锅粥,但是在淘米的时候突然有人来敲门,心里可能会比较纳闷,我今天应该没有约朋友或者亲戚来家怎么会有人敲门呢?这时有两个选择,一个是中断当前的操作,比如说是淘米这个操作,然后去门口看一看是谁来了,需不需要让他进来,还可以忽略掉正在敲门的外来的客人。当然对于你来说,现在要煮这锅粥,但是材料还没准备好,所以煮粥对我来说应该是最优先做得事,因为外面来的可能是一个不速之客,比如说是收电费的或者是推销的,对于我来说,理不理会他对我来说可能没有任何影响,所以我可以选择忽略他来继续操作,在我把厨房的事情都做好后,我就又回到电视机旁看电视。然而看了一会儿电视,突然你感觉有东西在晃动,桌子上的东西也越来越不稳了,通过生活经验来说,可能是地震了,所以赶紧叫上家人往外跑或者躲在桌子底下,或者是像卫生间这样比较牢固的地方,但是幸运的是,地震比较小,晃动一会儿就结束了,这时你看了看没有什么问题,就继续看剩下的电影,直到看完。

9-1 中断

9-1-1 中断类型

在这里插入图片描述
在DSP C6748或者说所有的C6000系列DSP来说,在它内部主要有以下4种中断类型:(关于中断的详细说明,详情请看TMS320C674x DSP Megamodule Reference Guide (Rev. A)第7章,TMS320C674x DSP CPU and Instruction Set User’s Guide(Rev.B)第5章)
1、复位中断(RESET),它的优先级是最高的,复位中断的主要作用是将CPU正在执行的操作暂停,并且返回到一个已知的状态,然后初始化所有的寄存器到默认状态。复位中断的优先级是最高的,而且在我们的CPU上电的时候都会执行一次上电复位。
2、12个可屏蔽硬件中断(INT4-INT15),既然它叫可屏蔽硬件中断,就说明可屏蔽硬件中断的发生是有条件的,可屏蔽硬件中断只有满足以下条件才会发生。首先在CSR也就是控制状态寄存器当中的全局中断使能位要置1;其次中断使能寄存器当中IER中的不可屏蔽中断位要置1,也就是使能不可屏蔽中断;还有就是在中断使能寄存器IER当中,相应的中断要置1,也就是将相应的可屏蔽中断使能;最后还有一个条件,这个条件就是它叫可屏蔽硬件中断来源,就是中断标志寄存器相应的位要置1,而且在这个中断标志寄存器IFR中,没有比它优先级更高的位被置1,也就是说,我这个中断想要发生,必须没有更高优先级的中断正在执行我才会发生,如果更高优先级的中断在执行的话,我的这个中断操作将会被屏蔽,就不会再执行。
3、不可屏蔽中断/异常(NMI),如果使能了异常模块,这个不可屏蔽中断就当不可屏蔽异常来使用,它的优先级在C6748内部是仅次于复位中断的,对于不可屏蔽中断来说,它要发生的条件很简单,就是在中断使能寄存器IER中NMIE,也就是不可屏蔽中断使能那一位置1,它就一定会发生,当然在一个极端的条件下,或者说唯一条件下,也就是说在我们的CPU在处理中断响应的时候会有一个延迟时间,在这个延迟间隙中也不会发生,当然对于所有中断来说,可屏蔽硬件中断如果是处于延迟的间隙中发生的话,也不会被响应,在一般情况下这种情况是不会发生的。
4、可屏蔽硬件异常(EXCEP),可屏蔽硬件异常是跟可屏蔽中断相对应的,我们的某一个中断可能发生也可能不发生,因为它是可屏蔽中断,如果不发生的话就会产生一个一个可屏蔽中断的硬件异常,这样的话我们就可以通过看到这个中断什么时候没有发生来帮助我们来找到它不发生的原因。

下边表格可以看到中断优先级的关系。
在这里插入图片描述
中断优先级最高的是复位中断,其次是不可屏蔽中断,然后是12个可屏蔽中断,中断4的优先级最高,中断15的优先级最低。

回到之前举的例子。
在沙发上看电影,相当于DSP当中,基于非操作系统开发时使用的无限循环。
厨房发生的烧开水和煮粥是一个组合事件,不管哪个发生都需要去处理;也可以选择忽略这些。
准备煮粥材料时门外发生敲门,相当于一个被屏蔽了的可屏蔽中断,因为在煮粥时,对于我们来说这个事件的优先级最高,而且这个事件还没有执行完,而门外敲门这个事件对于我们来说没有任何影响,而且它的优先级比正在执行的事件的优先级低,所以就可以把这个事件屏蔽掉。
在完成厨房的工作再回来看电视的时候,可能会发生地震的那个事件,就相当于一个不可屏蔽中断,或者说是一个不可屏蔽的异常,因为这样的自然灾害可能会危及我们的生命,所以它的优先级一定是最高的,不论我们现在在做什么,一定要对这个事件进行响应,对于DSP C6748也是这样,一般情况下,对于不可屏蔽中断的使用都是在极端的异常或者是极端的硬件错误的时候才会发生,比如说我们的DSP C6748是用在手持终端,一个靠电池以及外部供电双重供电的系统,当我们的供电方式由外部供电切换到内部供电的时候,或者说我们的电池容量即将耗尽的时候,这对于CPU来说都是比较极端的紧急情况,就必须要执行一些操作,比如说可以把CPU的大部分模块休眠,使它处在低功耗状态,这样的话可以维持到我可以给电池充电,或者说直接把CPU的所有状态保存下来,然后就可以等待电源的关闭,电源重新启动的时候再恢复相应的状态。这样就是紧急或者说比较极端的情况,当然对于DSP C6748来说,完全可以把不可屏蔽中断用作一个普通的中断,但是不建议这样做。

9-1-2 中断结构

DSP C6748中断的结构:
在这里插入图片描述
RESET,复位中断
NMEVT,不可屏蔽中断事件
EVT[127:4],DSP可以相应的4到127个事件,因为我们的CPU硬件中断只有这些,但是可以产生中断的事件却有很多,所以需要通过Interrupt selector中断选择来选择我们需要让哪些中断来产生,哪些事件来产生中断。
IDROP,中断发生异常的时候来产生一个中断错误INTERR,这个中断错误有一个固定的事件,它也可以映射到中断向量表中,我们就可以通过它来在中断发生异常的时候来执行一些操作。
AEG(Advanced Event Generator高级事件产生),它的主要作用是模拟或者仿真这个事件的发生来帮助我们调试。

在这里插入图片描述
关于事件的详细说明,请查阅:TMS320C6748 DSP Technical Reference Manual (Rev. A) 83-86页
在DSP C6748内部一共有128个独立的事件,也可以使用组合事件。独立的事件很好说,比如GPIO口、McBSP、McASP模块,这就是一个个独立的事件。组合事件就是当我们的中断不够用了,比如说我们只有12个可屏蔽中断来使用,但是我们现在有20个事件要产生中断,这样的话我们就没办法把这20个事件映射到12个中断中,就可以使用组合事件。还有一种使用组合事件的情况就是这两个事件满足或的关系,也就是说这两个事件只要有一个事件发生就产生中断,也可以把它们组合在一起,通过组合事件就可以让CPU响应所有128个事件产生的中断。

在这里插入图片描述
以上这个表格前4个事件是给组合事件来使用的,每一个组合事件代表32个事件,那么在这32个事件中,可能有的我们需要产生,有的不需要产生,就需要配置相应的掩码,我们屏蔽掉不需要产生的事件,只留下我们需要产生的事件就可以,这些事件满足或的关系,也就是任何事件的发生都会产生相应的中断。而对于这些可利用的事件,就是我们单个外设所产生的事件。这里需要注意一下,有一些其他的事件,这些事件的主要功能就是为我们捕获一些异常状况,比如说第119到127这些事件都是跟内存有关的,如果我们的内存读写发生异常的时候,我们就可以通过这些事件来捕获这些异常,118是PDC(Power Down Controler断电控制器)中断。因为C6748是一款低功耗的产品,在我们需要降低功耗的时候可以关闭一些CPU的模块来降低功耗。还有就是96,中断错误事件,我们如果需要捕获某个中断产生的错误事件,就需要将96这个事件映射到我们的12个中断当中。

9-1-3 中断事件选择

下面是中断事件的选择
在这里插入图片描述
主要功能就是为我们选择需要产生中断的事件,如果使用单一的事件来说,最多可以同时让12个事件产生中断,算上不可屏蔽中断来说,最多有13个。如果这些不能满足我们的话,就需要使用组合事件。组合事件可以将一些事件组合起来然后产生一个中断。

9-1-4 中断错误事件

中断错误事件
在这里插入图片描述
中断错误事件的选择跟组合事件和普通事件是类似的。这里需要注意的是,如果我们某一个中断发生错误,只有我们将相应的错误消除之后才会有新的错误发生,跟前面的结构类似,对于中断错误事件也可以实现以一个Exception selector(异常选择)。

9-1-5 中断向量表

中断向量表
在这里插入图片描述
中断向量表/中断服务表的主要功能就是相应的中断发生的时候,我们要跳转到相应的地址执行相应的指令。这里需要说明的是,如果我们的中断服务函数,或者说中断指令比较少的话,就可以把它写到中断向量表或者说是中断服务表当中。如果我们的函数比较长,就需要一个跳转,跳转到其他内存地址,通常情况下我们都执行跳转,因为在默认情况下,每一个内存地址的间隔是十进制32,也就是说它最多只能执行8条32位指令,最后还需要包含两条指令,一个是跳转指令,一个是延时。
在这里插入图片描述
也就是说我们指令最多只能使用6条指令来完成我们的操作,但是通常情况下可能不能满足我们的需求,这样我们就需要一个跳转。

下图举了个例子, 是不可屏蔽中断4,在它的中断向量表中执行了一个跳转,跳转到其他的指令来执行一些更长的指令。
在这里插入图片描述
对于不可屏蔽中断来说,可以在这个中断向量表看出它的返回指针是IRP(Interrupt Return Pointer中断返回指针),但是对于不可屏蔽中断来说,它的指针是NRP,在编程时一定要注意,如果使用了不可屏蔽中断,它的返回指针不是NRP的话,就会导致程序异常。在我们使用startware得中断管理来说,它对所有中断默认都是使用的IRP,在调试不可屏蔽中断的时候就可能出现问题,这一点一定要注意。

9-1-6 中断嵌套

中断嵌套
在这里插入图片描述
通常情况下,当CPU执行一个中断服务函数或者说执行一段中断服务指令的时候,中断应该是被禁用的,然而,当我们当前执行的中断是处于可屏蔽中断也就是中断4到中断15的时候,一个不可屏蔽中断可以中断当前执行的可屏蔽中断,换句话说,一个不可屏蔽中断可以中断一个可屏蔽中断,但是任何一个不可屏蔽中断或者可屏蔽中断是不能够中断不可屏蔽中断的。这段话听起来比较绕口,简单来说,通常情况下CPU是不允许中断嵌套这种情况发生的,除非这个中断源是一个不可屏蔽中断,如果希望一个可屏蔽中断可以被一个更高优先级的可屏蔽中断中断的话,这样的话我们需要执行一些软件上的操作,我们就需要在我们的中断服务函数中来实现一个保存现场的操作,主要是保存一些相关寄存器的值,最重要的是中断返回指针,这样的话才能保证我们的中断执行完可以完整的保持这个整个中断嵌套的逻辑,而不至于使程序发生异常。

9-2 异常

9-2-1 异常类型

对于DSP C6748来说,内部异常主要由以下4个方面的异常。
在这里插入图片描述
1、外部,这里所说的外部是指CPU核心的外部,也就是DSP C674x sub system也就是DSP子系统外部,外部主要就是一些存储器以及一些外设所产生的可屏蔽异常中断,这里主要指之前说过的一些事件,比如说我们的外设、McBSP、McASP、IIC、UART这些外设所产生的中断。但是中断由于种种原因没有被正确的执行就会产生异常,这个异常就可以通过异常事件来捕获,然后就可以根据发生异常当时CPU所处的情况,以程序所执行的流程来分析异常产生的原因来帮助我们来解决程序中可能存在的问题。
2、外部产生的不可屏蔽异常中断,这里所说的就是NMI不可屏蔽异常中断,如果我们没有使能异常处理的话,NMI不可屏蔽中断默认是作为中断来使用的,如果使能了异常处理的话,它是作为异常来处理的。
3、内核产生的内部不可屏蔽异常中断,这些中断主要就是内核在操作时候,比如说我们在取指令,或者是在执行某些操作符的时候所产生的异常中断。
4、软件产生的软件异常中断,这里主要是指在程序中执行SWE和SWENR指令所产生的中断,这两条指令主要原因是切换我们CPU的特权模式,CPU有两种模式,一个是用户模式,一个是特权模式(管理员最高权限模式),它们的主要区别就是对于一些寄存器的访问权限是不同的,这些寄存器主要是跟CPU核心配置相关的寄存器。

9-2-2 内部异常

从这张表可以看出,内部异常主要是在CPU操作的时候产生的异常,比如说取指令的异常、不合法的取值包、不合法的操作符以及特权模式的冲突等等。通过这样一个异常捕获可能帮我们更好优化程序。
在这里插入图片描述

9-2-3 软件异常

在这里插入图片描述
软件异常是值指执行软件异常指令SWE和软件异常无返回指令SWENR,执行这两条异常指令所产生的异常,之前也说过,主要就是用于切换CPU的特权模式,在默认情况下,CPU在复位之后是处于最高权限的,可以对所有寄存器访问,这里需要注意的点是,对于我们经常使用的SYSCFG寄存器来说,在CPU的硬件版本在2.0之前我们在对这个寄存器进行访问的时候需要先对寄存器的某个值,Kick寄存器写一个固定值来解锁以便获得对它的访问权限,但是在芯片版本2.0以后就不需要这个操作了,可以直接读写,而如果我们再对Kick 0和Kick 1这两个寄存器写任何的值都不会有任何反应。

对于DSP C6748内部的异常事件的中断处理跟前面讲过的中断处理流程大概是一致的,比如就以外部产生的可屏蔽中断事件来说,也需要经过异常选择,异常组合以及映射这样的关系,我们才能对相应异常事件做出响应,而且在对于异常处理的时候也需要中断向量表,当然这个中断向量表需要的是NMI的中断,我们也需要编写相应的中断服务函数来对处于异常状况的CPU进行一些处理,一般情况下我们在异常处理的中断服务函数中主要是执行一些无限循环的打印操作,打印一些当时的状态信息,来协助我们分析CPU处于异常的原因。对于中断来说,中断管理的寄存器也不是很多,但是无论我们使用的startware还是实时操作系统像DSP BIOS或者是TI RTOS来说,我们都不需要关心某个具体的寄存器该如何操作。在startware里有相应的API函数来帮我们完成中断的操作,像中断的使能、中断的映射等等,而在SYS BIOS中因为中断是属于HAL也就是硬件抽闲层的一部分,也就是说它必须,或者说强烈健在在SYS BIOS这样的实时操作系统将这些中断、内存、缓存交由系统来管理,而不是向基于非操作系统编程的时候我们直接对寄存器访问。如果我们在使用实时操作系统的时候同时也在程序中直接对寄存器或者是直接对中断缓存直接操作的时候可能会引起不必要的冲突,所以最好的方法是这些跟硬件抽闲层有关的一些模块,通常是CPU内部的模块交由系统来管理。
在这里插入图片描述

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点灯小能手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值