历史上的今天

今天是:2024年10月25日(星期五)

正在发生

2021年10月25日 | uCOS-II的中断-ARM7实现中断嵌套的方法探究

发布者:eta17 来源: eefocus关键字:uCOS-II  中断嵌套 手机看文章 扫描二维码
随时随地手机看文章

在uCOS-II,或者是任何一个可剥夺型OS系统中,中断嵌套是一个必须要解决的问题。从结论上来说,并不是所有的CPU都支持中断嵌套的,即便是ARM系列内核。对于ARM7系列,例如LPC2xxx系列芯片,硬件上是不支持中断嵌套的,而对于新的CortexM3系列,中断嵌套是可配置的,但是中断嵌套时保存现场的操作并不完整,并没有把R0~R15所有寄存器都保存到堆栈中,而是只保存R0~R4。这就需要我们手动软件实现全部或部分的中断现场保护机制。不过首先通过分析ARM7系列芯片来看看中断嵌套的硬件要求。


ARM7系列的内核一共有7中模式,如下图所示:

image

其中

(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的结构如下:

 

image

其中CPSR的末尾几位即保存了当前的CPU模式。


当每种异常发生,硬件上会做以下操作:

1.CPSR的Mode位置位成当前模式,控制位置位

2.保存打断前模式的R0~R14到对应寄存器,CPSR到SPSR。

3.新模式的PC跳转到内存指定地址,即异常入口地址。

image

这就需要我们在启动代码的对应地址段协商地址偏移的标签。下面对几个常用的异常进行介绍:


一.Reset。发生在首次上电或者手动按下Reset键(CPU的Reset引脚给个低电平):

image

上电或Reset之后一般会进入固化在flash中的bootloader,bootloader的工作流程比较复杂,大致上需要判断一些引脚电平来进入相应的模式。比如若判断到ISP引脚(P0.14 in LPC2119)低电平,会进入ISP模式烧写程序。判断Boot0和Boot1的电平组合可以进入对应的外部flash的启动。正常情况下会进入flash中的0x00000000地址的Reset入口。按照启动代码的编写进行一些必要的寄存器操作,以及初始化各个模式的堆栈,最后进入到main函数。


二.Irq中断。一般中断可以注册成irq或者fiq中断。若注册为irq中断时的流程如下:

image

1.CPSR模式位置为IRQ模式

2.将当前的PC存入到irq的R14中,也就是程序的返回地址,当退出irq时会从这里取出地址给PC,程序回到原处。

3.CPSR中irq使能位清零,禁止irq中断响应。可以看到这就是不能中断嵌套的一个重要原因,因为硬件上会禁止irq的响应,除非你手动将其打开。

4.程序跳转到irq的入口地址,按照启动代码执行操作。比如Keil中会跳转到VicVectAddr地址,即向量中断的入口地址,之后交给向量中断控制器来进行操作。


三.FIQ

image

Fiq异常基本跟irq异常的流程一致,除了仅仅会将CPSR中的irq和fiq使能位都清零,即不能再响应irq和fiq中断了,并且跳入到fiq的入口地址。当然按照Keil中的启动代码这里是一个死循环,即若不修改启动代码是不能使用fiq中断的。不过对于fiq这种快速中断机制,若我们能手动实现中断嵌套完全可以不用fiq中断,全部利用我们自己的代码来实现。比如uCOS-II中,所有中断都是irq中断,不需要fiq中断。


四.SWI(软件中断)

image

软件中断不同于其他的中断或异常,这是需要在程序中自己编程调用软件中断命令来触发的。调用后会将CPSR置为SVC(supervisor)管理员模式,存入PC到R14_swi,禁止irq和fiq中断,并且跳转到swi异常入口。这种方式的特点就是进入了一个没有权限限制的SVC模式,这样就可以进行对CPSR的读写操作了。这种方式带给我们很多遐想,我们可以用软件中断进行模式切换,进而进行寄存器的保存操作即保存中断现场,从而可以实现中断嵌套。


【@.2 中断嵌套的方法探究】

中断嵌套的核心思想是,保存当前CPU寄存器到堆栈中,即保存中断现场,并且打开中断使能位允许中断再次响应。但是由于CPU不同模式的权限区分导致这一想法不能简单的实现。比如,很多启动代码中在进入CPU前会进入没有权限的User模式,但是User模式是没办法对CPSR进行读写操作的,也就是说没办法直接在User模式中将CPSR压入到堆栈,同时不能通过向CPSR的模式位写入模式代码切换到其他的模式。

image

仅仅考虑irq中断,我们来回忆一下整个中断响应的流程。首先中断有输入,CPSR模式置位为irq模式,将当前PC值保存到irq模式的R14中,并且清除CPSR的irq标志位使得不能再次响应irq中断,最后跳转到irq中断入口地址。进过启动代码和我们的程序配置,最终会进入到我们编写中断服务程序中,当这个程序结束时会读取之前保存在R14_irq中的地址值给PC,程序回到原来中断处继续运行。在此基础上我们考虑集中方法实现中断嵌套。(以下假设主程序在User mode下运行)

image

方法一:

中断产生时会进入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会进入一个死循环。


所以,仅仅打开中断使能位而不进行现场保护操作是绝对不行的。

 image

方法二:

在中断操作进入中断服务之前手动打开CPSR中断使能位,保存所有寄存器到堆栈,中断返回之前手动恢复堆栈中保存的寄存器。但是这种方法实际上并不可行,如果仅仅有IRQ1时是OK的,但是若有IRQ2,打断IRQ1,当IRQ2返回时此时硬件已经进入User Mode,而CPSR中保存的是之前IRQ1时的CPSR,其中mode位是irq。这就产生了冲突,能不能继续运行下都是个问题。其实可以这样理解,当IRQ2返回时已经进入User Mode模式,而若想返回到刚才的IRQ1,相当于要从User Mode跳到Irq模式执行IRQ1的剩余部分,而User Mode是无法自发跳转到其他模式的,除非调用软件中断,这其实就涉及到下面的方法:

image

方法三:

每次中断返回时调用软件中断指令,进入swi软件中断模式,这时其实已经进入SVC模式,所以有权限对CPSR进行操作,所以这种方法可以实现中断嵌套,而且实际上这也是很多OS在特定CPU上实现中断现场保护的方法。不过回过头想,所有这一切其实都是因为User Mode没有权限对CPSR进行操作所造成的,那么我们换一种思维,直接让主程序运行在有权限操作CPSR的SVC管理员模式不就好了吗?

image

方法四:

可以通过修改启动代码,放弃对User模式的使用,使进入main函数之前处于SVC模式,这样一来整个程序从头到尾都是处于SVC模式,具有全部权限进行寄存器的操作,这样一来,在中断返回时也不用像方法三一样,特意进入swi的异常入口进入SVC模式,并且需要保存进入SVC模式的现场。方法四中断返回时直接就是主程序运行的SVC模式,不用新进入另一个模式进行恢复现场操作,这样中断恢复时的时间也会快一些。实际上,这也是uCOS-II在ARM7系列上移植的推荐模式,很多移植的实例也是采用全程SVC模式的方式进行中断嵌套操作的。当然你也可以自己写程序用方法三的软件中断进行现场保护,是可以实现的,只是机器周期上需要多几步软件中断本身的模式切换操作。


【@.3 中断嵌套对于CPU硬件的反思】

最后我们可以分析,之所以ARM7要花这么大代价实现中断嵌套,完全是因为CPU内核的模式与特权造成的。所以如果CPU的内核没有那么多的限制,或者说CPU内核本身就支持简单的中断嵌套,我们的工作也就会好做很多了。我们可以看看Cortex M3系列的STM32F10x内核,模式和特权上就简单很多了:

 image

Cortex的中断机制也跟ARM7截然不同。

 image

可以看到这种内核模式与中断机制上简化了许多,很适合与OS在其上面的移植。


关键字:uCOS-II  中断嵌套 引用地址:uCOS-II的中断-ARM7实现中断嵌套的方法探究

上一篇:【ARM学习笔记】ARM中断嵌套模式理解
下一篇:ARM Cortex-M处理器详解

推荐阅读

集微网消息,众所周知,评测一款手机的性能,最好是用跑分软件,因为数据显示的比较直观,其中跑分软件有Geekbench、鲁大师、PCMark、3D Mark、BndroBench等,要说当中最有名的跑分软件要数安兔兔了,它经常在各大手机厂商的发布会上亮相。        所谓人红是非多,对于跑分软件来说也是如此,因为某厂商的跑分成绩老是名列前茅,不少人对安兔兔...
由于近期的需要,开始学习TI的MSP430 MCU。脑子不好使记不下来,只能辛苦一一敲在这里,便于大脑短路时随时查阅。首先学习了F149的时钟系统。F149拥有一个名为DCOCLK的内部数控振荡器,可外接两个晶振,通常一个晶振提供32768Hz实时时钟(LFXT1CLK),另一个晶振提供最大8MHz的系统主时钟(XT2CLK)。以上3个时钟源可以产生三个时钟信号:ACLK:辅助时钟...
Galaxy S20 FE 是今年发布的最实惠的 Galaxy S 系列智能手机。它具有 S 旗舰系列的所有核心功能,遗憾的是,某些早期用户遇到了屏幕的触摸问题。近日,三星已经通过软件更新对其进行了修复。上周,有报道称几批 Galaxy S20 FE 用户遇到了和触摸输入有关的问题。用户面临的问题包括重影触摸,无法区分敲击和手势以及根本不响应触摸等。据 SamM...
广告摘要声明广告2021年,怀揣着“射月”梦想的极智嘉,又向前迈进了重要的几大步。极智嘉创始人兼CEO郑勇曾公开表示:“极智嘉自创立之初就怀揣着以AI和机器人技术为企业、为社会创造价值的初心。基于客户需求,我们逐步拓展业务版图,从一款机器人产品、到全品类机器人矩阵,再到发力智能物流解决方案,始终希望能够帮助企业应对复杂多样的痛点和场景需...

史海拾趣

问答坊 | AI 解惑

感谢您8辈子祖宗 HELP !!前辈来解救我吧

我知道各位大哥们可能见惯了这类的帖子,也有些不屑,心里肯定在想:早干嘛去了 不认真学习! 小弟有错,但是小弟运气也不是一般倒霉,抽签抽的毕业论文是单片机,以前没学过,但是指导老师必须让我用单片 机做,先说说小弟的论文题目吧 简易信号 ...…

查看全部问答∨

委托设计控制器的原理图和PCB板

①用ARM7。FLASH存储数据8M。板子有自己的时钟,可以校时,有看门狗,死机会重启。 ②一路RS232(COM1),一路RS485(COM2),一路RS232/RS485(COM3)可跳线设置。这三路串口独立。 ③两路RS232(COM4,COM5),这两路是共用的。程序设置哪路通讯 ...…

查看全部问答∨

如何提高SD卡读写速度?

YLP2440的板子,应用程序是放在SD卡上的,大小5M多。运行时程序启动特别慢,大概十多秒。请问各位大侠,有什么办法能提高读写SD卡速度?…

查看全部问答∨

I2C的奇怪问题,高手进!

I2C线上挂了3个器件,2个正常工作,有一个对它发送读写指令时,它能回应ACK信号,但是读写却得不到正确的值。 而我用另一个CPU控制时,却可以。另一个CPU不是我做的,但是我抓它的时序和我是一样的!  有谁知道吗?…

查看全部问答∨

RenamePartition(...) 编译错误

使用RenamePartition函数想给某个partition改个名字,编译总是通不过,错误如下: D:\\。。。。。\\mount.cpp(339) : error C2018: unknown character \'0xa3\' D:\\。。。。。\\mount.cpp(339) : error C2018: unknown character \'0xbb\' 代码 ...…

查看全部问答∨

wince中如何显示漏斗等待图标

用了以下两种方法,都没有显示漏斗: 1.   SetCursor(::LoadCursor(NULL,IDC_WAIT)) 2.   CWaitCursor wait;   wait.Restore(); 请各位指点思路 …

查看全部问答∨

关于设备命名Device\Harddisk#\dr# 的意思

如题,主要是dr代表什么意思?…

查看全部问答∨

谁有 at89s51实验板的资料啊?

朋友给我一个是实验板子,上面接了好多元件,6个数码管,步进机,A/D转换器,4*4键盘..液晶显示,可都不知道这些元件是怎么接到那些引脚上的,原来写的程序也不知道要怎么改.....…

查看全部问答∨

msp430缺点

总线不开放,外接数据存储器很慢,而且程序麻烦 i/o口不够用 有同意的吗? 怎么解决…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved