历史上的今天

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

正在发生

2021年10月20日 | ARM处理器架构------可嵌套中断的实现

发布者:RadiantGaze 来源: eefocus关键字:ARM  处理器架构 手机看文章 扫描二维码
随时随地手机看文章

传统ARM中IRQ是作为一种系统异常出现的。对于ARM核来说,有且仅有一个称为IRQ的系统异常。而ARM对于IRQ的处理一般通过异常向量找到IRQ的中断处理程序。当进入IRQ中断处理程序之后,ARM自动屏蔽IRQ,也就是说在中断响应过程中是忽略之后到来的中断请求的。即使使用了VIC,VIC也仅仅是悬起后来的中断请求。也就是说,传统ARM的中断是不可嵌套、不可抢占的。


不过,ARM给了我们一种权利,那就是在中断处理程序中可以手动打开IRQ,这样在前一个IRQ响应的过程中,就可以被后来的中断所打断。就给我们提供了一种用软件解决中断嵌套的途径。


中断的过程我们都十分清楚:保护现场à响应中断à恢复现场。ARM对于每一种异常都有相应的堆栈寄存器,且会自动切换,互不影响。所以自然而然地,在嵌套中,我们可以用SP_irq来保护现场和恢复现场。流程如下所示:

 

1.      第一次进入中断

2.      ARM自动保存CPSR到SPSR_irq

3.      ARM自动保存PC到LR_irq

4.      ARM自动关闭IRQ使能

5.      保存通用寄存器、LR_irq、SPSR_irq到SP_irq所指示的堆栈中

6.      打开IRQ使能位

7.      根据中断号进行中断服务

7.1    第二次进入中断,开始嵌套

7.2    ARM自动保存CPSR到SPS_irq

7.3    ARM自动保存PC到LR_irq

7.4    ARM自动关闭IRQ使能

7.5    保存通用寄存器、LR_irq、SPSR_irq到SP_irq所指示的堆栈中

7.6    打开IRQ使能位

7.7    根据中断号进行中断服务

7.8    关闭IRQ使能位

7.9    从SP_irq堆栈中恢复通用寄存器、LR_irq、SPSR_irq

7.10通过LR_irq跳转回到7

7.11ARM自动从SPSR_irq恢复CPSR

8.      关闭IRQ使能位

9.      从SP_irq堆栈中恢复通用寄存器、LR_irq、SPSR_irq

10.  通过LR_irq跳转回到到任务程序

11.  ARM自动从SPSR_irq恢复CPSR

 

这样就实现了嵌套,而且只要堆栈够大,可以嵌套很多层。不考虑优先级,或者把优先级教给中断控制器管理,这样已经不错了吧,虽然不愿意这么说,但是问题还是来了。


在上面的流程中,有一步是根据中断号进行中断服务。对于不同的中断源,我们一般都会用不同函数来写中断服务,这样不仅清晰,也利于将不同功能的模块分割开。这样我们就需要将这步变为:根据中断号进入服务子程序。这步中,我们会牵涉到函数调用。在函数调用过程中,一般都会先将PC保存在LR_irq中,在返回时,再将LR_irq恢复到PC。这也正是LR的作用所在。


正是这个事实,导致了问题的发生。想象这种情况:当我们进入服务子程序后,此时LR_irq正是我们程序的返回地址。这时,第二个中断到来了,回忆一下中断发生时ARM自动做了什么,ARM将PC保存到了LR_irq中!就这样,LR_irq被篡改了,因为我们无法预料到中断什么时候到来,我们也就根本无法保存这个被篡改的LR_irq。程序响应好第二个中断后,一路返回到这个LR_irq,毫无意外的,就跑飞了。


很扫兴吧,不过我们自然有办法解决这个问题。办法就是在进入服务子程序之前,先将系统转换到SVC状态,这样,子程序被调用时返回地址就会被保存在LR_svc中,也就不会再被第二个中断所篡改。流程如下,和第一次不同的地方都用红色标注。


为什么要保存r0-r3, 保存lr_svc不就够了吗?


1.      第一次进入中断

2.      ARM自动保存CPSR到SPSR_irq

3.      ARM自动保存PC到LR_irq

4.      ARM自动关闭IRQ使能

5.      保存通用寄存器、LR_irq、SPSR_irq到SP_irq所指示的堆栈中

6.      更改系统状态为SVC

7.      保存R0-R3,LR_svc到SP_svc所指示的堆栈中

8.      打开IRQ使能位

9.      根据中断号进入中断服务子程序

9.1    第二次进入中断,开始嵌套

9.2    ARM自动保存CPSR到SPS_irq

9.3    ARM自动保存PC到LR_irq

9.4    ARM自动关闭IRQ使能

9.5    保存通用寄存器、LR_irq、SPSR_irq到SP_irq所指示的堆栈中

9.6    更改系统状态为SVC

9.7    保存R0-R3,LR_svc到SP_svc所指示的堆栈中

9.8    打开IRQ使能位

9.9    根据中断号进入中断服务子程序

9.10关闭IRQ使能位

9.11从SP_svc所指示的堆栈中恢复R0-R3,LR_svc

9.12更改系统状态为IRQ

9.13从SP_irq堆栈中恢复通用寄存器、LR_irq、SPSR_irq

9.14通过LR_irq跳转回到9

9.15ARM自动从SPSR_irq恢复CPSR

10.  关闭IRQ使能位

11.  从SP_svc所指示的堆栈中恢复R0-R3,LR_svc

12.  更改系统状态为IRQ

13.  从SP_irq堆栈中恢复通用寄存器、LR_irq、SPSR_irq

14.  通过LR_irq跳转回到到任务程序

15.  ARM自动从SPSR_irq恢复CPSR

 

这样我们既可以用中断服务子程序,也不怕LR被篡改了。我们再来看一下嵌套过程中的堆栈使用情况。在进入SVC状态之前,使用IRQ的堆栈,保存嵌套所需的通用寄存器、LR_irq和SPSR_irq。进入SVC状态之后,使用SVC堆栈,需要保存调用函数规定的R0-R3,LR_svc。当然在中断服务例程中,也是使用SVC堆栈。可见两个状态的堆栈都被使用了。当然,因为中断服务例程使用SVC堆栈,我们也可以考虑将嵌套所需的堆栈也放到SVC中,这样就不需要IRQ堆栈了。流程上和前面这种方法很相似,只不过要将保存LR_irq和SPSR_irq的时间放到进入SVC态之后,方法可以是通过通用寄存器拷贝。最后也不必再返回IRQ态,可以直接通过SPSR_svc和LR_svc来推出中断处理程序。


程序贴在下面,用的是堆栈分开的方法,只是示例。

  1. __asm void IRQ_Handler(void){  

  2.       PRESERVE8  

  3.       IMPORT handler1      

  4.        

  5.       // STORE LR_irq & SPSR_irq  

  6.       SUB             LR, LR, #4  

  7.       MRS             R0, SPSR  

  8.       STMFD           SP!, {R0, LR}  

  9.    

  10.       // INTO SVC MODE  

  11.       MRS             R0, CPSR  

  12.       BIC             R0, #0x1f  

  13.       ORR             R0, #0x13  

  14.       MSR             CPSR_C, R0  

  15.        

  16.       // STORE REGISTORS OF SVC MODE  

  17.       STMFD           SP!, {R0-R3,LR}  

  18.        

  19.       // ENABLE IRQ  

  20.       MRS             R0, CPSR  

  21.       BIC             R0, #0x80  

  22.       MSR             CPSR_C, R0  

  23.        

  24.       // GO TO HANDLER  

  25.       BL              handler1  

  26.        

  27.       // RESTORE REGISTORS OF SVC MODE  

  28.       LDMFD           SP!, {R0-R3,LR}  

  29.        

  30.       // DISABLE IRQ  

  31.       MRS             R0, CPSR  

  32.       ORR             R0, #0x80  

  33.       MSR             CPSR_C, R0        

  34.        

  35.       // INTO IRQ MODE  

  36.       MRS             R0, CPSR  

  37.       BIC             R0, #0x1f  

  38.       ORR             R0, #0x12  

  39.       MSR             CPSR_C, R0  

  40.        

  41.       // RESTORE LR_irq & SPSR_irq  

  42.       LDMFD           SP!, {R0, LR}  

  43.       MSR             SPSR_CFX, R0  

  44.        

  45.   // EXIT IRQ  

  46.       MOVS            PC, LR   

  47. }  


关键字:ARM  处理器架构 引用地址:ARM处理器架构------可嵌套中断的实现

上一篇:mini2440裸机编程--------触摸屏驱动
下一篇:ARM处理器架构-----异常/中断处理

推荐阅读

        近日,三星Galaxy Book2在纽约正式发布,这款产品最大的亮点就是搭载了高通骁龙850移动计算平台。该芯片具备千兆级LTE连接以及超长的续航,可为消费者带来畅快的操作体验。搭载高通骁龙850移动计算平台的三星Galaxy Book2(图片来自官方)  本届发布会上,Qualcomm全球产品市场副总裁莫珂东出席了此次发布会,他表示:“PC用户应该享...
互联网、、人工智能等技术与机器人产业加速融合,促使机器人技术及其产品也发生天翻地覆的变化。大象机器人以全新逻辑,持续在机器人算法、控制器、及产品开发方面创新和投入,布局安全机器人细分市场,以满足市场多元化的需求。 伴随智能化、信息化、网络化的不断发展,机器人技术及其产品也发生着天翻地覆的变化。在汽车行业,工业机器人一改以往固定...
10月16日,FUS猎云网2020年度人工智能产业峰会在北京金茂万丽酒店隆重举行,近百位知名资本大咖,独角兽创始人、创业风云人物及近千位创业者共聚一堂。在由峰瑞资本副总裁刘鹏琦主持、以《后疫情时代,人工智能落地应用何处所在》为议题的高峰论坛上,埃睿迪合伙人&副总裁赵华伟、睿帆科技联合创始人&CTO王雪、云迹科技战略合作副总裁杨子和宾果智能CEO...
上海诺基亚贝尔股份有限(以下简称“诺基亚贝尔”)是诺基亚集团和中国保利集团旗下华信邮电共同组建的中外合资企业,在中国设立了研发、市场、服务、全球交付、供货等全产业链布局。随着全面数字化转型的推进,诺基亚贝尔数字化办公室灵活运用各种新兴技术,开启了数字化转型的华丽变身。 其中,诺基亚贝尔选择了UiPath RPA作为转型的一个抓手,在合...

史海拾趣

问答坊 | AI 解惑

DSP入门知识

Digital Signal Processing 数字信号处理作为一个案例研究,我们来考虑数字领域里最通常的功能:滤波。简单地说,滤波就是对信号进行处理,以改善其特性。例如,滤波可以从信号里清除噪声或静电干扰,从而改善其信噪比。为什么要用微处理器,而不是 ...…

查看全部问答∨

辰汉电子推出稳定可靠的4路视频输入方案

辰汉电子推出稳定可靠的4路视频输入方案                        辰汉电子推出稳定可靠的4路视频输入方案…

查看全部问答∨

上位机控制的液晶电子时钟(提供VB,C语言程序)

上位机控制的液晶电子时钟(提供VB,C语言程序)…

查看全部问答∨

TI超低功耗 MSP430 MCU 设计大赛开始了!

刚看到的新闻,有兴趣的可以看看: 德州仪器宣布启动 MSP430 微控制器 (MCU) 超低功耗设计挑战赛。比赛将在 2009 年 10 月 19 日至 2010 年 1 月 19 日期间进行。参赛选手将提交使用业界最低功耗 MSP430 MCU 与开发工具、面向从日常实用解决方案到 ...…

查看全部问答∨

我们敬爱的SOSOMM今天遇到麻烦了,大家看能否帮忙想想办法

本帖最后由 ddllxxrr 于 2016-1-7 17:19 编辑 同志们,我西门今天在这里说一件事.在半小时前,我们的SOSOMM打来电话,问我刚刚可曾在QQ上要她汇款给我,我说没有.因为我今天一直在开会.她说:糟了,刚有人在网上用你的QQ让我汇款,我汇出去了........... ...…

查看全部问答∨

LM3S系列ARM 的应用笔记(Luminary系列ARM)

LM3S系列ARM 的应用笔记(Luminary系列ARM)      欢迎大家下载,:$ …

查看全部问答∨

十万火急,,哪个帮忙看看这个消防设施如何设计???

搞火灾报警的我想知道 1.电路图原理 2.单片机程序如何写…

查看全部问答∨

急问:WinCE下用GPRS串口猫 不能读串口

我买了一个串口SIM300GPRS模块,想用在WinCE上拨号上网。 当在PC上时,把模块连到COM1上,发送"AT/r",收到:at OK 但是在安装了WinCE的开发板上,把模块连到com1上,设置同样的串口参数,发送"AT/r",却收不到任何数据。在程序中使用Rea ...…

查看全部问答∨

做POS机的软件开发前景如何啊

我在公司做的是银行POS系统,C语言开发的,不知道前景如何啊,顺便给点专业点的意见…

查看全部问答∨

release下能用OutputDebugString() ?

ce release 下能用OutputDebugString()打印输出吗? 如果不可以,请问用什么函数?…

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

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

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

更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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