当前位置:   article > 正文

ARC学习(3)基本编程模型认识(三)_arc0 rtt

arc0 rtt

笔者来介绍arc的编程模型的中断流程和异常流程

1、中断介绍

主要介绍一下中断进入的流程,包括需要配置的寄存器等信息。

  • 中断号:16-255,总共240个中断。
  • 触发类型:脉冲或者电平触发
  • 中断优先级:16个,0最大,15最小。
  • 中断向量表地址:地址0x400对齐,因为中断+异常的地址总共大小占用0x400的字节
  • 中断向量大小:32位

1.1 中断配置流程

  • 配置全局优先级阈值,STATUS.E[3:0],
  • 关闭外设中断
  • 关闭全局中断,即STATU32.IE 为0,
  • 选择需要配置的中断,IRQ_Select 寄存器,
  • 配置中断优先级,IRQ_Priority
  • 配置触发方式,IRQ_Trigger
  • 清除脉冲,IRQ_PULSE_CANCEL
  • 使能该中断,IRQ_ENABLE
  • 开启全局中断,即STATU32.IE 为1
  • 最后在开启外设中断
    在这里插入图片描述
    注意:首先肯定得开启外设使用,包括总线时钟使能等。

2、异常介绍

主要介绍一些arc-v2版本的异常向量以及异常的处理流程。也分为同步异常和异步的异常:

  • 同步异常:准确的异常,知道准确出错误的数据地址,指令地址等,cpu在发生异常时,立即进入异常处理函数,
  • 异步异常:不准确的异常,在出错之后才发生的异常,发生异常时,不是第一现场
    接下里介绍一下arc-v2的一些异常向量,以及处理异常的一些流程。

2.1 异常向量

异常向量共有16个,向量号0x-0x15,占用64字节,每个异常向量就是一个异常处理函数地址,异常发生后,会从该处取地址,然后跳到对应的处理函数。
在这里插入图片描述
每个异常可能都有多种原因,为了区分多种异常原因,arc这边提供了辅助寄存器来指示异常的原因,有点类似于ARM架构下面的fsr ,详情看ARM学习(3) 异常模式学习(CortexR5),寄存器为ESR,上文中已经介绍过,ARC学习(2)基本编程模型认识(二)

  • Vector Number,向量号(16-23Bit):指明哪个异常发生
  • Cause 异常原因(8-15Bit):该异常时有什么原因触发,
  • Parameter 参数(0-7Bit):原因的参数是什么,也类似于一种原因类型,进一步细分
  • P:指示异常发生在中断里面
    在这里插入图片描述
    异常的地址由异常地址寄存器指明:EFA,32位,可能是pc地址,可能是数据地址,或者是cache 地址等等。
    在这里插入图片描述

再来看一下异常向量具体会有哪些原因触发:

  1. 复位:Reset,外部信号造成的硬件复位,core寄存器不会被初始化,需要手动初始化。

在这里插入图片描述

  1. 内存错误:
  • 包括总线指令内存错误、
  • 总线数据内存错误,
  • 不存在的memory获取指令
  • 跨多个指令memory类型的指令获取,
  • 跨多个数据memory类型的数据获取,
  • 跨多个mpu region的指令获取,

在这里插入图片描述
在这里插入图片描述
内存类型有如下几种:
在这里插入图片描述

  1. 指令错误,无效的指令或者指令序列

在这里插入图片描述

  1. 机制检查异常
  • 异常里面发生异常,两次异常
  • 指令地址翻译错误,或者一个地址的多次翻译匹配
  • 致命的cache错误
  • 内部memory的指令获取异常
  • 内部memory的数据获取异常
  • 无效的MPU区域重叠
  • 不可屏蔽的异步异常发生或者两次发生
  • 获取向量时,无法纠正的ECC 或者奇偶校验发生,
    在这里插入图片描述在这里插入图片描述
  1. 指令页表缓存未命中(ITLB,Instruction Translation Lookaside Buffer)

在这里插入图片描述

  1. 数据页表缓存未命中(DTLB,Data Translation Lookaside Buffer),包括读写没有命中

在这里插入图片描述

  1. 保护机制违反异常
  • 代码保护机制,栈保护机制,MPU和MMU保护下的内存读 违反机制
  • 代码保护机制,栈保护机制,MPU、MMU和NVM保护下的内存写 违反机制
  • 代码保护机制,栈保护机制,MPU、MMU和NVM保护下的读修改写的违反机制
  • 读主要有:LD,POP,中断离开等
  • 写主要有:ST,PUSH,中断进入等

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 特权违反异常机制
  • 特权违反,比如只允许特权模式操作的指令,比如BRK、SWI和FLAG等
  • 禁止拓展的寄存器访问,比如32以外的寄存器

在这里插入图片描述
10. 软件中断:SWI 或者SWI_S指令会触发该向量处理函数,

在这里插入图片描述

  1. 陷阱异常:TRAP_S指令触发该向量异常处理函数

在这里插入图片描述

  1. 拓展指令异常:例如浮点等指令

在这里插入图片描述

  1. 除0异常:除数为0的异常,STATUS32 的DZ=1,

在这里插入图片描述

  1. 数据cahce 一致异常,不是cache 内存的操作指令 执行了一个data cache的地址。

在这里插入图片描述

  1. 数据未对齐访问异常
  • status32 的AD位置0,则运行对齐检查,未对齐的数据访问,进入该异常,比如32位的数据,处于奇地址。
  • EFA会抓到访问的异常地址。
    在这里插入图片描述
  1. 未对齐的向量内存访问异常

在这里插入图片描述

  1. 保留

异常的优先级和处理顺序:处理器每次都只能处理一个异常,所以当多个异常发生时,要排队处理,涉及到优先处理的异常。
注意:异常的优先级不按异常向量来决定,而是根据异常的原因来进行排序。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 异常流程

异常进入:exception entry

  1. 所有的异常指令被丢弃
  2. ERET 寄存器被赋值PC地址,PC地址为那错误指令的地址,如果是TRAP异常,ERET寄存器保存的是下一条指令。
  3. ESTATUS被赋予STATUS32寄存器的值
  4. ERBTA被赋予异常返回目标分支地址,即BTA的寄存器值
  5. ECR记录了异常向量,异常原因和参数等数据
  6. EFA记录异常的地址,比如当内存访问异常,则EFA记录触发异常的数据地址,如果是指令触发异常,则记录PC的地址,
  7. STATUS32的状态位开始修改,CPU转为内核模式,STATUS32的U bit 置0,中断被禁止,STATUS32的IE bit 置1,处于异常模式,STATUS32的AE bit 置1,STATUS32的EI bit 置0,禁止栈溢出检查,STATUS32的SC bit 置0,禁止除0异常,STATUS32的DZ bit 置0,0赋值循环禁止,STATUS32的L bit 置1,禁止延迟分支阻塞,STATUS32的DE bit 置0,
  8. PC 开始从异常向量表取异常向量,开始跳转到异常处理函数执行。
  9. 异常处理函数需要保存所有用到的寄存器,并且退出时恢复所有的寄存器,

流程图绘制:
在这里插入图片描述

异常退出:exception exit
主要是影响:ERET、ESTATUS和ERBTA,恢复到原来的状态,PC,STATUS32和BTA,以及恢复寄存器等等,相对比较简单。

3、实际例子说明

3.1 数据总线异常

下面例子代码会造成异常,0x3FFFFFFF是memory总线不存在的例子,

ls_u32_t *ptr=0x3FFFFFFF;
printf("0x%x 0x%x\r\n", ptr, *ptr);
  • 1
  • 2

实际异常后,打印出如下寄存器信息:

[18999]reg0=0x0001 [18999]reg1=0x0003 [18999]reg2=0x1fd30 [18999]reg3=0x30000000 [18999]reg4=0x0000 [18999]reg5=0x3fffffff [18999]reg6=0x0000 [18999]reg7=0x0000 [18999]reg8=0x10004f68 [18999]reg9=0x0001 [18999]reg10=0x1a17a [18999]reg11=0x0000 [18999]reg12=0x10004ef7 [18999]reg13=0x0000 [18999]reg14=0x0000 [18999]reg15=0x100006a0 [18999]
[18999]reg16=0x103f4 [18999]reg17=0x0000 [18999]reg18=0x0000 [18999]reg19=0x0020 [18999]reg20=0x0001 [18999]reg21=0x0080 [18999]reg22=0x0000 [18999]reg23=0x0000 [18999]reg24=0x0000 [18999]reg25=0x0000 [18999]reg26=0x0000 [18999]reg27=0x10005000 [18999]reg28=0x10004f8c [18999]reg29=0x172ee [18999]reg30=0x10004f68 [18999]pc=0x4000959c lr=0x1fd2c sp=0x10004f8c status32=0x80081624 
[18999]ECR=0x11000 ERET=0x4000ca54 EFA=0x3fffffff ERSTATUS=0x84004 
  • 1
  • 2
  • 3

提取出如下异常寄存器如下:
ECR=0x11000
ERET=0x4000ca54
EFA=0x3fffffff
ERSTATUS=0x84004

如ECR寄存器的值,我们可以找到如下说明,看到是访问data memory异常,符合预期异常。
在这里插入图片描述
然后EFA=0x3FFFFFFF,就是异常访问的地址信息,确实是异常的地址,

最后ERET,就是异常的返回地址,可以通过addr2line 然后定位源代码位置。

3.2 地址总线异常

再看一一个异常例子。
在这里插入图片描述
ECR=0x1000
ERET=0x3f8eec48
EFA=0x3f8eec48
ERSTATUS=0x80084804
如ECR寄存器的值,我们可以找到如下说明,看到是访问指令 memory异常
在这里插入图片描述
看到ERET和EFA,均是0x3f8eec48,怀疑是CPU跑飞到一块异常地址,该地址的值均是0x3f8eec48,所以ERET和EFA相等。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号