3013|1

241

帖子

4

TA的资源

纯净的硅(初级)

楼主
 

Helper2416-16——裸机第八弹——异常(Exception) [复制链接]

裸机第八弹——异常(Exception

参与Helper2416开发板助学计划心得



上一篇帖子介绍过ARM有5钟异常模式。我们可以通过修改CPSR的工作模式位来进入不同的模式,但这并没有什么实际意义,我们需要的是当有异常发生的时候,能进入相应的异常模式,并跳转到相应的异常服务函数中去对异常做出处理,同时在处理完后又能返回到处理异常之前的状态下去。这篇帖子主要介绍异常从发生到处理,到返回的具体过程。


Exception:
Exceptions are generated by internal and external sources to cause the processor to handle an event, such as an externally generated interrupt or an attempt to execute an Undefined instruction.The processor state just before handling the exception is normally preserved so that the originalprogram can be resumed when the exception routine has completed. More than one exception can arise at the same time.


异常的检测:

CPU在执行每条指令之前检测是否有异常发生。

mov r1,#0x10

mov r2, #0x20

sub r0, r2, r1

例如在CPU在执行mov r1,#0x10时,产生一个IRQ异常信号,则CPU将在这条指令执行完后,由于ARM的流水线模式PC指向sub r0, r2, r1这条指令但mov r2, #0x20并未执时检测到异常信号。


进入异常模式:

在检测到异常之后,硬件会自动切换到相应的异常模式同时切换到该异常模式下对应的那一组寄存器下,并把之前模式CPSR保存到当前异常模式下的SPSR下,同时把PC值压入该异常模式下的栈中。然后再将一个固定的地址装入PC,对于不同的异常,这个值也是不同的,对应的值如下:


通常我们所使用的是Normal address 若要使用High vector address还需要做另外的配置

我们通常在这些位置放上相应的跳转指令,构成了我们的异常向量表,例如如下这段代码构成的异常向量表

  1. _start:
  2.         // 异常向量表
  3.         b reset                                                 /* 复位时,cpu跳到0地址 */
  4.         b halt                                                            /* cpu遇到不能识别的指令时 */
  5.         b halt                                                        /* swi异常,进入svc模式 */
  6.         b halt                                                             /* 预取中止异常 */
  7.         b halt                                                          /* 数据访问异常 */
  8.         b halt                                                      /* 没用到 */
  9.         b IRQHandler                                               /* 中断异常 */
  10.         b _fiq                                                       /* 快中断异常 */
复制代码
需要注意的是,这些条状指令一定要写在相应的特定地址上。

由于几个不同的异常可以同时产生,那就必须要引出异常优先级的概念,来让各异常能够有序的执行。

各异常对应的优先级如下:



异常处理
通过上面的异常向量表跳转到特定的异常服务函数来进行相应的处理。
通常在异常服务函数中还要对上下文的切换做一些工作,把一些之前模式用到的寄存器都要保存好,同时在退出异常服务的时候要恢复这些寄存器,
例如如下这段简单的IRQ异常服务函数:
需要注意的是由于ARM流水线操作,我们需要修正返回地址:如上我们必须要返回到mov r2, #0x20的位置。
  1. IRQHandler:
  2.                 SUB         LR, LR, #4                        @修正返回地址
  3.                 STMFD         SP!, {R0-R12, LR}
  4.                 MRS                R0,        SPSR
  5.                 STMFD        SP!,        {R0}

  6.                 BL                do_irq                                @处理异常

  7.                 LDMFD        SP!,        {R0}                 @恢复现场
  8.                 MSR                SPSR,        R0
  9.                 LDMFD        SP!,        {R0-R12, PC}^        @^表示把spsr恢复到cpsr
复制代码
异常返回:
如上代码,恢复上下文,把SPSR恢复到cpsr就完成了模式的切换,同时将返回地址装入PC即从异常返回。

由于我使用的是SD卡启动,代码会搬运到0x40000000的地址执行,所以如果要进行自定义异常处理的话,就必须让自己的异常向量表位于0x0开始的地址上,所以我们只能使用MMU把地址0x40000000重映射到地址0x00000000上去。
我将在下一篇帖子贴出我有关MMU及重映射的心得。







论坛ID:yuanlai2010

发表时间:2014-07-22








最新回复

赞一个  详情 回复 发表于 2014-7-22 21:53

赞赏

1

查看全部赞赏

点赞 关注(1)

回复
举报

22

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
赞一个
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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