ARM之异常

异常的介绍

概念
异常会导致处理器暂停程序执行以处理事件,例如外部生成的中断或试图执行未定义的指令。异常可以由内部和外部源生成,通常,当出现异常时,处理器状态会在处理异常之前立即保存。这意味着,当事件被处理后,可以从发生异常的地方恢复原始状态并恢复程序执行。
可能会同时生成多个异常,并且在处理器处理异常时可能会生成一个新的异常(异常也可以嵌套)
下图为ARM所用工作模式的介绍
在这里插入图片描述
他的中断又分为以下这些在这里插入图片描述
我们4412的板子的异常向量表在0XFFFF 0000这个位置,所以我们首先要开启MMU,才可以去访问这个异常向量表,这时候我们就需要用到汇编来定义

.align 2
.text
.global _start

_start:  //全局向量表
	b       reset     		   @0x0
        ldr     pc, _Undefined_Instruction @0x4
        ldr     pc, _Supervisor_Call	   @0x8	
        ldr     pc, _Prefetch_Abort        @0xc
        ldr     pc, _Data_Abort           @0x10
        ldr     pc, _Not_Used              @0x14
        ldr     pc, _IRQ_interrupt                   @0x18    
        ldr     pc, _FIQ_interrupt		   @0x1c

//异常的跳转
_Undefined_Instruction: 
	.word Undefined_Instruction
_Supervisor_Call:   
	.word Supervisor_Call
_Prefetch_Abort:        
	.word Prefetch_Abort
_Data_Abort:            
	.word Data_Abort
_Not_Used:              
	.word Not_Used
_IRQ_interrupt:                   
	.word IRQ_interrupt 
_FIQ_interrupt:                   
	.word FIQ_interrupt 

reset:
	mov ip, sp
	push {fp, ip, lr, pc}
	sub fp, ip, #4

	bl clr_bss
	bl main

	sub sp, fp, #12
	ldm sp, {fp, sp, pc}

Undefined_Instruction:
	
	mov sp, #0x76000000
	stmfd sp!, {r0-r12, lr}
	bl do_unde
	ldmfd sp!, {r0-r12, pc}^
	
Supervisor_Call:
	stmfd sp!, {r0-r12, lr}
	sub r0, lr, #4
	ldr r0, [r0]
	bic r0, r0, #0xff000000
	bl do_svc
	ldmfd sp!, {r0-r12, pc}^

Prefetch_Abort:

Data_Abort:
ldr sp, =0x76e00000 //将一个地址装载到sp中
sub lr, lr, #4
stmfd sp!, {r0-r12, lr}  //lr已经在产生异常时被设置为 pc -4   pc-4正好是C的下一行
bl do_abt_data //跳转到异常函数
ldmfd sp!, {r0-r12, pc}^  //^的作用是手动将SPSR返还给CPSR

Not_Used:

IRQ_interrupt:

FIQ_interrupt:

excep_sec:

excep_start:
	.word _start	
excep_end:
	.word excep_sec

.globl excep_start //声明起始地址为全局变量
.globl excep_end //声明结束地址为全局变量
 
__start_bss:
	.word _bss_start
__end_bss:
	.word _bss_end

这时候我们需要将物理地址映射到虚拟地址,同时把我们的在汇编中写好的表放到0XFFFF0000这个位置,这时候我们在汇编中声明这全局变量.globl excep_start和
excep_end,并在c语言中定义他,主要的编码为下面

	extern u32 excep_start[],u32 excrp_end //用数组的首地址来记录在汇编中的的位置 
	init_global_map(TTB);//mmu初始化
	CREATE_DESCRIPTOR(TTB, 0xffff0000, 0x75000000); //映射0xffff0000
	enable_mmu(TTB); //使能mmu
	memcpy((void *)0xffff0000, (void *)excep_start, excep_end - excep_start)	
	//将表防入0xffff0000

这样子我们就搭建好了一个最近基本的异常框架,我们可以在c语言中修改异常函数来做我们想做的处理

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ARM异常处理过程分为三个阶段:异常入口、异常处理异常返回。 1. 异常入口 当ARM处理器遇到异常时,首先会将当前指令的地址保存到CPSR寄存器中的SVC模式下的lr寄存器中,并将程序状态切换到异常模式。此时,处理器会将异常类型码保存到异常模式下的lr寄存器中,并将程序计数器设置为异常向量表中对应异常类型的地址。 2. 异常处理 当程序进入异常向量表指定的异常处理程序后,ARM会执行相应的异常处理程序。在异常处理程序中,处理器会按照异常类型码和异常状态,选择相应的处理方式。通常情况下,处理器会将当前程序的上下文(例如寄存器值、栈指针等)保存到内存或堆栈中,并根据异常类型和状态进行相应的处理,例如中断处理、系统调用等。 3. 异常返回 当异常处理程序完成后,处理器会将上下文信息还原回来,并将程序状态切换回原来的模式。此时,处理器会将异常返回地址从lr寄存器中取出,并将其设置为程序计数器,继续执行原来的指令。如果原来的指令是被中断打断的,处理器会返回到被中断的指令处继续执行。如果原来的指令已经执行完毕,处理器会执行下一条指令。 需要注意的是,异常处理过程中需要保证处理器的状态不被破坏。因此,在异常处理程序中需要谨慎地使用寄存器和内存,以免造成数据的损坏或丢失。此外,在实现异常处理程序时,还需要考虑异常处理的优先级和处理方式,以保证系统的稳定性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值