【ARM裸板】ARM模式、异常与状态

示例代码下载

1.两种流程处理

  • 1.查询方式
    • 特点:简单、但占用较多资源
  • 2.中断方式
    • 特点:负责、但占用资源少

  • 常见的中断有(中断也是异常的一种):
    • 按键(外部中断)、定时器中断、网络数据
  • 常见的异常有
    • 指令异常、数据访问出错、Reset

2.中断处理过程

2.1 硬件初始化

  • 设置中断源
  • 设置中断控制器(屏蔽、优先级)
  • 设置CPU总开关(使能中断)

2.2 执行程序

2.3 产生中断

  • eg:
中断信号
按下按键
中断控制器
CPU
  • CPU每执行完一条指令,都会检查有误异常(中断)产生
  • 发现异常(中断)产生,开始处理
    • 对于不同的异常,会跳去不同的地址(异常向量)执行程序
    • 这些地址上,只是一条跳转指令(跳去执行其他函数)

2.4 执行中断

  • 1.保存现场(各类寄存器)
  • 2.中断处理
  • 3.恢复现场

3.ARM的7种模式(Mode)

  • 正常模式
    • User (usr): The normal ARM program execution state
      • 用户模式(不可以直接进入其他模式)
    • System (sys): A privileged user mode for the operating system
      • 系统模式

  • 异常模式

    • FIQ (fiq): Designed to support a data transfer or channel process
      • 快中断模式
    • IRQ (irq): Used for general-purpose interrupt handling
      • 中断模式
    • Supervisor (svc): Protected mode for the operating system
      • 管理模式
    • Abort mode (abt): Entered after a data or instruction prefetch abort
      • 中止模式
    • Undefined (und): Entered when an undefined instruction is executed
      • 未定义指令模式
  • 除了用户模式以外的6中模式 成为特权模式(Privileged Mode),可以编程操作CPSR(当前程序状态寄存器)直接进入其他模式

  • 不同模式是为了更好的应对所对应的异常(差别在于:寄存器的资源)

在这里插入图片描述

banker register 为备份寄存器,可以成为专属寄存器,R13(SP栈指针)、R14(LR返回地址)
SPSR(保存程序状态寄存器):用来保存“被中断模式的CPSR”,相当于CPSR的备份寄存器,eg:当正处于User Mode,发生中断,进入IRQ Mode,SPSR_irq就保存了User Mode那一时刻的CPSR

3.1 异常向量表

在这里插入图片描述

4.ARM的2种状态(State)

  • ARM State:

    • 使用ARM指令集,占据4个字节
  • Thumb State:

    • 使用Thumb指令集,占据2个字节
  • M0~M4:模式位 Mode bit (7种模式)

  • T:状态位 State bits(ARM or Thumb)

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

5.异常的处理流程

5.1 进入异常

  • 进入异常时的动作(硬件部分实现)
    • 1.异常模式下的LR存放 [被中断模式的下一条指令的地址](PC+4/PC+8)
    • 2.异常模式下的SPSR = CPSR
    • 3.修改CPSR的[M4~M0],进入异常模式
    • 4.跳到向量表

在这里插入图片描述

5.2 退出异常

  • 退出异常时的动作(硬件部分实现)
    • 1.PC = 异常模式下的LR - Offest(offest根据下表来确定)\
    • 2.CPSR = 异常模式下的SPSR(恢复CPSR)
    • 3.清除中断标志位

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

6.程序以thumb指令集运行

6.1 gcc以thumb编译

  • thumb指令集编译、使得代码以thunb状态运行,在makefile中的gcc编译加上-mthunb
  • arm-linux-gcc -mthumb -c -o $@ $<

6.2 如何从arm切换至thumb

  • [x]在start.S中需要使用ARM指令集的用.code 32指定,用thumb指令集的用.code 16指定
  • 使用BX指令(其是ARM指令系统中的带状态切换跳转指令),BX命令后面的那个值如果最低位为1的话,则切换到thumb指令
.code 32
/*..............*/

	/* 从ARM State 切换到Thumb State*/
	adr r0,thumb_func
	add r0,r0,#1 /*bit0 = 1时,bx就会切换CPU状态至thumb state*/
	bx r0

.code 16
thumb_func:

 /*..............*/

6.3 注意

  • 对于thumb指令,不能向PC直接赋值
    • eg:ldr pc, =main(这样不行),需要先把值赋值寄存器,再把寄存器赋值给PC

gcc disable built-in memcpy

  • 当使用thumb编译时,gcc会调用memcy,我们可以把变量改成static(存放在data段),这样就不会让gcc去调用了
发布了42 篇原创文章 · 获赞 176 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_39492932/article/details/104089224