在uCOS-II,或者是任何一个可剥夺型OS系统中,中断嵌套是一个必须要解决的问题。从结论上来说,并不是所有的CPU都支持中断嵌套的,即便是ARM系列内核。对于ARM7系列,例如LPC2xxx系列芯片,硬件上是不支持中断嵌套的,而对于新的CortexM3系列,中断嵌套是可配置的,但是中断嵌套时保存现场的操作并不完整,并没有把R0~R15所有寄存器都保存到堆栈中,而是只保存R0~R4。这就需要我们手动软件实现全部或部分的中断现场保护机制。不过首先通过分析ARM7系列芯片来看看中断嵌套的硬件要求。
ARM7系列的内核一共有7中模式,如下图所示:
其中
(1) User Mode:用户模式。唯一非特权模式,可执行指令受限。(读写CPSR禁止)
(2) System Mode:特权模式。
(3) IRQ Mode:中断模式
(4) FIQ Mode:快速中断模式。可打断IRQ模式
(5) Supervisor Mode:监视模式。软中断(SWI)处理函数在这种模式下执行。
(6) Abort Mode:所有同内存保护相关的异常均在这种模式下执行。
(7) Undefined Mode:处理无效指令的异常处理函数在这种模式下执行。
每种模式都有自己的一套R0~R14,以及CPSR,这样能保证跳转其他模式时能直接保存现场。而如果我们要手动保存现场时还必须将这些寄存器压入到堆栈中,这样就用C或汇编写一些比较底层的代码了。当进入中断或异常时会自动进入响应的模式进行处理。而这些都是由程序状态寄存器CPSR保存的。每个CPU内部的状态寄存器可能结构不同,但是对于ARM来说大体的结构差不多。ARM7中的CPSR的结构如下:
其中CPSR的末尾几位即保存了当前的CPU模式。
当每种异常发生,硬件上会做以下操作:
1.CPSR的Mode位置位成当前模式,控制位置位
2.保存打断前模式的R0~R14到对应寄存器,CPSR到SPSR。
3.新模式的PC跳转到内存指定地址,即异常入口地址。
这就需要我们在启动代码的对应地址段协商地址偏移的标签。下面对几个常用的异常进行介绍:
一.Reset。发生在首次上电或者手动按下Reset键(CPU的Reset引脚给个低电平):
上电或Reset之后一般会进入固化在flash中的bootloader,bootloader的工作流程比较复杂,大致上需要判断一些引脚电平来进入相应的模式。比如若判断到ISP引脚(P0.14 in LPC2119)低电平,会进入ISP模式烧写程序。判断Boot0和Boot1的电平组合可以进入对应的外部flash的启动。正常情况下会进入flash中的0x00000000地址的Reset入口。按照启动代码的编写进行一些必要的寄存器操作,以及初始化各个模式的堆栈,最后进入到main函数。
二.Irq中断。一般中断可以注册成irq或者fiq中断。若注册为irq中断时的流程如下:
1.CPSR模式位置为IRQ模式
2.将当前的PC存入到irq的R14中,也就是程序的返回地址,当退出irq时会从这里取出地址给PC,程序回到原处。
3.CPSR中irq使能位清零,禁止irq中断响应。可以看到这就是不能中断嵌套的一个重要原因,因为硬件上会禁止irq的响应,除非你手动将其打开。
4.程序跳转到irq的入口地址,按照启动代码执行操作。比如Keil中会跳转到VicVectAddr地址,即向量中断的入口地址,之后交给向量中断控制器来进行操作。
三.FIQ
Fiq异常基本跟irq异常的流程一致,除了仅仅会将CPSR中的irq和fiq使能位都清零,即不能再响应irq和fiq中断了,并且跳入到fiq的入口地址。当然按照Keil中的启动代码这里是一个死循环,即若不修改启动代码是不能使用fiq中断的。不过对于fiq这种快速中断机制,若我们能手动实现中断嵌套完全可以不用fiq中断,全部利用我们自己的代码来实现。比如uCOS-II中,所有中断都是irq中断,不需要fiq中断。
四.SWI(软件中断)
软件中断不同于其他的中断或异常,这是需要在程序中自己编程调用软件中断命令来触发的。调用后会将CPSR置为SVC(supervisor)管理员模式,存入PC到R14_swi,禁止irq和fiq中断,并且跳转到swi异常入口。这种方式的特点就是进入了一个没有权限限制的SVC模式,这样就可以进行对CPSR的读写操作了。这种方式带给我们很多遐想,我们可以用软件中断进行模式切换,进而进行寄存器的保存操作即保存中断现场,从而可以实现中断嵌套。
【@.2 中断嵌套的方法探究】
中断嵌套的核心思想是,保存当前CPU寄存器到堆栈中,即保存中断现场,并且打开中断使能位允许中断再次响应。但是由于CPU不同模式的权限区分导致这一想法不能简单的实现。比如,很多启动代码中在进入CPU前会进入没有权限的User模式,但是User模式是没办法对CPSR进行读写操作的,也就是说没办法直接在User模式中将CPSR压入到堆栈,同时不能通过向CPSR的模式位写入模式代码切换到其他的模式。
仅仅考虑irq中断,我们来回忆一下整个中断响应的流程。首先中断有输入,CPSR模式置位为irq模式,将当前PC值保存到irq模式的R14中,并且清除CPSR的irq标志位使得不能再次响应irq中断,最后跳转到irq中断入口地址。进过启动代码和我们的程序配置,最终会进入到我们编写中断服务程序中,当这个程序结束时会读取之前保存在R14_irq中的地址值给PC,程序回到原来中断处继续运行。在此基础上我们考虑集中方法实现中断嵌套。(以下假设主程序在User mode下运行)
方法一:
中断产生时会进入irq模式,所以当然有权限操作CPSR,因此如果我们仅仅清除CPSR的中断使能位使之能够在此响应中断的话看看有什么结果。图中进入中断的红色部分就是我们手动添加的代码。当IRQ1响应时,我们进入中断服务程序之前手动打开CPSR的irq中断使能位,那么如果当运行到一定时间新的中断IRQ2响应时,也会做同样的操作。而其中将PC存入到R14_irq这一步硬件帮我们做的操作就会出问题。因为这两个中断都是进入了irq模式,所以他们的R14_irq是同一个寄存器,中断2响应时会将原本中断1响应时保存在R14中的返回地址值修改,变成中断2响应之前的地址值,而这个值正是中断1的服务程序运行到被中断2打断的地方。当中断2结束返回时读取R14_irq的值,返回到中断1的被打断出,中断1继续运行,当返回时又读取R14_irq的值,这时候的值却是被中断2打断时的地址值,所以中断1会进入一个死循环。
所以,仅仅打开中断使能位而不进行现场保护操作是绝对不行的。
方法二:
在中断操作进入中断服务之前手动打开CPSR中断使能位,保存所有寄存器到堆栈,中断返回之前手动恢复堆栈中保存的寄存器。但是这种方法实际上并不可行,如果仅仅有IRQ1时是OK的,但是若有IRQ2,打断IRQ1,当IRQ2返回时此时硬件已经进入User Mode,而CPSR中保存的是之前IRQ1时的CPSR,其中mode位是irq。这就产生了冲突,能不能继续运行下都是个问题。其实可以这样理解,当IRQ2返回时已经进入User Mode模式,而若想返回到刚才的IRQ1,相当于要从User Mode跳到Irq模式执行IRQ1的剩余部分,而User Mode是无法自发跳转到其他模式的,除非调用软件中断,这其实就涉及到下面的方法:
方法三:
每次中断返回时调用软件中断指令,进入swi软件中断模式,这时其实已经进入SVC模式,所以有权限对CPSR进行操作,所以这种方法可以实现中断嵌套,而且实际上这也是很多OS在特定CPU上实现中断现场保护的方法。不过回过头想,所有这一切其实都是因为User Mode没有权限对CPSR进行操作所造成的,那么我们换一种思维,直接让主程序运行在有权限操作CPSR的SVC管理员模式不就好了吗?
方法四:
可以通过修改启动代码,放弃对User模式的使用,使进入main函数之前处于SVC模式,这样一来整个程序从头到尾都是处于SVC模式,具有全部权限进行寄存器的操作,这样一来,在中断返回时也不用像方法三一样,特意进入swi的异常入口进入SVC模式,并且需要保存进入SVC模式的现场。方法四中断返回时直接就是主程序运行的SVC模式,不用新进入另一个模式进行恢复现场操作,这样中断恢复时的时间也会快一些。实际上,这也是uCOS-II在ARM7系列上移植的推荐模式,很多移植的实例也是采用全程SVC模式的方式进行中断嵌套操作的。当然你也可以自己写程序用方法三的软件中断进行现场保护,是可以实现的,只是机器周期上需要多几步软件中断本身的模式切换操作。
【@.3 中断嵌套对于CPU硬件的反思】
最后我们可以分析,之所以ARM7要花这么大代价实现中断嵌套,完全是因为CPU内核的模式与特权造成的。所以如果CPU的内核没有那么多的限制,或者说CPU内核本身就支持简单的中断嵌套,我们的工作也就会好做很多了。我们可以看看Cortex M3系列的STM32F10x内核,模式和特权上就简单很多了:
Cortex的中断机制也跟ARM7截然不同。
可以看到这种内核模式与中断机制上简化了许多,很适合与OS在其上面的移植。
上一篇:【ARM学习笔记】ARM中断嵌套模式理解
下一篇:ARM Cortex-M处理器详解
推荐阅读
史海拾趣
在市场竞争日益激烈的环境下,晨翔电子始终坚持产品创新,不断推出具有市场竞争力的新产品。同时,公司还注重品牌建设,通过提升产品质量、优化服务流程、加强市场营销等方式,不断提高品牌知名度和美誉度。这一时期的努力,使得晨翔电子在电子连接器行业树立了良好的品牌形象。
德丰金属材料有限公司(简称“德丰金属”)是一家专业从事铝合金建筑型材加工的企业。随着市场竞争的加剧和环保要求的提高,公司意识到必须加快转型升级的步伐。为此,德丰金属加大了研发投入和技术改造力度,成功开发出了一系列符合绿色环保标准的新型铝合金型材产品。同时,公司还积极拓展国际市场,与多家国外知名企业建立了长期稳定的合作关系。通过不断的努力和创新,德丰金属成功实现了从传统制造业向绿色环保型制造业的转型升级。
随着技术的不断进步和市场的扩大,ALCOA公司的业务逐渐扩展到铝土矿开采、氧化铝精炼和原铝生产等领域。这种垂直整合的模式使得公司能够更好地控制原材料的质量和供应,提高了生产效率,也降低了成本。到了20世纪中期,ALCOA已经成为全球最大的铝业公司之一,几乎垄断了全球的铝市场。
第一次世界大战期间,铝因其轻质且强度高的特性,被广泛应用于航空和汽车工业。ALCOA公司借此机会迅速发展壮大,为军方和汽车制造商提供了大量的铝材。这种需求推动了公司的技术进步和生产规模的扩大,也奠定了ALCOA在电子行业中的领先地位。
在恩智浦剥离射频业务后,安谱隆迅速吸引了资本市场的关注。建广资产成功竞标,以18亿美元(约116.82亿元人民币)的价格收购了安谱隆。这一交易不仅显示了建广资产对安谱隆技术实力和市场潜力的认可,也为安谱隆未来的发展注入了新的动力。在建广资产的支持下,安谱隆开始了其独立发展的新篇章。
随着技术的不断进步,Ai公司在LED照明光源领域取得了重大突破。公司成功研发出了一系列高效、稳定、可靠的LED光源产品,这些产品不仅性能卓越,而且设计新颖,满足了市场对于高质量照明光源的迫切需求。同时,公司还不断创新,推出了多款具有自主知识产权的新型LED光源,进一步巩固了公司在行业内的领先地位。
我知道各位大哥们可能见惯了这类的帖子,也有些不屑,心里肯定在想:早干嘛去了 不认真学习! 小弟有错,但是小弟运气也不是一般倒霉,抽签抽的毕业论文是单片机,以前没学过,但是指导老师必须让我用单片 机做,先说说小弟的论文题目吧 简易信号 ...… 查看全部问答∨ |
①用ARM7。FLASH存储数据8M。板子有自己的时钟,可以校时,有看门狗,死机会重启。 ②一路RS232(COM1),一路RS485(COM2),一路RS232/RS485(COM3)可跳线设置。这三路串口独立。 ③两路RS232(COM4,COM5),这两路是共用的。程序设置哪路通讯 ...… 查看全部问答∨ |
I2C线上挂了3个器件,2个正常工作,有一个对它发送读写指令时,它能回应ACK信号,但是读写却得不到正确的值。 而我用另一个CPU控制时,却可以。另一个CPU不是我做的,但是我抓它的时序和我是一样的! 有谁知道吗?… 查看全部问答∨ |
|
使用RenamePartition函数想给某个partition改个名字,编译总是通不过,错误如下: D:\\。。。。。\\mount.cpp(339) : error C2018: unknown character \'0xa3\' D:\\。。。。。\\mount.cpp(339) : error C2018: unknown character \'0xbb\' 代码 ...… 查看全部问答∨ |
|
用了以下两种方法,都没有显示漏斗: 1. SetCursor(::LoadCursor(NULL,IDC_WAIT)) 2. CWaitCursor wait; wait.Restore(); 请各位指点思路 … 查看全部问答∨ |
|
朋友给我一个是实验板子,上面接了好多元件,6个数码管,步进机,A/D转换器,4*4键盘..液晶显示,可都不知道这些元件是怎么接到那些引脚上的,原来写的程序也不知道要怎么改.....… 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- 有奖直播报名:TI DLP®技术在汽车行业的创新应用——增强型抬头显示
- 如何用3个关键步骤,来确保下一代设计安全性,深入解读嵌入式设备DeepCover加密控制器,看视频答题赢好礼!
- 逛村田在线云展厅,了解通信、移动、工业+环境、健康四大领域的应用干货!
- EEWorld邀你来拆解(第7期)——拆拆减肥利器,看看跳绳里都有什么
- 1月22日下午14:00Mouser携手Maxim邀您观看有奖直播:深入浅出可穿戴健康监测
- 有奖直播|恩智浦嵌入式人机界面解决方案详解
- 可靠QTouch技术集成邻键抑制(AKS)功能,适用任何触摸应用领域
- 恩智浦LPC1500开发体验有奖征集
- 安森美半导体——FOD83xx/T系列来袭! 答题赢好礼,更可免费申请样片