swi原理与应用

<script type="text/javascript"> </script> <script type="text/javascript"> </script>

1).SWI指令的使用

    AREA ADDREG,CODE,READONLY

    ENTRY

MAIN

                ADR r0,ThunbProg 1 ;(为什么要加1呢?因为BX指令跳转到指定的地址执行程序 时, 若   (BX{cond} Rm)Rm的位[0]为1,则跳转时自动将CPSR中的标志T置位即把目标 代码解释为 Thunb代码)

                BX r0

                CODE16

ThunbProg

                mov r2,#2

    mov r3,#3

    add r2,r2,r3

    ADR r0,ARMProg

    BX ro

    CODE32

ARMProg

    mov r4,#4

    mov r5,#5

    add r4,r4,r5

stop         mov r0,#0x18

                LDR r1,=0x20026
    
                SWI 0x123456

END

 SWI--软中断指令:

 SWI指令用于产生软中断,从拥护模式变换到管理模式,CPSR保存到管理模式的SPSR中.

 SWI{cond} immed_24 ;immed_24为软中断号(服务类型)

使用SWI指令时,通常使用以下两种方法进行传递参数,SWI 异常中断处理程序就可以提供相关的服务,这两种方法均是用户软件协定.SWI异常中断处理程序要通过读取引起软中断的SWI指令,以取得24位立即数.

(1) 指令中的24位立即数指定了用户请求的服务类型,参数通过通用寄存器传递.

        mov r0,#34 ;设置子功能号位34

        SWI 12 ;调用12号软中断

(2) 指令中的24位立即数被忽略,用户请求的服务类型有寄存器R0的值决定,参数通过其他的通用寄存器传递.

        mov r0,#12 ;调用12号软中断

        mov r1,#34 ;设置子功能号位34

        SWI  0

在SWI异常中断处理程序中,取出SWI立即数的步骤为:首先确定引起软中断的SWI指令是ARM指令还是Thunb指令,这可通过对SPSR访问 得到;然后取得该SWI指令的地址,这可通过访问LR寄存器得到;接着读出指令,分解出立即数.如如下程序:

           T_bit EQU 0X20
   
            SWI_Handler 
   
            STMFD SP!,{R0-R3,R12,LR} ;现场保护
   
            MRS R0,SPSR ;读取SPSR
   
            STMFD SP!,{R0} :保存SPSR
   
            TST R0,#T_bit 
   
            LDRNEH R0,[LR,#-2] ;若是Thunb指令,读取指令码(16位)

   BICNE R0,#0XFF00 :取得Thunb指令的8位立即数

   LDREQ R0,[LR,#-4] ;若是ARM指令,读取指令码(32位)

   BICEQ R0,#0XFF000000 ;取得ARM指令的24位立即数

   ....

   LDMFD SP!,{R0-R3,R12,PC}^ ;SWI异常中断返回

 

 

2)

;/*
;*******************************************************************************************
;** 模 块 名:SWI.s
;** 功能描述:SWI异常处理函数
;** 创建日期:04-16-2007  by:CANopen
;** 修改日期:     by:
;*******************************************************************************************
;*/
    AREA SWI_Function, CODE, READONLY

    EXPORT SWI_Handler_Ex
    IMPORT SWI_Exception_Function

;T_bit EQU 0x20

SWI_Handler_Ex

    STMFD   sp!,  {r0-r3, r12, lr}    ;// STMDB,保护现场
    MOV     r1,  sp                   ;// 若SWI调用带参,将R1指向第一个参数
                 ;// 遵照ATPCS标准,第一个参数存于R0中
    MRS     r0,  spsr              
    STMFD   sp!,  {r0}                ;// spsr入栈
    LDR    r0,  [lr,#-4]             ;// 获取SWI指令码
    BIC    r0,  r0, #0xFF000000      ;// 获取SWI number

    ;// r0 now contains SWI number
    ;// r1 now contains pointer to stacked registers

    BL      SWI_Exception_Function       ;// 调用C编写的SWI处理函数
    LDMFD   sp!,  {r0}             
    MSR     spsr_cf,r0               ;// spsr出栈
    LDMFD   sp!,  {r0-r3, r12, pc}^   ;// 恢复现场

    END

;/******************************************************************************************
;**                            End Of File
;*******************************************************************************************

备忘如下:

1、触及SWI软中断,就不能不说ATPCS过程调用,将后续日志记录;

2、本文件SWI.s位于ARM Executable Image for LPC2294工程模板中,故不考虑SWI触发前为Thumb态;SWI异常一旦触发,内核硬件完成:
   ♂ 进入Supervisor模式;
   ♂ 拷贝CPSR至SPSR_svc
   ♂ 拷贝异常返回地址至LR_svc
   ♂ 将0x00000008装入PC
    因此,当触发SWI软中断前内核处于Supervisor模式,SPSR_svc、LR_svc中的值将被破坏;

3、SWI指令编码中自带24bit数据作为软中断号(swi_num),因此可 通过取SWI指令编码获取软中断号;LDR r0,[lr,#-4]就是这样;

4、SWI_Exception_Function函数一般采用C编码(也可汇 编),采用C编码可直接套用switch根据swi_nun软中断号切换,SWI_Exception_Function函数的编制是灵活的,比如可以为 带参或不带参函数;

5、一个SWI调用允许带1~4个字型参数和1~4个字型返回值,触发SWI调用 时四个参数依次保存在R0~R3中,返回值也存于R0~R3内,这和ATPCS函数调用一致;

6、在C中声明一个典型的无参无返回值的SWI调用为:”__swi(0x00) void IRQEnable();“这样随时都可以使用”IRQEnable();“触发一个软中断(中断号0),其允许IRQ中断的功能必须在 SWI_Exception_Function软中断处理函数中实现;

7、以下为带参数的SWI调用,SWI调用和普通函数调用一样遵循ATPCS标 准,Handle参数存放在R0中:
__swi(0x01) void SwiHandle(int Handle);
#define IRQDisable()    SwiHandle(0)
#define IRQEnable()     SwiHandle(1)
#define FIQDisable()    SwiHandle(2)
#define FIQEnable()     SwiHandle(3)

8、最后须要注意的:SP最栈指针时为间接寻址,”MOV r1,sp“指令将R1也编程一个指针,其存放的内容为R0在RAM中的地址而非R0值;

9、还有一点:SWI调用带参和 SWI_Exception_Function函数的带参,是两回事,我都被这两个”带参“搞晕胡了半天。
 

我的总结:我在RealView 里试了试还真行。用立即数来区别到底是哪个服务就行了

 

http://blog.csdn.net/nih1986517/archive/2008/10/16/3087286.aspx

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值