【ARM裸板】软件中断分析及示例

发布者:yanfeng00最新更新时间:2020-03-06 来源: eefocus关键字:ARM裸板  软件中断  切换模式 手机看文章 扫描二维码
随时随地手机看文章

1.APP如何切换模式

APP一般运行于User Mode下,受到限制(例如不可访问硬件)

如果APP想要访问硬件,必须切换模式

如何切换?发生异常即可:

软中断,swi #val

中断

未定义指令异常

2.SWI中软处理过程

执行异常处理函数之前,硬件会处理的事情:

 1.lr_svc保存有被中断模式中的下一条即将执行的指令的地址

 2.SPSR_svc保存被中断模式CPSR

 3.CPSR的[M4:M0]=[11011],进入到svc模式

 4.跳到0x08的模式执行程序,即跳到b do_svc这一指令

/*====================================异常向量表===========================================*/

_start:

b reset    //vector 0: reset(0地址对应reset)

  ldr pc, und_addr //vector 4: und  (发生未定义指令异常,则进入“处理未定义异常函数”)绝对跳转,跳转至sdram中

  ldr pc, swi_addr //vector 8: swi


und_addr:

.word do_und //存放地址,确保这一地址存放在内存的前4K中


swi_addr:

.word do_swi


 /*=================================处理软中断异常=========================================*/

 do_swi:


/*执行到这里之前:

*1.lr_svc保存有被中断模式中的下一条即将执行的指令的地址

*2.SPSR_svc保存被中断模式CPSR

*3.CPSR的[M4:M0]=[10011],进入到svc模式

*4.跳到0x08的模式执行程序,即跳到`b do_swi`这一指令

*/

    /* 1.sp_svc 设置栈,因为后面函数需要栈 */

    ldr sp, =0x33E00000


    /* 2.保存现场 */

    /* lr是异常处理完后的返回地址,也需要保存 */

    stmdb sp!, {r0-r12,lr} //在swi异常处理函数总有可能需要用到r0~r12,因此先保存下来


    mov r4,lr //将lr存放在r4中,调用c函数不会破坏r4

    /* 3.处理swi异常 */

    mrs r0,cpsr //把cpsr的值放入r0

    ldr r1, =swi_string

    bl printException


    sub r0,r4,#4

    bl printSWIVal


    /* 4.恢复现场 */

    ldmia sp,{r0-r12,pc}^ //将lr的值赋给pc ,`^`会把spsr的值恢复到cpsr中


swi_string:

.string "swi exception"

.align 4  //确保4字节对齐


2.1设置栈

sp_svc 设置栈,因为后面有函数需要用到栈

ldr sp, =0x33E00000


2.2 保存现场

stmdb:stm(m为many),即写多个内存,db预先减少(Decrement Before),即先减后写

r是异常处理完后的返回地址,也需要保存

stmdb sp!, {r0-r12,lr}` //在swi异常处理函数总有可能需要用到r0~r12,因此先保存下来


2.3 处理swi异常

打印提示发生未定义异常,并调用打印函数显示CPSR的值

mrs r0,cpsr //把cpsr的值放入r0


、预先增加(Increment Before)、过后减少(Decrement After)、。


2.4 恢复现场

ldmia:ldm(m为many)即读多个内存,ia(Increment After)过后增加,即先读后加

将lr的值赋给pc ,^会把spsr的值恢复到cpsr中

ldmia sp,{r0-r12,pc}^ 


3.取出SWI指令中的值

在swi异常处理函数中,先将lr的值保存在r4中,因为执行完swi指令后,发生异常,lr会保存下一条指令的地址,因此lr-4即是swi指令的地址

用r0 = r4-4

传给打印函数

    sub r0,r4,#4

    bl printSWIVal


由下表可知,swi中断指令高8位可以忽略,即取后24位即可

void printSWIVal(unsigned int *pSWI)

{

unsigned int val = *pSWI & (~0xff000000);

printf("SWI val = %xrn",val);

}

在这里插入图片描述

关键字:ARM裸板  软件中断  切换模式 引用地址:【ARM裸板】软件中断分析及示例

上一篇:【ARM裸板】按键外部中断过程及示例
下一篇:【ARM裸板】未定义指令异常分析及示例

小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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