ARM 汇编若干问题(一般中断问题与软中断SWI分析)

发布者:飘然出尘最新更新时间:2016-08-05 来源: eefocus关键字:ARM  汇编若  中断问题  软中断  SWI分析 手机看文章 扫描二维码
随时随地手机看文章
      一般中断问题分析
 
      ARM CPU 在上电启动之后会自动进入SVC模式,也是ARM上电后的默认工作模式,如果发生了中断,ARM会自动切换到外部中断模式(IRQ为例),如果是FIQ那么就切换到FIQ模式下面进行处理。
 
      在每一个模式下面都有一组可以访问的寄存器,SVC和IRQ模式下的R0~R12是共用的,这就涉及到寄存器Rx内容的保存:压栈,恢复:出栈操作。在IRQ处理中用到了哪些Rx就要进行相应的保护与恢复,否则当处理退出IRQ时就会出错误。
 
      发生中断时候,ARM是要首先完成当前正在执行的指令,然后再进行为IRQ的必要处理。具体的内容如下:
 
将当前CPSR,保存到IRQ模式下的的SPSR_irq,进行备份。
把PC-4所指向的地址放到LR。LR = PC-4。为中断返回是有个退出点。
强制PC= 0X0000'0018,指向IRQ的中断向量的地址,通常地址0X0000'0018放置一条跳命令,跳转到IRQ的中断服务函数的入口地址。B   HANDLERIRQ.
补充一点:ARM的正在执行的指令地址x,和取指令的地址PC,地址y,之间是差x=y-8.
 
 
 
                                     难点:中断服务函数退出地址的计算
 
    PC-8        --------------->|正在执行的指令的地址|0x120  如果此时发生中断了
 
    PC-4        --------------->|真正的中断返回点地址|0x124
 
    PC          ---------------->|取指令的地址       |0x128      
 
通过上述分析可以得出:真正的中断返回点地址是0X124,真正应该存入LR的地址是0X124.但是实际情况是:0X128 ?????
 
分析:ARM 总是执行完当前的指令才会处理其他事情,问题就出在这里,当ARM执行完当前的指令的时候PC已经更新了,如下
 
 PC = PC+4;PC = 0X128+4 = 0X12C,存放到LR=PC-4; LR = 0X12C-4=0X128;这个0X128不是真正的中断函数的返回点。真正的函数返回点是0X124.怎么办???? 
 
在给PC恢复数值是进行这样的处理下:LR = LR-4,PC=LR.   ==>SUBS PC,LR,#4.  并且自动恢复CPSR=SPSR_irq
 
 
 
SWI软中断问题分析
 
    软中断和一般的中断处理流程有不同的地方:CPU在执行指令时候,遇见一般的中断,先要执行完当前的指令,更新PC,然后把LR=PC-4.SPSR_irq=CPSR.CPSR=XXX.进入IRQ中断处理过程。真正的断点返回地址是:LR-4。在返回时需要进行地址的调整。 ==>SUBS PC,LR,#4.并且自动恢复CPSR=SPSR_irq。
 
   swi软中断还是很特别的玩意,软中断发生的时候,CPU切换到SVC工作模式,PC的数值不进行更新,即:不是等到把当前的指令执行完毕之后在执行其他的处理。而是立刻处理。CPU立即把软中断的返回地址写入LR中。LR=PC-4,这是真正的返回地址,PC的数据不更新。!!!!。SWI中断返回地址不需要调整就是正确的地址。
 
   然后就是软中断编号的计算,方法:发生软中断时那条指令地址里面数据的低24位放的就是软中断标号,从中取出来放到R0里面,R0是函数的第一个参数,也是存放函数返回结果的地方。
 
   HandlerSWI
 
    STMFD SP!,{R0-R3,R12,LR},LR存放的是swi真正的软中断要返回的中断地址点。
 
    LDR   R0,[LR,#-4];找到到底在哪一条指令时发生了软中断,很明显:就是LR真正断点返回地址的上面一条地址。LR-4或者PC-8。找个这个指令的地址,取出其中的内容。软中断的编号就是存放在发生软中断那条指令地址的低24位数据里面。
 
    BIC  R0,R0,#0xFF00'0000,低24位是软中断号
 
    BL  my_swi_handler;
 
    LDMFD SP! ,{R0-R3,R12,PC}^,其中^表示CPSR=SPSR_svc.只能手动恢复。
 
使用方法
 
 extern void my_swi_handler(unsigned int num);
 
      __swi(0x1)led_one(void);
 
     __swi(0x2)led_two(void);
 
 
 
main()
 
{
 
   led_one();
 
 delay(100ms);
 
led_two();
 
}
 
void my_swi_handler(unsigned int num)
 
{
 
      case 0x1:{ do_some_thing}break;
 
      case 0x2:{do_another_thing}break;
 
      default:    break;
 
}
关键字:ARM  汇编若  中断问题  软中断  SWI分析 引用地址:ARM 汇编若干问题(一般中断问题与软中断SWI分析)

上一篇:ARM 汇编与C调用的若干问题(一般函数调用情况)
下一篇:ARM-LINUX-GCC设置环境变量

小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved