异常向量表的编程处理

《朱老师物联网大讲堂》学习笔记

学习地址:www.zhulaoshi.org


像内存一样去访问异常向量表。


在我们开发板中iRAM的向量异常表的起始地址为0xd0037400,

结合上节说的,相对地址是固定的,而这里起始地址又确定了,

各种异常对应的入口地址就很好知道了。



函数名的实质就是函数的首地址,拿C语言中的语言来讲,函数名就是这个函数的函数指针,

将异常向量表和异常处理程序的首地址绑定起来后,异常处理初步阶段就完成了,

目前如果相应异常发生后,硬件自动跳转到对应异常向量表入口去执行,进而执行我们事先绑定的函数。

第一眼看到下面的异常向量表绑定,会觉得不知所以,其实前面有宏定义,

#define exception_vector_table_base  0xD0037400


#define exception_reset     (exception_vector_table_base + 0x00)


#define r_exception_reset  (*(volatile unsigned int *)exception_reset)

 

void system_init_exception(void)
{
	r_exception_reset = (unsigned int)reset_exception;
	r_exception_undef = (unsigned int)undef_exception;
	r_exception_sotf_int = (unsigned int)sotf_int_exception;
	r_exception_prefetch = (unsigned int)prefetch_exception;
	r_exception_data = (unsigned int)data_exception;
	r_exception_irq = (unsigned int)IRQ_handle;
	r_exception_fiq = (unsigned int)IRQ_handle;	
	intc_init();
}



为什么中断处理要先在汇编中进行,

因为中断是从SVC模式开始的,要保存该模式下必要的寄存器值,

中断完成后返回SVC,恢复这些寄存器的值,

否则SVC模式寄存器的值就乱了,SVC模式下原来正在进行的常规任务就被你破坏了。


现场保存包括

1.设置IRQ栈,各个模式的栈不同,所以各自要单独设置,

ldr sp, IRQ_STACK

sp名字只有一个,不过在不同模式下会自动切换到对应的sp,

2.保存LR,中断返回时2个关键寄存器就是pc和CPSR,

在进入IRQ模式时,应该将SVC模式下的下一句指令的地址和CPSR保存起来,

将来恢复时将返回地址给PC,将保存的CPSR给CPSR,

中断返回地址就保存在LR中,而CPSR自动保存在IRQ的SPSR中,

3.保存R0~R12。


#define IRQ_STACK 0xd0037f80

IRQ_handle:
	ldr	sp,	IRQ_STACK
	sub lr, lr, #4
//这里的4这样理解,+8-4,因为是3级指令,
	stmfd sp!	{r0-r12, lr}
	bl	irq_handler
	ldrfd	sp!	{r0-r12, pc}^


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值