您的位置 首页 IOT

传统ARM中可嵌套的IRQ程序

传统ARM中IRQ是作为一种系统异常出现的。对于ARM核来说,有且仅有一个称为IRQ的系统异常。而ARM对于IRQ的处理一般通过异常向量找到IRQ的中…

传统ARM中IRQ是作为一种体系反常呈现的。关于ARM核来说,有且仅有一个称为IRQ的体系反常。而ARM关于IRQ的处理一般经过反常向量找到IRQ的中止处理程序。当进入IRQ中止处理程序之后,ARM主动屏蔽IRQ,也就是说在中止呼应进程中是疏忽之后到来的中止请求的。即便运用了VIC,VIC也仅仅是悬起后来的中止请求。也就是说,传统ARM的中止是不可嵌套、不行抢占的。

不过,ARM给了咱们一种权力,那就是在中止处理程序中能够手动翻开IRQ,这样在前一个IRQ呼应的进程中,就能够被后来的中止所打断。就给咱们供给了一种用软件处理中止嵌套的途径。

中止的进程咱们都非常清楚:维护现场à呼应中止à康复现场。ARM关于每一种反常都有相应的仓库寄存器,且会主动切换,互不影响。所以天然而然地,在嵌套中,咱们能够用SP_irq来维护现场和康复现场。流程如下所示:

1.2.3.4.5.6.7.7.17.27.37.47.57.67.77.87.97.10经过LR_irq跳转回到7

7.11ARM主动从SPSR_irq康复CPSR

8.9.10.11.

这样就完成了嵌套,并且只需仓库够大,能够嵌套很多层。不考虑优先级,或许把优先级教给中止控制器办理,这样现已不错了吧,尽管不愿意这么说,可是问题仍是来了。

在上面的流程中,有一步是依据中止号进行中止服务。关于不同的中止源,咱们一般都会用不同函数来写中止服务,这样不只明晰,也利于将不同功用的模块分割开。这样咱们就需求将这步变为:依据中止号进入服务子程序。这步中,咱们会牵涉到函数调用。在函数调用进程中,一般都会先将PC保存在LR_irq中,在回来时,再将LR_irq康复到PC。这也正是LR的效果地点。

正是这个现实,导致了问题的产生。幻想这种状况:当咱们进入服务子程序后,此刻LR_irq正是咱们程序的回来地址。这时,第二个中止到来了,回想一下中止产生时ARM主动做了什么,ARM将PC保存到了LR_irq中!就这样,LR_irq被篡改了,由于咱们无法预料到中止什么时候到来,咱们也就底子无法保存这个被篡改的LR_irq。程序呼应好第二个中止后,一路回来到这个LR_irq,毫无意外的,就跑飞了。

很败兴吧,不过咱们天然有办法处理这个问题。办法就是在进入服务子程序之前,先将体系转换到SVC状况,这样,子程序被调用时回来地址就会被保存在LR_svc中,也就不会再被第二个中止所篡改。流程如下,和第一次不同的当地都用赤色标示。

1.2.3.4.5.6.7.8.9.9.19.29.39.49.59.69.79.89.99.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.11.12.13.14.15.

这样咱们既能够用中止服务子程序,也不怕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来推出中止处理程序。

程序贴在下面,用的是仓库分隔的办法,仅仅示例。

[cpp]view plaincopy

  1. __asmvoidIRQ_Handler(void){
  2. PRESERVE8
  3. IMPORThandler1
  4. //STORELR_irq&SPSR_irq
  5. SUBLR,LR,#4
  6. MRSR0,SPSR
  7. STMFDSP!,{R0,LR}
  8. //INTOSVCMODE
  9. MRSR0,CPSR
  10. BICR0,#0x1f
  11. ORRR0,#0x13
  12. MSRCPSR_C,R0
  13. //STOREREGISTORSOFSVCMODE
  14. STMFDSP!,{R0-R3,LR}
  15. //ENABLEIRQ
  16. MRSR0,CPSR
  17. BICR0,#0x80
  18. MSRCPSR_C,R0
  19. //GOTOHANDLER
  20. BLhandler1
  21. //RESTOREREGISTORSOFSVCMODE
  22. LDMFDSP!,{R0-R3,LR}
  23. //DISABLEIRQ
  24. MRSR0,CPSR
  25. ORRR0,#0x80
  26. MSRCPSR_C,R0
  27. //INTOIRQMODE
  28. MRSR0,CPSR
  29. BICR0,#0x1f
  30. ORRR0,#0x12
  31. MSRCPSR_C,R0
  32. //RESTORELR_irq&SPSR_irq
  33. LDMFDSP!,{R0,LR}
  34. MSRSPSR_CFX,R0
  35. //EXITIRQ
  36. MOVSPC,LR
  37. }

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/iot/277077.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部